WPF快速指导15:动画
在WPF或者SilverLight中,所谓动画,就是让一个对象的属性,随着时间而发生变化。动画由时间线(timeline)控制。时间线在C#中的原型为:
{
// 省略
}
它是一个抽象类。在WPF中,定义了各类时间线,最常用的有DoubleAnimation,它便继承自Timeline。
1:Storyboard及一个简单示例
容纳时间线的是故事板(Storyboard)。下面是一个最简单的例子:
前台:
< Image x:Name ="image1" Source ="/WpfApplication1;component/run.jpg" >
</ Image >
< Button x:Name ="buttonTest" Click ="buttonTest_Click" Canvas.Top ="250" Content ="测试" >
</ Button >
</ Canvas >
后台:
{
TranslateTransform animatedTranslateTransform = new TranslateTransform();
image1.RenderTransform = animatedTranslateTransform;
DoubleAnimation doubleAnimation = new DoubleAnimation( 0 , 360 , new Duration(TimeSpan.FromMilliseconds( 1000 )));
this .RegisterName( " AnimatedTranslateTransform " , animatedTranslateTransform);
Storyboard.SetTargetName(doubleAnimation, " AnimatedTranslateTransform " );
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(TranslateTransform.XProperty));
Storyboard translationStoryboard = new Storyboard();
translationStoryboard.Children.Add(doubleAnimation);
translationStoryboard.Begin( this );
}
在这个示例中,Storyboard中,我们使用了DoubleAnimation对象,它表示:随着时间改变一个数值。Storyboard通过SetTargetName方法将DoubleAnimation对象和animatedTranslateTransform联系起来。而animatedTranslateTransform又被指向image1.RenderTransform(关于RenderTransform属性,不明白的可以查看上篇《WPF快速指导14:变换》)。这就相当于说,动画被关联到了image1对象上。
这里面要重点讲一下SetTargetProperty方法。该方法第一个参数指定动画对象,第二个方法指的是,在SetTarget方法中被关联的那个的对象的一个属性。在本文的实例中,这个属性是TranslateTransform.XProperty。串联起来,本示例的需求就是:“在1000毫秒的时间里,让image1的TranslateTransform.XProperty属性由0变为360”。如果我们换一个属性,如TranslateTransform.XProperty,则表达的意思是:“在1000毫秒的时间里,让image1离最高处由0变为360”。
本示例运行效果:
2:关键帧
在上面的这个例子中,我们使用的线性插值。为了调整这个行为,可以用一组关键帧(key frame)来过渡。这也就是说,为了更改动画从起始属性到结束属性的线性行为,可插入一个或者多个关键帧。查看下面的示例:
image1.RenderTransform = animatedTranslateTransform;
this .RegisterName( " AnimatedTranslateTransform " , animatedTranslateTransform);
DoubleAnimationUsingKeyFrames translationAnimation = new DoubleAnimationUsingKeyFrames();
translationAnimation.Duration = TimeSpan.FromSeconds( 6 );
translationAnimation.KeyFrames.Add( new LinearDoubleKeyFrame( 500 , KeyTime.FromTimeSpan(TimeSpan.FromSeconds( 3 ))));
translationAnimation.KeyFrames.Add( new DiscreteDoubleKeyFrame( 400 , KeyTime.FromTimeSpan(TimeSpan.FromSeconds( 4 ))));
translationAnimation.KeyFrames.Add( new SplineDoubleKeyFrame( 0 , KeyTime.FromTimeSpan(TimeSpan.FromSeconds( 6 )), new KeySpline( 0.6 , 0.0 , 0.9 ,
0.0 )));
translationAnimation.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTargetName(translationAnimation, " AnimatedTranslateTransform " );
Storyboard.SetTargetProperty(translationAnimation, new PropertyPath(TranslateTransform.XProperty));
Storyboard translationStoryboard = new Storyboard();
translationStoryboard.Children.Add(translationAnimation);
translationStoryboard.Begin( this );
在这个示例中,一个共有3个关键帧:LinearDoubleKeyFrame,DiscreteDoubleKeyFrame,SplineDoubleKeyFrame。
LinearDoubleKeyFrame指的是:这是一个线性关键帧。
DiscreteDoubleKeyFrame指的是:这是一个离散关键帧。
SplineDoubleKeyFrame指的是:这是一个加速和减速关键帧。
要体会它们之间的差异,可以运行代码,任何语言描述不抵一次视觉感受。
3:动画缓动
缓动(Easing)允许我们创建各类动画效果,类似反弹或者弹簧效果。如BounceEase,模拟的就是一种弹跳效果。在第一个示例中,我们加入如下语句:
就会发现图片在到达终点会弹跳,然后结束。所有内建的缓动类,都在System.Windows.Media.Animation命名空间中,它们都以Ease结尾。
本代码的源码下载:WpfApplication1.rar