1. 普通动画的目标属性:
普通UI控件属性,如Width,Height等;变换特效属性;三维变换特效属性。
普通UI控件属性会触发布局系统重新工作,因此首选后两种属性进行动画运用。
动画类位于Windows.UI.Xaml.Media.Animation命名空间下。
基于时间线动画,继承自Timeline:
线性插值动画,即From/To/By动画,反映对象在指定时间范围内持续渐变。
关键帧动画,更强大,可以指定任意数量目标值,控制它们之间的插值方法。
基于帧动画:
有些动画无法通过以上方法实现,通常是复杂动画,如模拟雪花飘落。每一帧都通过事件重绘界面。
2. 线性插值动画有DoubleAnimation,ColorAnimation和PointAnimation,分别对Double,Color,Point类型的属性进行动画处理。
From:起始值
To:目标值,如果同时设置By,则优先于By
By:变化量值,对非数值类型没有意义
Duration:完整播放一次动画的时间长度,默认为1秒,格式为“时:分:秒”(TimeSpan对象),如果在代码中设置,则使用TimeSpan隐式转换为Duration。Duration提供了两个属性,Automatic和Forever。
AutoReverse:时间线是否自动倒退,默认为false。
FillBehavior:确定在到达其活动期末尾时是否保留最终值。
RepeatBehavior:时间线重复播放次数。
RepeatBehavior有三种语法:
设置为“Forever”,表示无限重复;
重复运行次数,由一个整数迭代次数,和字符x构成,如“3x”表示三次;
时间跨度,格式为 “[天.]时:分:秒[.秒小数部分]”。
DoubleAnimation与Transform结合可以实现变换动画,只需指定Storyboard的TargetName和TargetProperty属性,与所用Transform关联。
ColorAnimation本质是对RGB色值的线性处理。用法类似,注意TargetProperty属性的设置,如:(Button.Background).(SolidColorBrush.Color)。
PointAnimation是Point的线性运动,可以实现Path的动画。
3. 关键帧动画
在早期的动画片制作中,关键画面由熟练动画师设计,也就是关键帧,中间帧由一般动画师设计。
概念就是这样引入到计算机动画,不过使用插值来代替中间帧的动画师。
线性插值动画可以创建两个值之间的过渡,关键帧动画可以创建任意数量的目标值之间的过渡。
关键帧动画的目标值是使用关键帧对象KeyFrame来描述。
需注意的属性:
KeyTime:所在帧的Value的设置时刻。可以以时间值TimeSpan来指定,或者指定为Uniform均匀划分。必须在动画Duration之内才有效。
BeginTime:延迟动画的起始部分,帧内KeyTime值的时间线在BeginTime到达前不开始计数。
关键帧动画内插方法有三种:线性、样条、离散。样条关键帧通过贝赛尔曲线来定义动画变化。
相关动画类有:ColorAnimationUsingKeyFrames、Double...、Point...、Object...,其中ObjectAnimationUsingKeyFrames内插方法只能是离散的。
线性帧动画,顾名思义变换是线性的。
相关动画关键帧类有:LinearDoubleKeyFrame、...
样条帧动画:与线性帧动画相比,每个帧都有一个KeySpline属性,使用三次贝赛尔曲线来定义动画插值方式,这样动画就具有了更真实的加速减速效果,如自由落体,淡入淡出等。曲线的起始点和结束点分别为(0,0)和(1,1),在KeySpline属性中定义的是两个控制点。
相关动画关键帧类有:SplineDoubleKeyFrame、...
离散帧动画:到达KeyTime,属性值直接突变,因此不够流畅平滑,但支持更多的属性类型。
相关动画关键帧类:Discrete<数据类型>KeyFrame,如DiscretePointKeyFrame、...
能用于ObjectAnimationUsingKeyFrames的只有DiscreteObjectFrame。
4. 缓动函数动画
WP内置了11种缓动函数动画,在使用时只需设置动画的EasingFunction属性即可,EasingFunction的EasingMode属性指定缓动的方式。
下面以y表示动画进度,x表示时间。
BackEase:在动画处理中,略微收回动画的动作。属性Amplitude指定收回幅度。注意收回时可能超过目标属性正常范围。y = x^3 - x*a*sin(x*π)。
BounceEase:类似球落地的弹跳效果。Bounces指定弹跳此时,Bounciness指定弹跳程度,即前后两个弹跳的幅度倍数。
CircleEase:循环,加速/减速效果。x^2 + (y-1)^2 = 1。
ElasticEase:弹簧效果,振幅可以越来越大或越来越小,Oscillations指定来回振动次数,Springiness指定弹性。同样注意可能超过目标属性正常范围。
ExponentialEase:含指数公式加速/减速动画。Exponent属性用于确定动画的内插的指数,默认值为2。y = (e^(a*x)-1) / (e^a-1)。
PowerEase:y = x^p,其中p是Power属性(QuadraticEase:y = x^2;CubicEase:y = x^3;QuarticEase:y = x^4;QuinticEase:y = x^5)。
SineEase:正弦公式。y = 1 - sin((1-x)*π/2)。
5. 基于帧动画
顾名思义是依赖于帧的,不依赖时间。
通过订阅CompositionTarget.Rendering事件,在每次呈现一帧时事件触发,可以实现逐帧处理一些内容。
线性插值和关键帧动画是在动画的构图线程运行的,而CompositionTarget.Rendering事件运行在UI线程,因此效率低。
6. 动画方案选择
帧速率,单位即FPS。
帧速率计数器默认能在Debug时显示在屏幕上,在App.xaml.cs中通过代码可以改变设置。
构图线程:Composition Thread,可以处理某些UI线程上的工作,合并图形纹理并传递到GPU以供绘制,处理与变换特效、三维特效属性相关的动画,StoryBoard动画都是完全运行在构图线程上的。
一般从两个方面衡量实现方案:性能和复杂度。考虑以下三点:
变换特效属性和三维特效属性实现的动画,是通过构图线程对UI元素产生作用的,不会调用布局系统,不会阻塞UI线程;元素本身其它属性,如改变Width属性实现的动画会阻塞UI线程。
线性插值和关键帧动画,是在构图线程上运行的。