wpf动画,WPF 动画笔记

Demo在这里 http://files.cnblogs.com/xiaokang088/WpfAnimation.zip
  1. Animation结构
以DoubleAnimation 来看结构,如下:
System. Object System.Windows.Threading. DispatcherObject System.Windows. DependencyObject System.Windows. Freezable System.Windows.Media.Animation. Animatable System.Windows.Media.Animation. Timeline System.Windows.Media.Animation. AnimationTimeline System.Windows.Media.Animation. DoubleAnimationBase System.Windows.Media.Animation. DoubleAnimation System.Windows.Media.Animation. DoubleAnimationUsingKeyFrames System.Windows.Media.Animation. DoubleAnimationUsingPath
DoubleAnimtionBase以下有三种动画类型
最常用的是DoubleAnimation,最熟悉的了。
其次是DoubleAnimtionUsingKeyFrames,这个最丰富,他的KeyFrams能够接受三种类型的KeyFrame,分别是离散、线性、样条,后面详述。
最后是DoubleAnimtionUsingPath,这个最有意思,可以沿着一个指定的轨迹来进行动画,最好玩的是MatrixAnimtionUsingPath。
DoubleAnimtionBase 是Double类动画的一个基础类,如果要自定义一个Double动画,可以继承DoubleAnimtionBase来写,如下,其中GetCurrentValueCore和CreateInstanceCore是一定要重写的。
public class TestAnimation : DoubleAnimationBase { public static readonly DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(double?), typeof(TestAnimation)); public double? From { get { return (double?)GetValue(FromProperty); } set { SetValue(FromProperty, value); } } public static readonly DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(double?), typeof(TestAnimation)) public double? To { get { return (double?)GetValue(ToProperty); } set { SetValue(ToProperty, value); } } public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register("Interval", typeof(double?), typeof(TestAnimation)) public double? Interval { get { return (double?)GetValue(IntervalProperty); } set { SetValue(IntervalProperty, value); } } protected override double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock) { double returnValue; double from = 0, delta = 0; from = From.HasValue ? From.Value : defaultOriginValue; delta = To.HasValue ? To.Value - from : defaultDestinationValue - from; returnValue = (int)(animationClock.CurrentProgress.Value * delta / 30) * 30 + from; if (animationClock.CurrentProgress.Value == 1) returnValue = from + delta; return returnValue; } protected override Freezable CreateInstanceCore() { return new TestAnimation(); } }
往上看
AnimationTimeline,这个是Animtion的鼻祖了,提供了多个对动画来说很重要的方法,如下:
public AnimationClock CreateClock();
public virtual object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock);
关于CreateClock,据说,用clock的效率会比较高,如下代码:
AnimationClock myClock = myAnimation.CreateClock(); //1.据说这样写效率比较高 myScaleTransform.ApplyAnimationClock( ScaleTransform.ScaleXProperty, myClock); myScaleTransform.ApplyAnimationClock( ScaleTransform.ScaleYProperty, myClock); //myScaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, myAnimation); //myScaleTransform.BeginAnimation(ScaleTransform.ScaleYProperty, myAnimation);
Timeline,动画进行的基础,这些动画都是基于时间轴进行的,所以提供了很多基础的成员,例如属性:
public double AccelerationRatio { get; set; } public bool AutoReverse { get; set; } public TimeSpan? BeginTime { get; set; } public double DecelerationRatio { get; set; } public Duration Duration { get; set; } public FillBehavior FillBehavior { get; set; } public RepeatBehavior RepeatBehavior { get; set; } public double SpeedRatio { get; set; }
2.接上详细阐述DoubleAnimtionUsingKeyFrames 看例子:

LinearDoubleKeyFrame 线性动画,3秒钟后到left=500,匀速移动到500的位置
DiscreteDoubleKeyFrame 离散动画,接上一个动画,4秒的时候突然蹦到400的位置
SplineDoubleKeyFrame 样条动画,这个最复杂了,6秒后到达10的位置。
若要了解 KeySpline 的工作原理,首先需要了解三次方贝塞尔曲线。 一条三次方贝塞尔曲线由一个起点、一个终点和两个控制点来定义。KeySpline 中的两个坐标定义了这两个控制点。 在描述关键样条时,贝塞尔曲线的起点始终为 0,终点始终为 1,这也就是只定义两个控制点的原因。得到的曲线指定了如何在一个时间段内内插动画;也就是说,该曲线表示动画的目标属性在该时间段内的变化速度。为了更好地了解动画进度与贝塞尔曲线之间的关系,请参见 Key Spline Animation Sample(关键样条动画示例http://msdn.microsoft.com/zh-cn/library/ms771640(VS.85).aspx)。
附件Demo里面也有例子,请仔细看。
另外,KeyTime也是很有讲究的,

为普通的计时方式,00:00:04即为本段动画时间为4秒

10%代表本段动画耗时占全部时间的10%

所有KeyFrame耗时都是一样的

所有KeyFrame都是匀速的,个人觉得这个很鸡肋。
详见Demo
3.接上,阐述MatrixAnimationUsingPath
让元素沿着轨迹走,而且DoesRotateWithTangent=True可以控制元素朝着轨迹的方向。

4.关注比较少的属性
By 以往只注意了From、To ,起始值和终止值,By可以获取或设置动画更改其起始值时依据的总量。如果同时设置了 To 和 By 属性,则 To 属性优先,而 By 属性会被忽略。
IsAdditve:获取或设置一个值,该值指示是否应将目标属性的当前值与此动画的起始值相加。如果动画仅设置了其 From、 To 或 By 属性之一,则设置此属性将无效。
IsCumulative 获取或设置动画更改其起始值时依据的总量。如果同时设置了 To 和 By 属性,则 To 属性优先,而 By 属性会被忽略。
5.关于StoryBoard,先看继承结构
System. Object System.Windows.Threading. DispatcherObject System.Windows. DependencyObject System.Windows. Freezable System.Windows.Media.Animation. Animatable System.Windows.Media.Animation. Timeline System.Windows.Media.Animation. TimelineGroup System.Windows.Media.Animation. ParallelTimeline System.Windows.Media.Animation. Storyboard
Storyboard 继承与ParallelTimeline,那么ParallelTimeline是个什么东西呢?看例子:


ParallelTimeline 把几个动画放到一起,可以控制开始时间。
StoryBoard在继承了ParallelTimeline后,增加了一个常用的操作,例如Begin/Stop/Pause等操作和TargetProperty等属性
Tags: 

延伸阅读

最新评论

发表评论