private void TestMatrix_Click(object sender, RoutedEventArgs e) { Matrix matrix = Matrix.Identity; matrix.Translate(10, 20); matrix.Rotate(50); MatrixAnimation ma = new MatrixAnimation(Matrix.Identity, matrix, TimeSpan.FromMilliseconds(1000)); mt.BeginAnimation(MatrixTransform.MatrixProperty, ma); }
private static void CreateRecoverStoryboard(FrameworkElement element) { var delay = GetWaitForRecover(element); if (delay > TimeSpan.Zero) { var key = element.GetHashCode(); var mt = (element.RenderTransform as MatrixTransform); var to = _origin.ContainsKey(key) ? _origin[key] : new Matrix(); var speed = 10 * 96.0 / 1000.0;//速度 var time = Math.Sqrt(Math.Pow(mt.Matrix.OffsetX - to.OffsetX, 2) + Math.Pow(mt.Matrix.OffsetY - to.OffsetY, 2)) / speed; var animation = new MatrixAnimation() { From = mt.Matrix, To = to, FillBehavior = FillBehavior.HoldEnd, Duration = new Duration(TimeSpan.FromMilliseconds(time)), EasingFunction = new BackEase() { EasingMode = EasingMode.EaseInOut } }; Storyboard.SetTarget(animation, element); Storyboard.SetTargetProperty(animation, new PropertyPath("(0).(1)", FrameworkElement.RenderTransformProperty, MatrixTransform.MatrixProperty)); var booleanAnimation = new BooleanAnimationUsingKeyFrames() { FillBehavior = FillBehavior.Stop }; booleanAnimation.KeyFrames.Add(new DiscreteBooleanKeyFrame(false, TimeSpan.Zero)); booleanAnimation.KeyFrames.Add(new DiscreteBooleanKeyFrame(true, animation.Duration.TimeSpan)); Storyboard.SetTarget(booleanAnimation, element); Storyboard.SetTargetProperty(booleanAnimation, new PropertyPath(UIElement.IsHitTestVisibleProperty)); var opacityAnimation = new DoubleAnimation(0.7, 1, animation.Duration, FillBehavior.Stop); Storyboard.SetTarget(opacityAnimation, element); Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(UIElement.OpacityProperty)); var s = new Storyboard() { BeginTime = delay }; s.Children.Add(animation); s.Children.Add(booleanAnimation); s.Children.Add(opacityAnimation); s.Completed += (ss, ee) => { _currentScale[key] = 1.0; _recoverStoryboard.Remove(key); }; s.Freeze(); s.Begin(); _recoverStoryboard[key] = s; } }
private void Animate(Transform newValue, TransitionSpeed transitionSpeed) { var duration = TransitionSpeedToDuration(transitionSpeed); var matrixAnimation = new MatrixAnimation(newValue.Value, duration, FillBehavior.HoldEnd) { EasingFunction = GetEasingFunction(transitionSpeed) }; Timeline.SetDesiredFrameRate(matrixAnimation, FrameRate); RenderTransform.BeginAnimation(MatrixTransform.MatrixProperty, matrixAnimation, HandoffBehavior.SnapshotAndReplace); }
/// <summary> /// Set element position with or whitout animation /// </summary> /// <param name="toElement">target element to move</param> /// <param name="DoAnimation">do or do not animation</param> /// <param name="animation">To and From value will be setted. If null a default animation will be used</param> public void SetPosition(FrameworkElement toElement, bool DoAnimation = false, MatrixAnimation animation = null) { this.Element.UpdateLayout(); GeneralTransform trans_MovableInFrom_Offset_On_To = toElement.TransformToVisual(this.Element); Matrix reverseMatrix = (trans_MovableInFrom_Offset_On_To as MatrixTransform).Matrix; Transform transform = this.ElementTransform; MatrixTransform mt = Utility.GetMatrixTransformFromTransform(transform); Matrix newMatrix = mt.Matrix; newMatrix.Prepend(reverseMatrix); Matrix oldMatrix = mt.Matrix; MatrixTransform matrixTransform = new MatrixTransform(oldMatrix); if (DoAnimation) { if (animation != null) { animation.From = oldMatrix; animation.To = newMatrix; } else { animation = new MatrixAnimation(oldMatrix, newMatrix, new Duration(new TimeSpan(0, 0, 1))) { EasingFunction = new PowerEase { EasingMode = EasingMode.EaseInOut, Power = 2 } }; } this.ElementTransform = (MatrixTransform)matrixTransform; if (!DoAnimation) { animation.Duration = new Duration(new TimeSpan(0)); } matrixTransform.BeginAnimation(MatrixTransform.MatrixProperty, animation); } else { this.ElementTransform = new MatrixTransform(newMatrix); } }
/// <summary> /// Reset element transform. Set actual transform to Origin transform /// </summary> public void ResetTransform() { MatrixTransform mt = Utility.GetMatrixTransformFromTransform(this.ElementTransform); Matrix oldMatrix = mt.Matrix; Matrix newMatrix = Utility.GetMatrixTransformFromTransform(OriginalElementTransform).Matrix; MatrixAnimation matrixAnimation = new MatrixAnimation(oldMatrix, newMatrix, new Duration(new TimeSpan(0, 0, 1))) { EasingFunction = new PowerEase { EasingMode = EasingMode.EaseInOut, Power = 2 } }; MatrixTransform matrixTransform = new MatrixTransform(oldMatrix); this.ElementTransform = (MatrixTransform)matrixTransform; matrixTransform.BeginAnimation(MatrixTransform.MatrixProperty, matrixAnimation); }
// Adjust scale and origin to see the whole puzzle internal void RescaleAndCenter(bool isWithAnimation) { if (viewModel.Layout == null) { return; } BoundingRectangle r = viewModel.Layout.Bounds; // Add some extra margin and always represent a 20x20 grid at minimum r = new BoundingRectangle(Math.Min(-11, r.Min.Row - 3), Math.Max(11, r.Max.Row + 4), Math.Min(-11, r.Min.Column - 3), Math.Max(11, r.Max.Column + 4)); // Reverse-transform corners into WordCanvas coordinates Point p1Grid = new Point(r.Min.Column * UnitSize, r.Min.Row * UnitSize); Point p2Grid = new Point(r.Max.Column * UnitSize, r.Max.Row * UnitSize); rescaleMatrix = MainMatrixTransform.Matrix; // Set rotation to zero // Get angle from transformation matrix double θ = Math.Atan2(rescaleMatrix.M21, rescaleMatrix.M11); // Just to use a variable named θ rescaleMatrix.Rotate(θ / Math.PI * 180); // It would certainly kill Microsoft to indicate on Rotate page or Intellisense tooltip that angle is in degrees... // First adjust scale Point p1Screen = rescaleMatrix.Transform(p1Grid); Point p2Screen = rescaleMatrix.Transform(p2Grid); double rescaleFactorX = ClippingCanvas.ActualWidth / (p2Screen.X - p1Screen.X); double rescaleFactorY = ClippingCanvas.ActualHeight / (p2Screen.Y - p1Screen.Y); double rescaleFactor = Math.Min(rescaleFactorX, rescaleFactorY); rescaleMatrix.Scale(rescaleFactor, rescaleFactor); // Then adjust location and center p1Screen = rescaleMatrix.Transform(p1Grid); p2Screen = rescaleMatrix.Transform(p2Grid); double offX1 = -p1Screen.X; double offX2 = ClippingCanvas.ActualWidth - p2Screen.X; double offY1 = -p1Screen.Y; double offY2 = ClippingCanvas.ActualHeight - p2Screen.Y; rescaleMatrix.Translate((offX1 + offX2) / 2, (offY1 + offY2) / 2); if (isWithAnimation) { // Use an animation for a smooth transformation MatrixAnimation ma = new MatrixAnimation { From = MainMatrixTransform.Matrix, To = rescaleMatrix, Duration = new Duration(TimeSpan.FromSeconds(0.35)) }; ma.Completed += MatrixAnimationCompleted; IsMatrixAnimationInProgress = true; MainMatrixTransform.BeginAnimation(MatrixTransform.MatrixProperty, ma); } else { EndMatrixAnimation(); } }