zoukankan      html  css  js  c++  java
  • 《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



  • 相关阅读:
    iOS 发送位置消息
    集成 jpush-react-native 常见问题汇总 (iOS 篇)
    RESTful API 最佳实践
    RESTful API 设计指南
    理解RESTful架构
    PHP 调用 shell
    Laravel Model updating&updated 事件使用注意事项
    sudo 命令报 unable to resolve host 导致反应速度变慢
    Nginx设置禁止通过IP访问服务器并且只能通过指定域名访问
    Homestead can not mount nfs on macos catalina
  • 原文地址:https://www.cnblogs.com/Jax/p/1136933.html
Copyright © 2011-2022 走看看