Exemplo n.º 1
0
        // Terminate transformation in a clean way, "freeing" animated properties
        private void EndMatrixAnimation()
        {
            IsMatrixAnimationInProgress = false;
            MainMatrixTransform.BeginAnimation(MatrixTransform.MatrixProperty, null);

            // Final tasks
            MainMatrixTransform.Matrix = rescaleMatrix;
        }
Exemplo n.º 2
0
        // 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();
            }
        }