/// <summary> /// Implementation of <see cref="FilterManipulation"/> that forces the rotation to be about /// the center of the manipulation target. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> public static void RotateAboutCenter(object sender, FilterManipulationEventArgs args) { var inputProcessor = sender as InputProcessor; var target = inputProcessor.Target; // Get the bounding box of the manipulation target, expressed in the coordinate system of its container var rect = target.RenderTransform.TransformBounds( new Windows.Foundation.Rect(0, 0, target.ActualWidth, target.ActualHeight)); args.Pivot = new Windows.Foundation.Point { X = rect.Left + (rect.Width / 2), Y = rect.Top + (rect.Height / 2) }; }
/// <summary> /// Implementation of <see cref="FilterManipulation"/> that forces the center of mass of the /// manipulation target to remain inside its container. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> public static void ClampCenterOfMass(object sender, FilterManipulationEventArgs args) { var inputProcessor = sender as InputProcessor; var target = inputProcessor.Target; var container = inputProcessor.Reference; // Get the bounding box and the center of mass of the manipulation target, // expressed in the coordinate system of its container var rect = target.RenderTransform.TransformBounds( new Windows.Foundation.Rect(0, 0, target.ActualWidth, target.ActualHeight)); var centerOfMass = new Windows.Foundation.Point { X = rect.Left + (rect.Width / 2), Y = rect.Top + (rect.Height / 2) }; // Apply delta transform to the center of mass var transform = new Windows.UI.Xaml.Media.CompositeTransform { CenterX = args.Pivot.X, CenterY = args.Pivot.Y, Rotation = args.Delta.Rotation, ScaleX = args.Delta.Scale, ScaleY = args.Delta.Scale, TranslateX = args.Delta.Translation.X, TranslateY = args.Delta.Translation.Y }; var transformedCenterOfMass = transform.TransformPoint(centerOfMass); // Reset the transformation if the transformed center of mass falls outside the container if (transformedCenterOfMass.X < 0 || transformedCenterOfMass.X > container.ActualWidth || transformedCenterOfMass.Y < 0 || transformedCenterOfMass.Y > container.ActualHeight) { args.Delta = new Windows.UI.Input.ManipulationDelta { Rotation = 0F, Scale = 1F, Translation = new Windows.Foundation.Point(0, 0) }; } }
/// <summary> /// Implementation of <see cref="FilterManipulation"/> that forces at least <see cref="ManipulationFilter.TargetMinSize"/> /// pixels of the manipulation target to remain inside its container. /// This filter also makes sure the manipulation target does not become too small or too big. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> public static void Clamp(object sender, FilterManipulationEventArgs args) { var inputProcessor = sender as InputProcessor; var target = inputProcessor.Target; var container = inputProcessor.Reference; //int x = 0; //int.TryParse(target.GetValue(Windows.UI.Xaml.Controls.Canvas.TopProperty).ToString(), out x); //int y = 0; //int.TryParse(target.GetValue(Windows.UI.Xaml.Controls.Canvas.LeftProperty).ToString(), out y); // Get the bounding box of the manipulation target, expressed in the coordinate system of its container var rect = target.RenderTransform.TransformBounds(new Windows.Foundation.Rect(0, 0, target.ActualWidth, target.ActualHeight)); // Make sure the manipulation target does not go completely outside the boundaries of its container var translate = new Windows.Foundation.Point { X = args.Delta.Translation.X, Y = args.Delta.Translation.Y }; if ((args.Delta.Translation.X > 0 && args.Delta.Translation.X > container.ActualWidth - rect.Left - ManipulationFilter.TargetMinInside) || (args.Delta.Translation.X < 0 && args.Delta.Translation.X < ManipulationFilter.TargetMinInside - rect.Right) || (args.Delta.Translation.Y > 0 && args.Delta.Translation.Y > container.ActualHeight - rect.Top - ManipulationFilter.TargetMinInside) || (args.Delta.Translation.Y < 0 && args.Delta.Translation.Y < ManipulationFilter.TargetMinInside - rect.Bottom)) { translate.X = 0; translate.Y = 0; } // Make sure the manipulation target does not become too small, or too big float scale = args.Delta.Scale < 1F ? (float)System.Math.Max(ManipulationFilter.TargetMinSize / System.Math.Min(rect.Width, rect.Height), args.Delta.Scale) : (float)System.Math.Min(ManipulationFilter.TargetMaxSize / System.Math.Max(rect.Width, rect.Height), args.Delta.Scale); args.Delta = new Windows.UI.Input.ManipulationDelta { Expansion = args.Delta.Expansion, Rotation = args.Delta.Rotation, Scale = scale, Translation = translate }; }
/// <summary> /// Implementation of <see cref="FilterManipulation"/> that forces at least <see cref="ManipulationFilter.TargetMinSize"/> /// pixels of the manipulation target to remain inside its container. /// This filter also makes sure the manipulation target does not become too small or too big. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> public static void Clamp(object sender, FilterManipulationEventArgs args) { var inputProcessor = sender as InputProcessor; var target = inputProcessor.Target; var container = inputProcessor.Reference; // Get the bounding box of the manipulation target, expressed in the coordinate system of its container var rect = target.RenderTransform.TransformBounds( new Windows.Foundation.Rect(0, 0, target.ActualWidth, target.ActualHeight)); // Make sure the manipulation target does not go completely outside the boundaries of its container var translate = new Windows.Foundation.Point { X = args.Delta.Translation.X, Y = args.Delta.Translation.Y }; if ((args.Delta.Translation.X > 0 && args.Delta.Translation.X > container.ActualWidth - rect.Left - ManipulationFilter.TargetMinInside) || (args.Delta.Translation.X < 0 && args.Delta.Translation.X < ManipulationFilter.TargetMinInside - rect.Right) || (args.Delta.Translation.Y > 0 && args.Delta.Translation.Y > container.ActualHeight - rect.Top - ManipulationFilter.TargetMinInside) || (args.Delta.Translation.Y < 0 && args.Delta.Translation.Y < ManipulationFilter.TargetMinInside - rect.Bottom)) { translate.X = 0; translate.Y = 0; } // Make sure the manipulation target does not become too small, or too big float scale = args.Delta.Scale < 1F ? (float)System.Math.Max(ManipulationFilter.TargetMinSize / System.Math.Min(rect.Width, rect.Height), args.Delta.Scale) : (float)System.Math.Min(ManipulationFilter.TargetMaxSize / System.Math.Max(rect.Width, rect.Height), args.Delta.Scale); args.Delta = new Windows.UI.Input.ManipulationDelta { Expansion = args.Delta.Expansion, Rotation = args.Delta.Rotation, Scale = scale, Translation = translate }; }
private void OnManipulationUpdated(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.ManipulationUpdatedEventArgs args) { _deltaTransform.TranslateX = args.Delta.Translation.X; _deltaTransform.TranslateY = args.Delta.Translation.Y; _target.SetValue(Windows.UI.Xaml.Controls.Canvas.TopProperty, 0); _target.SetValue(Windows.UI.Xaml.Controls.Canvas.LeftProperty, 0); // Because of the way we process pointer events, all coordinates are expressed // in the coordinate system of the reference of the manipulation target. // args.Position stores the position of the pivot of this manipulation // args.Delta stores the deltas (Translation, Rotation in degrees, and Scale) var filteredArgs = new FilterManipulationEventArgs(args); OnFilterManipulation?.Invoke(this, filteredArgs); // Update the transform // filteredArgs.Pivot indicates the position of the pivot of this manipulation // filteredArgs.Delta indicates the deltas (Translation, Rotation in degrees, and Scale) _previousTransform.Matrix = _transform.Value; _deltaTransform.CenterX = filteredArgs.Pivot.X; _deltaTransform.CenterY = filteredArgs.Pivot.Y; _deltaTransform.Rotation = filteredArgs.Delta.Rotation; _deltaTransform.TranslateX = filteredArgs.Delta.Translation.X; _deltaTransform.TranslateY = filteredArgs.Delta.Translation.Y; if (ZoomBehavior == Controls.ZoomType.Resize) { _target.Height = _target.ActualHeight * filteredArgs.Delta.Scale; _target.Width = _target.ActualWidth * filteredArgs.Delta.Scale; } else if (ZoomBehavior == Controls.ZoomType.Scale) { _deltaTransform.ScaleX = _deltaTransform.ScaleY = filteredArgs.Delta.Scale; } }
private void OnManipulationUpdated(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.ManipulationUpdatedEventArgs args) { // Because of the way we process pointer events, all coordinates are expressed // in the coordinate system of the reference of the manipulation target. // args.Position stores the position of the pivot of this manipulation // args.Delta stores the deltas (Translation, Rotation in degrees, and Scale) var filteredArgs = new FilterManipulationEventArgs(args); if (OnFilterManipulation != null) { OnFilterManipulation(this, filteredArgs); } // Update the transform // filteredArgs.Pivot indicates the position of the pivot of this manipulation // filteredArgs.Delta indicates the deltas (Translation, Rotation in degrees, and Scale) _previousTransform.Matrix = _transform.Value; _deltaTransform.CenterX = filteredArgs.Pivot.X; _deltaTransform.CenterY = filteredArgs.Pivot.Y; _deltaTransform.Rotation = filteredArgs.Delta.Rotation; _deltaTransform.ScaleX = _deltaTransform.ScaleY = filteredArgs.Delta.Scale; _deltaTransform.TranslateX = filteredArgs.Delta.Translation.X; _deltaTransform.TranslateY = filteredArgs.Delta.Translation.Y; }