internal static void ApplyParameters(InertiaTranslationBehavior behavior, InertiaProcessor2D processor, Vector initialVelocity) { if (behavior != null && behavior.CanUseForInertia()) { InertiaTranslationBehavior2D behavior2D = new InertiaTranslationBehavior2D(); if (behavior._isInitialVelocitySet) { behavior2D.InitialVelocityX = (float)behavior._initialVelocity.X; behavior2D.InitialVelocityY = (float)behavior._initialVelocity.Y; } else { behavior2D.InitialVelocityX = (float)initialVelocity.X; behavior2D.InitialVelocityY = (float)initialVelocity.Y; } if (behavior._isDesiredDecelerationSet) { behavior2D.DesiredDeceleration = (float)behavior._desiredDeceleration; } if (behavior._isDesiredDisplacementSet) { behavior2D.DesiredDisplacement = (float)behavior._desiredDisplacement; } processor.TranslationBehavior = behavior2D; } }
internal static void ApplyParameters(InertiaExpansionBehavior behavior, InertiaProcessor2D processor, Vector initialVelocity) { if (behavior != null && behavior.CanUseForInertia()) { InertiaExpansionBehavior2D behavior2D = new InertiaExpansionBehavior2D(); if (behavior._isInitialVelocitySet) { behavior2D.InitialVelocityX = (float)behavior._initialVelocity.X; behavior2D.InitialVelocityY = (float)behavior._initialVelocity.Y; } else { behavior2D.InitialVelocityX = (float)initialVelocity.X; behavior2D.InitialVelocityY = (float)initialVelocity.Y; } if (behavior._isDesiredDecelerationSet) { behavior2D.DesiredDeceleration = (float)behavior._desiredDeceleration; } if (behavior._isDesiredExpansionSet) { behavior2D.DesiredExpansionX = (float)behavior._desiredExpansion.X; behavior2D.DesiredExpansionY = (float)behavior._desiredExpansion.Y; } if (behavior._isInitialRadiusSet) { behavior2D.InitialRadius = (float)behavior._initialRadius; } processor.ExpansionBehavior = behavior2D; } }
internal static void ApplyParameters(InertiaRotationBehavior behavior, InertiaProcessor2D processor, double initialVelocity) { if (behavior != null && behavior.CanUseForInertia()) { InertiaRotationBehavior2D behavior2D = new InertiaRotationBehavior2D(); if (behavior._isInitialVelocitySet) { behavior2D.InitialVelocity = (float)AngleUtil.DegreesToRadians(behavior._initialVelocity); } else { behavior2D.InitialVelocity = (float)AngleUtil.DegreesToRadians(initialVelocity); } if (behavior._isDesiredDecelerationSet) { behavior2D.DesiredDeceleration = (float)AngleUtil.DegreesToRadians(behavior._desiredDeceleration); } if (behavior._isDesiredRotationSet) { behavior2D.DesiredRotation = (float)AngleUtil.DegreesToRadians(behavior._desiredRotation); } processor.RotationBehavior = behavior2D; } }
// </Snippet_GamePiece_PrivateMembers> /*******************************************/ // <Snippet_GamePiece_Constructor> #region Constructor public GamePiece(SpriteBatch spriteBatch, string fileName) { // For brevity, omitting checking of null parameters. this.spriteBatch = spriteBatch; // Get the texture from the specified file. texture = Texture2D.FromFile(spriteBatch.GraphicsDevice, fileName); // Initial position set to 0,0. position = new Vector2(0); // Set the origin to be the center of the texture. origin = new Vector2(texture.Width / 2.0f, texture.Height / 2.0f); // Set bounds. bounds.X and bounds.Y are set as the position or scale changes. bounds = new Rectangle(0, 0, texture.Width, texture.Height); // Create manipulation processor. Manipulations2D enabledManipulations = Manipulations2D.Translate | Manipulations2D.Rotate; manipulationProcessor = new ManipulationProcessor2D(enabledManipulations); manipulationProcessor.Pivot = new ManipulationPivot2D(); manipulationProcessor.Pivot.Radius = texture.Width / 2; manipulationProcessor.MinimumScaleRotateRadius = 10.0f; manipulationProcessor.Started += OnManipulationStarted; manipulationProcessor.Delta += OnManipulationDelta; manipulationProcessor.Completed += OnManipulationCompleted; // Create inertia processor. inertiaProcessor = new InertiaProcessor2D(); inertiaProcessor.Delta += OnInertiaDelta; inertiaProcessor.Completed += OnInertiaCompleted; inertiaProcessor.TranslationBehavior.DesiredDeceleration = 0.0001F; inertiaProcessor.RotationBehavior.DesiredDeceleration = 1e-6F; inertiaProcessor.ExpansionBehavior.DesiredDeceleration = 0.0001F; // Save the view port. Used to detect when the piece needs to bounce. viewport = spriteBatch.GraphicsDevice.Viewport; // Set the piece in a random location. Random random = new Random((int)Timestamp); X = random.Next(viewport.Width); Y = random.Next(viewport.Height); // Set a random orientation. rotation = (float)(random.NextDouble() * Math.PI * 2.0); dragPoint = new System.Windows.Point(double.NaN, double.NaN); pieceColor = Color.White; // Set scale to normal (100%) Scale = 1.0f; }
// </Snippet_ManipulationItem_OnManipulationOrInertiaDelta> private void SetDesiredRotation(InertiaProcessor2D inertiaProcessor) { // <Snippet_ManipulationItem_SetDesiredRotation> #region SetDesiredRotation // PI * 2 radians = 360 degrees. inertiaProcessor.RotationBehavior.DesiredRotation = (float)Math.PI * 7.0f; #endregion // </Snippet_ManipulationItem_SetDesiredRotation> }
/******************************************************************************/ #region Constructor public ManipulationItem() { InitializeComponent(); PivotButton.Click += OnPivotClick; // The DeadZone is a little red ring that shows the area inside which // no rotation or scaling will happen if you drag the mouse. We set // it to four times the size of the manipulation processor's MininumScaleRotateRadius. // Reason for the number: // - x2, because diameter = 2 * radius // - x2, because the number on the manipulation processor is radius from // the center of mass of the manipulators being used, which in the case // of this test app will be the midpoint between the mouse and the hub. //DeadZone.Width = 4 * minScaleRotateRadius; //DeadZone.Height = 4 * minScaleRotateRadius; manipulationProcessor = new ManipulationProcessor2D(Manipulations2D.None); manipulationProcessor.MinimumScaleRotateRadius = minScaleRotateRadius; manipulationProcessor.Started += OnManipulationStarted; manipulationProcessor.Started += OnManipulationStarted2; manipulationProcessor.Delta += OnManipulationDelta; manipulationProcessor.Completed += OnManipulationCompleted; inertiaProcessor = new InertiaProcessor2D(); inertiaProcessor.TranslationBehavior.DesiredDeceleration = 0.0001F; inertiaProcessor.RotationBehavior.DesiredDeceleration = 1e-6F; inertiaProcessor.ExpansionBehavior.DesiredDeceleration = 0.0001F; inertiaProcessor.Delta += OnManipulationDelta; inertiaProcessor.Completed += OnInertiaCompleted; inertiaTimer = new DispatcherTimer( DispatcherPriority.Input, Dispatcher.CurrentDispatcher); inertiaTimer.IsEnabled = false; inertiaTimer.Interval = TimeSpan.FromMilliseconds(25); inertiaTimer.Tick += OnTimerTick; pivot = new ManipulationPivot2D(); RenderTransformOrigin = new Point(0.5, 0.5); Radius = 75; Center = new Point(0, 0); IsPivotActive = true; Move(Radius, Radius, 0, 1); }
/// <summary> /// Initialize the behavior /// </summary> protected override void OnAttached() { base.OnAttached(); //Initialise default values for public properties IsConstrainedToParentBounds = true; IsRotateEnabled = true; IsTranslateEnabled = true; IsScaleEnabled = true; IsPivotEnabled = true; AreFingersVisible = true; IsInertiaEnabled = true; AreManipulationsEnabled = true; MinimumScaleRadius = 60; MaximumScaleRadius = 240; IgnoredTypes = null; _manipulationProcessor = new ManipulationProcessor2D(SupportedManipulations); _manipulationProcessor.Started += OnManipulationStarted; _manipulationProcessor.Delta += OnManipulationDelta; _manipulationProcessor.Completed += OnManipulationCompleted; _inertiaProcessor = new InertiaProcessor2D { TranslationBehavior = { DesiredDeceleration = Deceleration }, RotationBehavior = { DesiredDeceleration = AngularDeceleration }, ExpansionBehavior = { DesiredDeceleration = ExpansionDeceleration } }; _inertiaProcessor.Delta += OnManipulationDelta; _inertiaProcessor.Completed += OnInertiaCompleted; _inertiaTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(30) }; _inertiaTimer.Tick += OnTimerTick; var centerX = (double)AssociatedObject.ActualWidth / 2 + (double)AssociatedObject.GetValue(Canvas.LeftProperty); var centerY = (double)AssociatedObject.ActualHeight / 2 + (double)AssociatedObject.GetValue(Canvas.TopProperty); AssociatedObject.RenderTransformOrigin = new Point(centerX, centerY); Move(new Point(centerX, centerY), 0, 100); InitializeAssociatedObject(AssociatedObject); }
internal void ApplyParameters(InertiaProcessor2D processor) { processor.InitialOriginX = (float)ManipulationOrigin.X; processor.InitialOriginY = (float)ManipulationOrigin.Y; ManipulationVelocities velocities = InitialVelocities; InertiaTranslationBehavior.ApplyParameters(_translationBehavior, processor, velocities.LinearVelocity); InertiaRotationBehavior.ApplyParameters(_rotationBehavior, processor, velocities.AngularVelocity); InertiaExpansionBehavior.ApplyParameters(_expansionBehavior, processor, velocities.ExpansionVelocity); if (_inertiaParameters != null) { for (int i = 0, count = _inertiaParameters.Count; i < count; i++) { processor.SetParameters(_inertiaParameters[i]); } } }
/// <summary> /// Starts the inertia phase based on the results of a ManipulationInertiaStarting event. /// </summary> internal void BeginInertia(ManipulationInertiaStartingEventArgs e) { if (e.CanBeginInertia()) { _inertiaProcessor = new InertiaProcessor2D(); _inertiaProcessor.Delta += OnManipulationDelta; _inertiaProcessor.Completed += OnInertiaCompleted; e.ApplyParameters(_inertiaProcessor); // Setup a timer to tick the inertia to completion _inertiaTimer = new DispatcherTimer(); _inertiaTimer.Interval = TimeSpan.FromMilliseconds(15); _inertiaTimer.Tick += new EventHandler(OnInertiaTick); _inertiaTimer.Start(); } else { // This is the last event in the sequence. ManipulationCompletedEventArgs completedArguments = GetManipulationCompletedArguments(e); RaiseManipulationCompleted(completedArguments); PushEventsToDevice(); } }
/// <summary> /// Start the inertia processor in Surface screen space. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnAffine2DManipulationCompleted(object sender, Manipulation2DCompletedEventArgs e) { if (inertiaProcessor != null) { inertiaProcessor.Delta -= OnAffine2DInertiaDelta; inertiaProcessor.Completed -= OnAffine2DInertiaCompleted; inertiaProcessor.Complete(stopwatch.Elapsed100Nanoseconds()); } VectorF translation = new VectorF(e.Total.TranslationX, e.Total.TranslationY); // Don't start inertia if the tranlation is less than roughly 1/8" regardless of velocity. if (translation.Length < 96 / 8f) { return; } // Scroll in the opposite direction because a ScrollViewer moves with the touch. VectorF initialVelocity = new VectorF(-e.Velocities.LinearVelocityX, -e.Velocities.LinearVelocityY); // Check velocity. if (initialVelocity.Length < FlickUtilities.MinimumFlickVelocity) { // If velocity is below this threshold ignore it. return; } if (initialVelocity.Length >= FlickUtilities.MaximumFlickVelocity) { // If velocity is too large, reduce it to a reasonable value. initialVelocity.Normalize(); initialVelocity = FlickUtilities.MaximumFlickVelocity * initialVelocity; } processInertia = true; inertiaProcessor = new InertiaProcessor2D(); inertiaProcessor.Delta += OnAffine2DInertiaDelta; inertiaProcessor.Completed += OnAffine2DInertiaCompleted; inertiaProcessor.TranslationBehavior = new InertiaTranslationBehavior2D { DesiredDisplacement = ConvertFromVerticalValueToScreenSpace(VerticalViewportSize), InitialVelocityX = initialVelocity.X * HorizontalViewportSize, InitialVelocityY = initialVelocity.Y * VerticalViewportSize }; inertiaProcessor.InitialOriginX = ConvertFromHorizontalValueToScreenSpace(horizontalScrollBarStateMachine.Value); inertiaProcessor.InitialOriginY = ConvertFromVerticalValueToScreenSpace(verticalScrollBarStateMachine.Value); }
/// <summary> /// Start the flicking behavior. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnAffine2DManipulationCompleted(object sender, Manipulation2DCompletedEventArgs e) { if (inertiaProcessor != null) { inertiaProcessor.Delta -= OnAffine2DInertiaDelta; inertiaProcessor.Completed -= OnAffine2DInertiaCompleted; inertiaProcessor = null; } // The Manipulations should all run in screen space so don't convert between spaces. VectorF initialVelocity; VectorF maxViewPortSize; if (Orientation == Orientation.Horizontal) { initialVelocity = new VectorF(e.Velocities.LinearVelocityX, 0); maxViewPortSize = new VectorF(numberOfPixelsInAxis * viewportSize, 0); } else { initialVelocity = new VectorF(0, e.Velocities.LinearVelocityY); maxViewPortSize = new VectorF(0, numberOfPixelsInAxis * viewportSize); } // Check velocity. if (initialVelocity.Length < FlickUtilities.MinimumFlickVelocity) { return; } if (initialVelocity.Length >= MaximumFlickVelocity) { // If velocity is too large, reduce it to a reasonable value. initialVelocity.Normalize(); initialVelocity = MaximumFlickVelocity * initialVelocity; } VectorF flickDistance; if (FlickUtilities.TryGetFlickDistance(initialVelocity, out flickDistance, maxViewPortSize)) { processInertia = true; inertiaProcessor = new InertiaProcessor2D(); inertiaProcessor.Delta += OnAffine2DInertiaDelta; inertiaProcessor.Completed += OnAffine2DInertiaCompleted; float displacement = 0; if (flickDistance.X == 0) { displacement = flickDistance.Y; } else if (flickDistance.Y == 0) { displacement = flickDistance.X; } else { displacement = Math.Min(flickDistance.X, flickDistance.Y); } inertiaProcessor.TranslationBehavior = new InertiaTranslationBehavior2D { DesiredDisplacement = float.IsInfinity(displacement) ? 0 : Math.Abs(displacement), InitialVelocityX = initialVelocity.X, InitialVelocityY = initialVelocity.Y }; inertiaProcessor.InitialOriginX = ToScreenSpace(Value); inertiaProcessor.InitialOriginY = ToScreenSpace(Value); } }
public override void OnApplyTemplate() { // Set up the ContentPresenter. _content = GetTemplateChild("PART_Content") as ContentPresenter; _translate = new TranslateTransform(); _scale = new ScaleTransform(); _content.RenderTransform = new TransformGroup { Children = new TransformCollection { _scale, _translate } }; _content.RenderTransformOrigin = new Point(.5, .5); // Set up the spring animation. _spring = new Storyboard { Duration = TimeSpan.FromMilliseconds(200), FillBehavior = FillBehavior.Stop, DecelerationRatio = .6 }; _spring.Completed += Spring_Completed; _springScaleX = new DoubleAnimation { Duration = _spring.Duration, To = 1, DecelerationRatio = _spring.DecelerationRatio }; Storyboard.SetTarget(_springScaleX, _content); Storyboard.SetTargetProperty(_springScaleX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)")); _spring.Children.Add(_springScaleX); _springScaleY = new DoubleAnimation { Duration = _spring.Duration, To = 1, DecelerationRatio = _spring.DecelerationRatio }; Storyboard.SetTarget(_springScaleY, _content); Storyboard.SetTargetProperty(_springScaleY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)")); _spring.Children.Add(_springScaleY); _springTranslateX = new DoubleAnimation { Duration = _spring.Duration, To = 0, DecelerationRatio = _spring.DecelerationRatio }; Storyboard.SetTarget(_springTranslateX, _content); Storyboard.SetTargetProperty(_springTranslateX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.X)")); _spring.Children.Add(_springTranslateX); _springTranslateY = new DoubleAnimation { Duration = _spring.Duration, To = 0, DecelerationRatio = _spring.DecelerationRatio }; Storyboard.SetTarget(_springTranslateY, _content); Storyboard.SetTargetProperty(_springTranslateY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)")); _spring.Children.Add(_springTranslateY); _spring.Begin(this, true); ClipToBounds = true; // Set up the ManipulationProcessor. _contentManipulationProcessor = new ManipulationProcessor2D(Manipulations2D.Scale | Manipulations2D.TranslateX | Manipulations2D.TranslateY); _contentManipulationProcessor.Started += ContentManipulationProcessor_Affine2DManipulationStarted; _contentManipulationProcessor.Delta += ContentManipulationProcessor_Affine2DManipulationDelta; _contentManipulationProcessor.Completed += ContentManipulationProcessor_Affine2DManipulationCompleted; // Set up the InertiaProcessor. _inertiaTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(30) }; _inertiaTimer.Tick += (sender, e) => _inertiaProcessor.Process(DateTime.UtcNow.Ticks); _inertiaProcessor = new InertiaProcessor2D(); _inertiaProcessor.Delta += ContentManipulationProcessor_Affine2DManipulationDelta; _inertiaProcessor.Completed += (sender, e) => _inertiaTimer.Stop(); _inertiaProcessor.TranslationBehavior.DesiredDeceleration = (float)(96 * 1.5 * .001 * .001); #warning ElasticMargin has been deprecated. //// _inertiaProcessor.ElasticMargin = new Thickness(25); base.OnApplyTemplate(); }
/// <summary> /// Set the flick to completed so that it stops moving. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void OnAffine2DInertiaCompleted(object sender, Manipulation2DCompletedEventArgs e) { processInertia = false; manipulationProcessor = null; if (inertiaProcessor != null) { inertiaProcessor.Delta -= OnAffine2DInertiaDelta; inertiaProcessor.Completed -= OnAffine2DInertiaCompleted; inertiaProcessor = null; } }
//==========================================================// /// <summary> /// Creates manipulation and inertis processors that support only this item's allowed manipulations. /// </summary> private void SetAllowedManipulations() { Manipulations2D supportedManipulations = ((canTranslate || canTranslateFlick) ? Manipulations2D.TranslateX | Manipulations2D.TranslateY : Manipulations2D.None) | ((canScale || canScaleFlick) ? Manipulations2D.Scale : Manipulations2D.None) | ((canRotate || canRotateFlick) ? Manipulations2D.Rotate : Manipulations2D.None); manipulationProcessor = new ManipulationProcessor2D(supportedManipulations); manipulationProcessor.Started += OnAffine2DManipulationStarted; manipulationProcessor.Delta += OnAffine2DDelta; manipulationProcessor.Completed += OnAffine2DManipulationCompleted; inertiaProcessor = new InertiaProcessor2D(); inertiaProcessor.Completed += OnAffine2DInertiaCompleted; inertiaProcessor.Delta += OnAffine2DDelta; }