DoubleAnimationUsingPath.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media / Animation / DoubleAnimationUsingPath.cs / 1 / DoubleAnimationUsingPath.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, 2003
//
//  File: PathDoubleAnimation.cs 
//-----------------------------------------------------------------------------
 
using MS.Internal; 
using System;
using System.ComponentModel; 
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 
 
namespace System.Windows.Media.Animation
{ 
    /// 
    /// This animation can be used inside of a MatrixAnimationCollection to move
    /// a visual object along a path.
    ///  
    public class DoubleAnimationUsingPath : DoubleAnimationBase
    { 
        #region Data 

        private bool _isValid; 

        /// 
        /// If IsCumulative is set to true, this value represents the value that
        /// is accumulated with each repeat.  It is the end value of the path 
        /// output value for the path.
        ///  
        private double _accumulatingValue; 

        #endregion 

        #region Constructors

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

        #endregion 
 
        #region Public
 
        /// 
        /// PathGeometry Property
        /// 
        public static readonly DependencyProperty PathGeometryProperty = 
            DependencyProperty.Register(
                    "PathGeometry", 
                    typeof(PathGeometry), 
                    typeof(DoubleAnimationUsingPath),
                    new PropertyMetadata( 
                        (PathGeometry)null));

        /// 
        /// This geometry specifies the path. 
        /// 
        public PathGeometry PathGeometry 
        { 
            get
            { 
                return (PathGeometry)GetValue(PathGeometryProperty);
            }
            set
            { 
                SetValue(PathGeometryProperty, value);
            } 
        } 

        ///  
        /// Source Property
        /// 
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register( 
                    "Source",
                    typeof(PathAnimationSource), 
                    typeof(DoubleAnimationUsingPath), 
                    new PropertyMetadata(PathAnimationSource.X));
 
        /// 
        /// This property specifies which output property of a path this
        /// animation will represent.
        ///  
        /// 
        public PathAnimationSource Source 
        { 
            get
            { 
                return (PathAnimationSource)GetValue(SourceProperty);
            }
            set
            { 
                SetValue(SourceProperty, value);
            } 
        } 

        #endregion 

        #region Freezable

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

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

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

            base.OnChanged();
        }
 
        #endregion
 
        #region DoubleAnimationBase 

        ///  
        /// 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 double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock)
        {
            Debug.Assert(animationClock.CurrentState != ClockState.Stopped);
 
            PathGeometry pathGeometry = PathGeometry;
 
            if (pathGeometry == null) 
            {
                return defaultDestinationValue; 
            }

            if (!_isValid)
            { 
                Validate();
            } 
 
            Point pathPoint;
            Point pathTangent; 
            double pathValue = 0.0;

            pathGeometry.GetPointAtFractionLength(animationClock.CurrentProgress.Value, out pathPoint, out pathTangent);
 
            switch (Source)
            { 
                case PathAnimationSource.Angle: 
                    pathValue = CalculateAngleFromTangentVector(pathTangent.X, pathTangent.Y);
                    break; 

                case PathAnimationSource.X:
                    pathValue = pathPoint.X;
                    break; 

                case PathAnimationSource.Y: 
                    pathValue = pathPoint.Y; 
                    break;
            } 

            double currentRepeat = (double)(animationClock.CurrentIteration - 1);

            if (   IsCumulative 
                && currentRepeat > 0)
            { 
                pathValue += (_accumulatingValue * currentRepeat); 
            }
 
            if (IsAdditive)
            {
                return defaultOriginValue + pathValue;
            } 
            else
            { 
                return pathValue; 
            }
        } 

        /// 
        /// IsAdditive
        ///  
        public bool IsAdditive
        { 
            get 
            {
                return (bool)GetValue(IsAdditiveProperty); 
            }
            set
            {
                SetValue(IsAdditiveProperty, value); 
            }
        } 
 
        /// 
        /// IsCumulative 
        /// 
        public bool IsCumulative
        {
            get 
            {
                return (bool)GetValue(IsCumulativeProperty); 
            } 
            set
            { 
                SetValue(IsCumulativeProperty, value);
            }
        }
 
        #endregion
 
        #region Private Methods 

        ///  
        /// The primary purpose of this method is to calculate the accumulating
        /// value if one of the properties changes.
        /// 
        private void Validate() 
        {
            Debug.Assert(!_isValid); 
 
            if (IsCumulative)
            { 
                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);

                switch (Source) 
                {
                    case PathAnimationSource.Angle: 
                        _accumulatingValue = CalculateAngleFromTangentVector(endTangent.X, endTangent.Y) 
                                             - CalculateAngleFromTangentVector(startTangent.X, startTangent.Y);
                        break; 

                    case PathAnimationSource.X:
                        _accumulatingValue = endPoint.X - startPoint.X;
                        break; 

                    case PathAnimationSource.Y: 
                        _accumulatingValue = endPoint.Y - startPoint.Y; 
                        break;
                } 
            }

            _isValid = true;
        } 

        internal static double CalculateAngleFromTangentVector(double x, double y) 
        { 
            double angle = Math.Acos(x) * (180.0 / Math.PI);
 
            if (y < 0.0)
            {
                angle = 360 - angle;
            } 

            return angle; 
        } 

        #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: PathDoubleAnimation.cs 
//-----------------------------------------------------------------------------
 
using MS.Internal; 
using System;
using System.ComponentModel; 
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 
 
namespace System.Windows.Media.Animation
{ 
    /// 
    /// This animation can be used inside of a MatrixAnimationCollection to move
    /// a visual object along a path.
    ///  
    public class DoubleAnimationUsingPath : DoubleAnimationBase
    { 
        #region Data 

        private bool _isValid; 

        /// 
        /// If IsCumulative is set to true, this value represents the value that
        /// is accumulated with each repeat.  It is the end value of the path 
        /// output value for the path.
        ///  
        private double _accumulatingValue; 

        #endregion 

        #region Constructors

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

        #endregion 
 
        #region Public
 
        /// 
        /// PathGeometry Property
        /// 
        public static readonly DependencyProperty PathGeometryProperty = 
            DependencyProperty.Register(
                    "PathGeometry", 
                    typeof(PathGeometry), 
                    typeof(DoubleAnimationUsingPath),
                    new PropertyMetadata( 
                        (PathGeometry)null));

        /// 
        /// This geometry specifies the path. 
        /// 
        public PathGeometry PathGeometry 
        { 
            get
            { 
                return (PathGeometry)GetValue(PathGeometryProperty);
            }
            set
            { 
                SetValue(PathGeometryProperty, value);
            } 
        } 

        ///  
        /// Source Property
        /// 
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register( 
                    "Source",
                    typeof(PathAnimationSource), 
                    typeof(DoubleAnimationUsingPath), 
                    new PropertyMetadata(PathAnimationSource.X));
 
        /// 
        /// This property specifies which output property of a path this
        /// animation will represent.
        ///  
        /// 
        public PathAnimationSource Source 
        { 
            get
            { 
                return (PathAnimationSource)GetValue(SourceProperty);
            }
            set
            { 
                SetValue(SourceProperty, value);
            } 
        } 

        #endregion 

        #region Freezable

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

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

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

            base.OnChanged();
        }
 
        #endregion
 
        #region DoubleAnimationBase 

        ///  
        /// 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 double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock)
        {
            Debug.Assert(animationClock.CurrentState != ClockState.Stopped);
 
            PathGeometry pathGeometry = PathGeometry;
 
            if (pathGeometry == null) 
            {
                return defaultDestinationValue; 
            }

            if (!_isValid)
            { 
                Validate();
            } 
 
            Point pathPoint;
            Point pathTangent; 
            double pathValue = 0.0;

            pathGeometry.GetPointAtFractionLength(animationClock.CurrentProgress.Value, out pathPoint, out pathTangent);
 
            switch (Source)
            { 
                case PathAnimationSource.Angle: 
                    pathValue = CalculateAngleFromTangentVector(pathTangent.X, pathTangent.Y);
                    break; 

                case PathAnimationSource.X:
                    pathValue = pathPoint.X;
                    break; 

                case PathAnimationSource.Y: 
                    pathValue = pathPoint.Y; 
                    break;
            } 

            double currentRepeat = (double)(animationClock.CurrentIteration - 1);

            if (   IsCumulative 
                && currentRepeat > 0)
            { 
                pathValue += (_accumulatingValue * currentRepeat); 
            }
 
            if (IsAdditive)
            {
                return defaultOriginValue + pathValue;
            } 
            else
            { 
                return pathValue; 
            }
        } 

        /// 
        /// IsAdditive
        ///  
        public bool IsAdditive
        { 
            get 
            {
                return (bool)GetValue(IsAdditiveProperty); 
            }
            set
            {
                SetValue(IsAdditiveProperty, value); 
            }
        } 
 
        /// 
        /// IsCumulative 
        /// 
        public bool IsCumulative
        {
            get 
            {
                return (bool)GetValue(IsCumulativeProperty); 
            } 
            set
            { 
                SetValue(IsCumulativeProperty, value);
            }
        }
 
        #endregion
 
        #region Private Methods 

        ///  
        /// The primary purpose of this method is to calculate the accumulating
        /// value if one of the properties changes.
        /// 
        private void Validate() 
        {
            Debug.Assert(!_isValid); 
 
            if (IsCumulative)
            { 
                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);

                switch (Source) 
                {
                    case PathAnimationSource.Angle: 
                        _accumulatingValue = CalculateAngleFromTangentVector(endTangent.X, endTangent.Y) 
                                             - CalculateAngleFromTangentVector(startTangent.X, startTangent.Y);
                        break; 

                    case PathAnimationSource.X:
                        _accumulatingValue = endPoint.X - startPoint.X;
                        break; 

                    case PathAnimationSource.Y: 
                        _accumulatingValue = endPoint.Y - startPoint.Y; 
                        break;
                } 
            }

            _isValid = true;
        } 

        internal static double CalculateAngleFromTangentVector(double x, double y) 
        { 
            double angle = Math.Acos(x) * (180.0 / Math.PI);
 
            if (y < 0.0)
            {
                angle = 360 - angle;
            } 

            return angle; 
        } 

        #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