《Programming WPF》翻译 第8章 4.关键帧动画

本文深入探讨了关键帧动画在WPF中的使用,解释了如何通过关键帧控制动画的复杂过程,包括从简单动画到关键帧动画的过渡,以及如何通过线性插值和样条插值实现平滑动画效果。通过实例展示了关键帧动画的创建与调整,最终实现了更加流畅和真实的动画表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文: 《Programming WPF》翻译 第8章 4.关键帧动画

到目前为止,我们只看到简单的点到点的动画。我们使用了ToFrom属性或者By属性来设计动画——相对于当前的属性值。这很适合简单的动画,但是我们可以构造序列来创建更复杂的动画,这可能是非常麻烦的。幸运的是,这是没有必要的。WPF提供了动画对象,允许我们详细指出一系列时间和值。

在影视中传统的动画中,这是普通的开始——通过绘制最重要的动画步骤。这些关键帧定义了场景的基本流程,捕获了它的最重要的点。只要一旦这些关键帧是满意的,是保留的帧绘图。这些关键帧之间的图像并不要求非常创造性的输入,它们只是简单的打算添加进去,从一个关键帧到另一个。WPF优化了同样的概念。你可以考虑简单的FromTo方法——等价于提供两个关键帧,一个“before”帧和一个“after”帧——WPF会为你添加这两个帧。关键帧动画简单的扩展了多个帧的概念。

作为最简单的动画类型,关键帧仍然一次性为属性设定目标。因此它们并不与传统动画中关键帧一样,每一帧组成了整个的绘图。你不能提供两个绘图并告诉WPF从一个变换到另一个。

关键帧动画类型使用了命名装换TypeAnimationUsingKeyFrames。示例8-24显示了一个简单的动画:一个弹起的矩形,使用到了DoubleAnimationUsingKeyFrames

示例8-24

< Window  Text ="Key Frames"  Width ="850"  Height ="300"
    xmlns
="http://schemas.microsoft.com/winfx/avalon/2005"
    xmlns:x
="http://schemas.microsoft.com/winfx/xaml/2005" >


    
< Window.Storyboards >
        
< SetterTimeline  TargetName ="rect"  Path ="(Canvas.Left)"
                        RepeatBehavior
="Forever"  AutoReverse ="True" >
            
< DoubleAnimation  From ="0"  To ="800"  Duration ="0:0:10"   />
        
</ SetterTimeline >

        
< SetterTimeline  TargetName ="rect"  Path ="(Canvas.Top)" >
            
< DoubleAnimationUsingKeyFrames  Duration ="0:0:2"
                                           RepeatBehavior
="Forever" >
                
< DoubleAnimationUsingKeyFrames.KeyFrames >
                    
< LinearDoubleKeyFrame  Value ="0"  KeyTime ="0:0:0"   />
                    
< LinearDoubleKeyFrame  Value ="50"  KeyTime ="0:0:0.5"   />
                    
< LinearDoubleKeyFrame  Value ="200"  KeyTime ="0:0:1"   />
                    
< LinearDoubleKeyFrame  Value ="50"  KeyTime ="0:0:1.5"   />
                    
< LinearDoubleKeyFrame  Value ="0"  KeyTime ="0:0:2"   />
                
</ DoubleAnimationUsingKeyFrames.KeyFrames >
            
</ DoubleAnimationUsingKeyFrames >
        
</ SetterTimeline >
    
</ Window.Storyboards >

    
< Canvas >
        
< Rectangle  x:Name ="rect"  Fill ="Red"  Width ="20"  Height ="20"   />
    
</ Canvas >
</ Window >

这里有两个

timeline 。第一个移动矩形从左到右,使用常规的DoubleAnimation ,第二个通过使用DoubleAnimationUsingKeyFrames 控制了垂直的位置。这控制了5 个帧,详细指出了矩形的需要的垂直位置,在半秒的时间内。如图8-12 所示,这些关键帧显示了这个矩形,在它的跳动的顶部和底部,伴随着中途的点比中间点稍微高一点,指出一段时间的速度渐变。WPF 为我们在这些位置之间加入了新元素。

8-12


示例
8-24中每个关键帧的值都使用LinearDoubleKeyFrame详细指出。这说明了使用了线形添写。改变的速度是介于两个帧之间的常量。这就引起了运动并不是特别平滑的。这个矩形在它下降时提高速度,而速度上的改变发生在可见的“阶段”——从动画的一幕到下一幕。我们可以减少这种影响,通过添加更多的关键帧,但是这里有一条更容易的方式。不是图8-13中左边显示的简单线性插值,而是获取一个曲线插值如右边显示,提高了平滑度,而不需要添加更多的关键帧。

8-13


为了在我们想要的动画速度上获取更平滑的改动,我们可以使用
SplineDoubleKeyFrame。带有一个样条关键帧,一条贝塞尔曲线详细指出了动画值是应该如何改变的。可是,这种曲线使用的方式并不是完全直接的。正如我们在第7章看到的,贝塞尔曲线可以用于定义曲线形状。可是,使用动画,我们不能简单地定义路径。一个点沿示例中的贝塞尔曲线而行。这条曲线是一个二维的形状,但是这个动画对象仅修改了y轴,这意味着它只在一个维度上产生影响。(记得示例8-24使用了2SetterTimeline元素,每个都对应一个维度。)

代替以定义点的路径,贝塞尔曲线在一个样条关键帧上定义了一个数学函数的形式。这个函数把它的输入理解为关键帧的流逝时间的比例。作为输出,它提供了一个数字,指出之前的和当前的值混合在一起的比例。这条曲线总是从(0,0)移动到(1,1),但是你定位这两个控制点,决定了它的形状在这些极限之间。使用关键帧的KeySpline属性设置这些值。

8-14显示了3个动画样条的示例,控制点标记在小矩形上。记得这些曲线简单的决定了动画前进的速度。第一个“曲线”是一条直线,意味着这个动画以常速前进。这等价于一个LinearDoubleKeyFrame。第二条曲线指出了动画开始缓慢而后加速。第三条曲线显示了动画开始迅速而后减速到停止。

8-14


示例
8-25是示例8-24的对关键帧的修改版本。这个动画传递了同样的关键帧值,但是使用样条来指出动画的速度应该逐渐改变。这使得这个动画感觉很平滑,而不需要添加更多的关键帧。

示例8-25

< SetterTimeline  TargetName ="rect"  Path ="(Canvas.Top)" >
    
< DoubleAnimationUsingKeyFrames  Duration ="0:0:2"  RepeatBehavior ="Forever" >
        
< DoubleAnimationUsingKeyFrames.KeyFrames >
            
< LinearDoubleKeyFrame  Value ="0"  KeyTime ="0:0:0"   />
            
< SplineDoubleKeyFrame  Value ="50"  KeyTime ="0:0:0.5"
                                  KeySpline
="0.4,0 0.75,0.75"   />
            
< SplineDoubleKeyFrame  Value ="200"  KeyTime ="0:0:1"
                                  KeySpline
="0.2,0.2 1,0.4"   />
            
< SplineDoubleKeyFrame  Value ="50"  KeyTime ="0:0:1.5"
                                  KeySpline
="0,0.3 0.75,0.75"   />
            
< SplineDoubleKeyFrame  Value ="0"  KeyTime ="0:0:2"
                                  KeySpline
="0.25,0.25 0.6,1"   />
        
</ DoubleAnimationUsingKeyFrames 
.KeyFrames
>
    
</ DoubleAnimationUsingKeyFrames >
</ SetterTimeline >

第一帧仍然使用

LinearDoubleKeyFrame ,因为这里没有“before ”帧以进行插值。两个“downward ”关键帧使用了曲线形状——类似于图8-14 中间的那个。这导致了这个动画开始缓慢然后加速,正如你希望的在一个下落对象的动画中。两个“upward ”关键帧使用了曲线形状——类似于图8-14 右边的那个。这导致了这个动画逐渐缓慢直到这个对象到达顶部。这就提供了一个更有力的可视化近似:关于一个真实的对象是如何运动的。

这里还有一种可利用的的插值样式:四点插值细分算法。如果你使用了这样一个关键帧,WPF根本不会真正地“插值”。它会突然跳到详细指定的值。这就易于引进中断到你的动画中,如果必要。

注意到,WPF提供了关键帧的版本——大多数动画类型都支持它,不仅是Double类型,表8-2列出了这些类型。

Table 8-2. Key-frame animation types

BooleanAnimationUsingKeyFrames

PointAnimationUsingKeyFrames

ByteAnimationUsingKeyFrames

Rect3DAnimationUsingKeyFrames

CharAnimationUsingKeyFrames

RectAnimationUsingKeyFrames

ColorAnimationUsingKeyFrames

Rotation3DAnimationUsingKeyFrames

DecimalAnimationUsingKeyFrames

SingleAnimationUsingKeyFrames

DoubleAnimationUsingKeyFrames

Size3DAnimationUsingKeyFrames

Int16AnimationUsingKeyFrames

SizeAnimationUsingKeyFrames

Int32AnimationUsingKeyFrames

StringAnimationUsingKeyFrames

Int64AnimationUsingKeyFrames

ThicknessAnimationUsingKeyFrames

MatrixAnimationUsingKeyFrames

Vector3DAnimationUsingKeyFrames

Point3DAnimationUsingKeyFrames

VectorAnimationUsingKeyFrames



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值