MatrixAnimationUsingPath.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Animation / MatrixAnimationUsingPath.cs / 1305600 / MatrixAnimationUsingPath.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File: PathMatrixAnimation.cs 
//-----------------------------------------------------------------------------
 
using MS.Internal; 
using System;
using System.IO; 
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Reflection; 
using System.Runtime.InteropServices;
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Markup;
using System.Windows.Media.Animation; 
using System.Windows.Media.Composition;

namespace System.Windows.Media.Animation
{ 
    /// 
    /// This animation can be used inside of a MatrixAnimationCollection to move 
    /// a visual object along a path. 
    /// 
    public class MatrixAnimationUsingPath : MatrixAnimationBase 
    {
        #region Data

        private bool _isValid; 

        ///  
        /// If IsCumulative is set to true, these values represents the values 
        /// that are accumulated with each repeat.  They are the end values of
        /// the path. 
        /// 
        private Vector _accumulatingOffset = new Vector();
        private double _accumulatingAngle;
 
        #endregion
 
        #region Constructors 

        ///  
        /// Creates a new PathMatrixAnimation class.
        /// 
        /// 
        /// There is no default PathGeometry so the user must specify one. 
        /// 
        public MatrixAnimationUsingPath() 
            : base() 
        {
        } 

        #endregion

        #region Freezable 

        ///  
        /// Creates a copy of this PathMatrixAnimation. 
        /// 
        /// The copy. 
        public new MatrixAnimationUsingPath Clone()
        {
            return (MatrixAnimationUsingPath)base.Clone();
        } 

        ///  
        /// Implementation of Freezable.CreateInstanceCore. 
        /// 
        /// The new Freezable. 
        protected override Freezable CreateInstanceCore()
        {
            return new MatrixAnimationUsingPath();
        } 

        ///  
        /// Implementation of Freezable.OnChanged. 
        /// 
        protected override void OnChanged() 
        {
            _isValid = false;

            base.OnChanged(); 
        }
 
        #endregion 

        #region Public 

        /// 
        /// DoesRotateWithTangent Property
        ///  
        public static readonly DependencyProperty DoesRotateWithTangentProperty =
                DependencyProperty.Register( 
                    "DoesRotateWithTangent", 
                    typeof(bool),
                    typeof(MatrixAnimationUsingPath), 
                    new PropertyMetadata(false));

        /// 
        /// If this is set to true, the object will rotate along with the 
        /// tangent to the path.
        ///  
        public bool DoesRotateWithTangent 
        {
            get 
            {
                return (bool)GetValue(DoesRotateWithTangentProperty);
            }
            set 
            {
                SetValue(DoesRotateWithTangentProperty, value); 
            } 
        }
 
        /// 
        /// IsAdditive
        /// 
        public bool IsAdditive 
        {
            get 
            { 
                return (bool)GetValue(IsAdditiveProperty);
            } 
            set
            {
                SetValue(IsAdditiveProperty, value);
            } 
        }
 
        ///  
        /// IsAngleCumulative Property
        ///  
        public static readonly DependencyProperty IsAngleCumulativeProperty =
                DependencyProperty.Register(
                    "IsAngleCumulative",
                    typeof(bool), 
                    typeof(MatrixAnimationUsingPath),
                    new PropertyMetadata(false)); 
 
        /// 
        /// If this property is set to true, the rotation angle of the animated matrix 
        /// will accumulate over repeats of the animation.  For instance if
        /// your path is a small arc a cumulative angle will cause your object
        /// to continuously rotate with each repeat instead of restarting the
        /// rotation.  When combined with IsOffsetCumulative, your object may 
        /// appear to tumble while it bounces depending on your path.
        /// See PathMatrixAnimation.IsOffsetCumulative 
        /// for related information. 
        /// 
        /// default value: false 
        public bool IsAngleCumulative
        {
            get
            { 
                return (bool)GetValue(IsAngleCumulativeProperty);
            } 
            set 
            {
                SetValue(IsAngleCumulativeProperty, value); 
            }
        }

        ///  
        /// IsOffsetCumulative Property
        ///  
        public static readonly DependencyProperty IsOffsetCumulativeProperty = 
                DependencyProperty.Register(
                    "IsOffsetCumulative", 
                    typeof(bool),
                    typeof(MatrixAnimationUsingPath),
                    new PropertyMetadata(false));
 
        /// 
        /// If this property is set to true, the offset of the animated matrix 
        /// will accumulate over repeats of the animation.  For instance if 
        /// your path is a small arc a cumulative offset will cause your object
        /// to appear to bounce once for each repeat. 
        /// See PathMatrixAnimation.IsAngleCumulative
        /// for related information.
        /// 
        /// default value: false 
        public bool IsOffsetCumulative
        { 
            get 
            {
                return (bool)GetValue(IsOffsetCumulativeProperty); 
            }
            set
            {
                SetValue(IsOffsetCumulativeProperty, value); 
            }
        } 
 
        /// 
        /// PathGeometry Property 
        /// 
        public static readonly DependencyProperty PathGeometryProperty =
                DependencyProperty.Register(
                    "PathGeometry", 
                    typeof(PathGeometry),
                    typeof(MatrixAnimationUsingPath), 
                    new PropertyMetadata( 
                        (PathGeometry)null));
 
        /// 
        /// This geometry specifies the path.
        /// 
        public PathGeometry PathGeometry 
        {
            get 
            { 
                return (PathGeometry)GetValue(PathGeometryProperty);
            } 
            set
            {
                SetValue(PathGeometryProperty, value);
            } 
        }
 
        #endregion 

        #region MatrixAnimationBase 

        /// 
        /// Calculates the value this animation believes should be the current value for the property.
        ///  
        /// 
        /// This value is the suggested origin value provided to the animation 
        /// to be used if the animation does not have its own concept of a 
        /// start value. If this animation is the first in a composition chain
        /// this value will be the snapshot value if one is available or the 
        /// base property value if it is not; otherise this value will be the
        /// value returned by the previous animation in the chain with an
        /// animationClock that is not Stopped.
        ///  
        /// 
        /// This value is the suggested destination value provided to the animation 
        /// to be used if the animation does not have its own concept of an 
        /// end value. This value will be the base value if the animation is
        /// in the first composition layer of animations on a property; 
        /// otherwise this value will be the output value from the previous
        /// composition layer of animations for the property.
        /// 
        ///  
        /// This is the animationClock which can generate the CurrentTime or
        /// CurrentProgress value to be used by the animation to generate its 
        /// output value. 
        /// 
        ///  
        /// The value this animation believes should be the current value for the property.
        /// 
        protected override Matrix GetCurrentValueCore(Matrix defaultOriginValue, Matrix defaultDestinationValue, AnimationClock animationClock)
        { 
            Debug.Assert(animationClock.CurrentState != ClockState.Stopped);
 
            PathGeometry pathGeometry = PathGeometry; 

            if (pathGeometry == null) 
            {
                return defaultDestinationValue;
            }
 
            if (!_isValid)
            { 
                Validate(); 
            }
 
            Point pathPoint;
            Point pathTangent;

            pathGeometry.GetPointAtFractionLength(animationClock.CurrentProgress.Value, out pathPoint, out pathTangent); 

            double angle = 0.0; 
 
            if (DoesRotateWithTangent)
            { 
                angle = DoubleAnimationUsingPath.CalculateAngleFromTangentVector(pathTangent.X, pathTangent.Y);
            }

            Matrix matrix = new Matrix(); 

            double currentRepeat = (double)(animationClock.CurrentIteration - 1); 
 
            if (currentRepeat > 0)
            { 
                if (IsOffsetCumulative)
                {
                    pathPoint = pathPoint + (_accumulatingOffset * currentRepeat);
                } 

                if (   DoesRotateWithTangent 
                    && IsAngleCumulative) 
                {
                    angle = angle + (_accumulatingAngle * currentRepeat); 
                }
            }

            matrix.Rotate(angle); 
            matrix.Translate(pathPoint.X, pathPoint.Y);
 
            if (IsAdditive) 
            {
                return Matrix.Multiply(matrix, defaultOriginValue); 
            }
            else
            {
                return matrix; 
            }
        } 
 
        #endregion
 
        #region Private Methods

        private void Validate()
        { 
            Debug.Assert(!_isValid);
 
            if (   IsOffsetCumulative 
                || IsAngleCumulative)
            { 
                Point startPoint;
                Point startTangent;
                Point endPoint;
                Point endTangent; 
                PathGeometry pathGeometry = PathGeometry;
 
                // Get values at the beginning of the path. 
                pathGeometry.GetPointAtFractionLength(0.0, out startPoint, out startTangent);
 
                // Get values at the end of the path.
                pathGeometry.GetPointAtFractionLength(1.0, out endPoint, out endTangent);

                // Calculate difference. 
                _accumulatingAngle = DoubleAnimationUsingPath.CalculateAngleFromTangentVector(endTangent.X, endTangent.Y)
                                     - DoubleAnimationUsingPath.CalculateAngleFromTangentVector(startTangent.X, startTangent.Y); 
 
                _accumulatingOffset.X = endPoint.X - startPoint.X;
                _accumulatingOffset.Y = endPoint.Y - startPoint.Y; 
            }

            _isValid = true;
        } 

        #endregion 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File: PathMatrixAnimation.cs 
//-----------------------------------------------------------------------------
 
using MS.Internal; 
using System;
using System.IO; 
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Reflection; 
using System.Runtime.InteropServices;
using System.Windows; 
using System.Windows.Media; 
using System.Windows.Markup;
using System.Windows.Media.Animation; 
using System.Windows.Media.Composition;

namespace System.Windows.Media.Animation
{ 
    /// 
    /// This animation can be used inside of a MatrixAnimationCollection to move 
    /// a visual object along a path. 
    /// 
    public class MatrixAnimationUsingPath : MatrixAnimationBase 
    {
        #region Data

        private bool _isValid; 

        ///  
        /// If IsCumulative is set to true, these values represents the values 
        /// that are accumulated with each repeat.  They are the end values of
        /// the path. 
        /// 
        private Vector _accumulatingOffset = new Vector();
        private double _accumulatingAngle;
 
        #endregion
 
        #region Constructors 

        ///  
        /// Creates a new PathMatrixAnimation class.
        /// 
        /// 
        /// There is no default PathGeometry so the user must specify one. 
        /// 
        public MatrixAnimationUsingPath() 
            : base() 
        {
        } 

        #endregion

        #region Freezable 

        ///  
        /// Creates a copy of this PathMatrixAnimation. 
        /// 
        /// The copy. 
        public new MatrixAnimationUsingPath Clone()
        {
            return (MatrixAnimationUsingPath)base.Clone();
        } 

        ///  
        /// Implementation of Freezable.CreateInstanceCore. 
        /// 
        /// The new Freezable. 
        protected override Freezable CreateInstanceCore()
        {
            return new MatrixAnimationUsingPath();
        } 

        ///  
        /// Implementation of Freezable.OnChanged. 
        /// 
        protected override void OnChanged() 
        {
            _isValid = false;

            base.OnChanged(); 
        }
 
        #endregion 

        #region Public 

        /// 
        /// DoesRotateWithTangent Property
        ///  
        public static readonly DependencyProperty DoesRotateWithTangentProperty =
                DependencyProperty.Register( 
                    "DoesRotateWithTangent", 
                    typeof(bool),
                    typeof(MatrixAnimationUsingPath), 
                    new PropertyMetadata(false));

        /// 
        /// If this is set to true, the object will rotate along with the 
        /// tangent to the path.
        ///  
        public bool DoesRotateWithTangent 
        {
            get 
            {
                return (bool)GetValue(DoesRotateWithTangentProperty);
            }
            set 
            {
                SetValue(DoesRotateWithTangentProperty, value); 
            } 
        }
 
        /// 
        /// IsAdditive
        /// 
        public bool IsAdditive 
        {
            get 
            { 
                return (bool)GetValue(IsAdditiveProperty);
            } 
            set
            {
                SetValue(IsAdditiveProperty, value);
            } 
        }
 
        ///  
        /// IsAngleCumulative Property
        ///  
        public static readonly DependencyProperty IsAngleCumulativeProperty =
                DependencyProperty.Register(
                    "IsAngleCumulative",
                    typeof(bool), 
                    typeof(MatrixAnimationUsingPath),
                    new PropertyMetadata(false)); 
 
        /// 
        /// If this property is set to true, the rotation angle of the animated matrix 
        /// will accumulate over repeats of the animation.  For instance if
        /// your path is a small arc a cumulative angle will cause your object
        /// to continuously rotate with each repeat instead of restarting the
        /// rotation.  When combined with IsOffsetCumulative, your object may 
        /// appear to tumble while it bounces depending on your path.
        /// See PathMatrixAnimation.IsOffsetCumulative 
        /// for related information. 
        /// 
        /// default value: false 
        public bool IsAngleCumulative
        {
            get
            { 
                return (bool)GetValue(IsAngleCumulativeProperty);
            } 
            set 
            {
                SetValue(IsAngleCumulativeProperty, value); 
            }
        }

        ///  
        /// IsOffsetCumulative Property
        ///  
        public static readonly DependencyProperty IsOffsetCumulativeProperty = 
                DependencyProperty.Register(
                    "IsOffsetCumulative", 
                    typeof(bool),
                    typeof(MatrixAnimationUsingPath),
                    new PropertyMetadata(false));
 
        /// 
        /// If this property is set to true, the offset of the animated matrix 
        /// will accumulate over repeats of the animation.  For instance if 
        /// your path is a small arc a cumulative offset will cause your object
        /// to appear to bounce once for each repeat. 
        /// See PathMatrixAnimation.IsAngleCumulative
        /// for related information.
        /// 
        /// default value: false 
        public bool IsOffsetCumulative
        { 
            get 
            {
                return (bool)GetValue(IsOffsetCumulativeProperty); 
            }
            set
            {
                SetValue(IsOffsetCumulativeProperty, value); 
            }
        } 
 
        /// 
        /// PathGeometry Property 
        /// 
        public static readonly DependencyProperty PathGeometryProperty =
                DependencyProperty.Register(
                    "PathGeometry", 
                    typeof(PathGeometry),
                    typeof(MatrixAnimationUsingPath), 
                    new PropertyMetadata( 
                        (PathGeometry)null));
 
        /// 
        /// This geometry specifies the path.
        /// 
        public PathGeometry PathGeometry 
        {
            get 
            { 
                return (PathGeometry)GetValue(PathGeometryProperty);
            } 
            set
            {
                SetValue(PathGeometryProperty, value);
            } 
        }
 
        #endregion 

        #region MatrixAnimationBase 

        /// 
        /// Calculates the value this animation believes should be the current value for the property.
        ///  
        /// 
        /// This value is the suggested origin value provided to the animation 
        /// to be used if the animation does not have its own concept of a 
        /// start value. If this animation is the first in a composition chain
        /// this value will be the snapshot value if one is available or the 
        /// base property value if it is not; otherise this value will be the
        /// value returned by the previous animation in the chain with an
        /// animationClock that is not Stopped.
        ///  
        /// 
        /// This value is the suggested destination value provided to the animation 
        /// to be used if the animation does not have its own concept of an 
        /// end value. This value will be the base value if the animation is
        /// in the first composition layer of animations on a property; 
        /// otherwise this value will be the output value from the previous
        /// composition layer of animations for the property.
        /// 
        ///  
        /// This is the animationClock which can generate the CurrentTime or
        /// CurrentProgress value to be used by the animation to generate its 
        /// output value. 
        /// 
        ///  
        /// The value this animation believes should be the current value for the property.
        /// 
        protected override Matrix GetCurrentValueCore(Matrix defaultOriginValue, Matrix defaultDestinationValue, AnimationClock animationClock)
        { 
            Debug.Assert(animationClock.CurrentState != ClockState.Stopped);
 
            PathGeometry pathGeometry = PathGeometry; 

            if (pathGeometry == null) 
            {
                return defaultDestinationValue;
            }
 
            if (!_isValid)
            { 
                Validate(); 
            }
 
            Point pathPoint;
            Point pathTangent;

            pathGeometry.GetPointAtFractionLength(animationClock.CurrentProgress.Value, out pathPoint, out pathTangent); 

            double angle = 0.0; 
 
            if (DoesRotateWithTangent)
            { 
                angle = DoubleAnimationUsingPath.CalculateAngleFromTangentVector(pathTangent.X, pathTangent.Y);
            }

            Matrix matrix = new Matrix(); 

            double currentRepeat = (double)(animationClock.CurrentIteration - 1); 
 
            if (currentRepeat > 0)
            { 
                if (IsOffsetCumulative)
                {
                    pathPoint = pathPoint + (_accumulatingOffset * currentRepeat);
                } 

                if (   DoesRotateWithTangent 
                    && IsAngleCumulative) 
                {
                    angle = angle + (_accumulatingAngle * currentRepeat); 
                }
            }

            matrix.Rotate(angle); 
            matrix.Translate(pathPoint.X, pathPoint.Y);
 
            if (IsAdditive) 
            {
                return Matrix.Multiply(matrix, defaultOriginValue); 
            }
            else
            {
                return matrix; 
            }
        } 
 
        #endregion
 
        #region Private Methods

        private void Validate()
        { 
            Debug.Assert(!_isValid);
 
            if (   IsOffsetCumulative 
                || IsAngleCumulative)
            { 
                Point startPoint;
                Point startTangent;
                Point endPoint;
                Point endTangent; 
                PathGeometry pathGeometry = PathGeometry;
 
                // Get values at the beginning of the path. 
                pathGeometry.GetPointAtFractionLength(0.0, out startPoint, out startTangent);
 
                // Get values at the end of the path.
                pathGeometry.GetPointAtFractionLength(1.0, out endPoint, out endTangent);

                // Calculate difference. 
                _accumulatingAngle = DoubleAnimationUsingPath.CalculateAngleFromTangentVector(endTangent.X, endTangent.Y)
                                     - DoubleAnimationUsingPath.CalculateAngleFromTangentVector(startTangent.X, startTangent.Y); 
 
                _accumulatingOffset.X = endPoint.X - startPoint.X;
                _accumulatingOffset.Y = endPoint.Y - startPoint.Y; 
            }

            _isValid = true;
        } 

        #endregion 
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK