WPF关键帧动画介绍与实现

2022-04-16 21:17:36
目录
动画与关键帧的区别普通动画关键帧介绍关键帧动画关键帧动画类型关键帧的动画类型列表帧对象的类型插值方法线性内插离散内插曲线内插组合内插Duration与KeyTimeTimeSpan百分比UniformPaced关键帧时间及顺序

本章介绍关键帧动画之前, 首先需要讲解一下关于WPF当中基础动画与本章所讲的关键帧动画的区别。

动画与关键帧的区别

普通动画

WPF基础动画当中, 我们熟悉的From/To/By驱动的动画, 主要在两个值之间创建过渡效果, 如下图所示:

> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="TranslateTransform01" Storyboard.TargetProperty="X" Duration="0:0:10" RepeatBehavior="Forever"> <!-- KeyTime properties are expressed as TimeSpan values which are in the form of "hours:minutes:seconds". --> <LinearDoubleKeyFrame Value="100" KeyTime="0:0:3" /> <LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" /> <LinearDoubleKeyFrame Value="500" KeyTime="0:0:9" /> <LinearDoubleKeyFrame Value="600" KeyTime="0:0:10" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </BeginStoryboard> </EventTrigger> </Rectangle.Triggers></Rectangle>

百分比

百分比值指定关键帧以动画的某些Duration百分比结束。 在 XAML 中,指定百分比作为 % 符号后的数字。 在代码中,使用FromPercent方法并传递一个Double指示百分比的方法。 该值必须大于或等于 0 并且小于或等于 100%。 以下示例演示一个持续时间为 10 秒钟、有四个关键帧(这些关键帧的关键时间指定为百分比)的动画。

在前 3 秒钟内,第一个关键帧将在基值和 100 之间进行动画处理,结束时间 = 0:0:3。第二个关键帧在 100 和 200 之间进行动画处理。 它在第一个关键帧结束后开始(开始时间 = 3 秒),播放 5 秒钟,结束时间 = 0:0:8 (0.8 * 10 = 8)。第三个关键帧在 200 和 500 之间进行动画处理。 它在第二个关键帧结束时开始(开始时间 = 8 秒),播放 1 秒钟,结束时间 = 0:0:9 (0.9 * 10 = 9)。第四个关键帧在 500 和 600 之间进行动画处理。 它在第三个关键帧结束时开始(开始时间 = 9 秒),播放 1 秒钟,结束时间 = 0:0:10 (1 * 10 = 10)。
      <Rectangle Height="50" Width="50" Fill="Purple">  <Rectangle.RenderTransform>    <TranslateTransform x:Name="TranslateTransform02" X="10" Y="110" />  </Rectangle.RenderTransform>  <Rectangle.Triggers>    <EventTrigger RoutedEvent="Rectangle.Loaded">      <BeginStoryboard>        <Storyboard>          <DoubleAnimationUsingKeyFrames             Storyboard.TargetName="TranslateTransform02"             Storyboard.TargetProperty="X"            Duration="0:0:10"            RepeatBehavior="Forever">            <!-- KeyTime properties are expressed as Percentages. -->            <LinearDoubleKeyFrame Value="100" KeyTime="30%" />            <LinearDoubleKeyFrame Value="200" KeyTime="80%" />            <LinearDoubleKeyFrame Value="500" KeyTime="90%" />            <LinearDoubleKeyFrame Value="600" KeyTime="100%" />          </DoubleAnimationUsingKeyFrames>        </Storyboard>      </BeginStoryboard>    </EventTrigger>  </Rectangle.Triggers></Rectangle>

Uniform

当您Uniform希望每个关键帧花费相同的时间时,请使用计时。
Uniform关键时间将可用时间平均除以关键帧数,以确定每个关键帧的结束时间。 下面的示例显示持续时间为 10 秒的动画和四个关键帧,其关键时间指定为Uniform。

在前 2.5 秒钟内,第一个关键帧在基值和 100 之间进行动画处理,结束时间 = 0:0:2.5。第二个关键帧在 100 和 200 之间进行动画处理。 它在第一个关键帧结束后开始(开始时间 = 2.5 秒),播放大约 2.5 秒钟,结束时间 = 0:0:5。第三个关键帧在 200 和 500 之间进行动画处理。 它在第二个关键帧结束时开始(开始时间 = 5 秒),播放 2.5 秒钟,结束时间 = 0:0:7.5。第四个关键帧在 500 和 600 之间进行动画处理。 它在第二个关键帧结束时开始(开始时间 = 7.5 秒),播放 2.5 秒钟,结束时间 = 0:0:1。
      <Rectangle Height="50" Width="50" Fill="Red">  <Rectangle.RenderTransform>    <TranslateTransform x:Name="TranslateTransform03" X="10" Y="190" />  </Rectangle.RenderTransform>  <Rectangle.Triggers>    <EventTrigger RoutedEvent="Rectangle.Loaded">      <BeginStoryboard>        <Storyboard>          <DoubleAnimationUsingKeyFrames             Storyboard.TargetName="TranslateTransform03"             Storyboard.TargetProperty="X"            Duration="0:0:10"            RepeatBehavior="Forever">            <!-- KeyTime properties are expressed with values of Uniform.                  When a key time is set to "Uniform" the total allotted                  time of the animation is divided evenly between key frames.                   In this example, the total duration of the animation is                  ten seconds and there are four key frames each of which                  are set to "Uniform", therefore, the duration of each key frame                  is 3.3 seconds (10/3). -->            <LinearDoubleKeyFrame Value="100" KeyTime="Uniform" />            <LinearDoubleKeyFrame Value="200" KeyTime="Uniform" />            <LinearDoubleKeyFrame Value="500" KeyTime="Uniform" />            <LinearDoubleKeyFrame Value="600" KeyTime="Uniform" />          </DoubleAnimationUsingKeyFrames>        </Storyboard>      </BeginStoryboard>    </EventTrigger>  </Rectangle.Triggers></Rectangle>

Paced

如果要Paced以恒定速率进行动画处理,请使用计时。
Paced关键时间根据每个关键帧的长度分配可用时间,以确定每个帧的持续时间。 这样,动画的速度或速率将保持不变。 下面的示例显示持续时间为 10 秒的动画和三个关键帧,其关键时间指定为Paced。

      <Rectangle Height="50" Width="50" Fill="Orange">  <Rectangle.RenderTransform>    <TranslateTransform x:Name="TranslateTransform04" X="10" Y="270" />  </Rectangle.RenderTransform>  <Rectangle.Triggers>    <EventTrigger RoutedEvent="Rectangle.Loaded">      <BeginStoryboard>        <Storyboard>          <DoubleAnimationUsingKeyFrames             Storyboard.TargetName="TranslateTransform04"             Storyboard.TargetProperty="X"            Duration="0:0:10"            RepeatBehavior="Forever">            <!-- KeyTime properties are expressed witwww.easck.comh values of Paced.                  Paced values are used when a constant rate is desired.                  The time allocated to a key frame with a KeyTime of "Paced"                  is determined by the time allocated to the other key                  frames of the animation. This time is calculated to                  attempt to give a "paced" or "constant velocity"                  for the animation. -->            <LinearDoubleKeyFrame Value="100" KeyTime="Paced" />            <LinearDoubleKeyFrame Value="200" KeyTime="Paced" />            <LinearDoubleKeyFrame Value="500" KeyTime="Paced" />            <LinearDoubleKeyFrame Value="600" KeyTime="Paced" />          </DoubleAnimationUsingKeyFrames>        </Storyboard>      </BeginStoryboard>    </EventTrigger>  </Rectangle.Triggers></Rectangle>

关键帧时间及顺序

可以在同一动画中使用具有不同KeyTime值类型的关键帧。 尽管建议以关键帧的实际播放顺序来添加关键帧,但此操作不是必需的。 动画和计时系统能够处理顺序紊乱的关键帧。 将忽略关键时间无效的关键帧。
下表描述了为关键帧动画的关键帧解析关键时间的过程。

1 解析TimeSpanKeyTime值。2 确定动画的总内插时间,即关键帧动画完成向前迭代所需的全部时间。
如果动画的Duration不是Automatic或Forever,则总插值时间是动画Duration属性的值。
否则,总插值时间是其关键帧(TimeSpanKeyTime如果有)之间指定的最大值。
否则,总内插时间为 1 秒。3 使用总插值时间值解析PercentKeyTime值。4 如果最后一个关键帧尚未在之前步骤中解析,则将解析该关键帧。 如果最后KeyTime一个关键帧为Uniform或Paced,则其解析时间将等于总插值时间。
如果第KeyTime一个关键帧的,Paced并且此动画比关键帧多,则将其KeyTime值解析为零;如果只有一个关键帧,并且其KeyTime值为Paced,则解析为总插值时间,如上一步所述。5 解析剩余UniformKeyTime值:每个值都给定可用时间的相等份额。 在此过程中PacedKeyTime,未解析的值将暂时视为UniformKeyTime值,并获得临时解析的时间。6 使用声明KeyTime的最接近具有已解析KeyTime值的关键帧,解决未指定密钥时间的关键帧的值。7 解析剩余PacedKeyTime值。 PacedKeyTime使用相邻KeyTime关键帧的值来确定其解析时间。 目的是确保动画速度在此关键帧的解析时间内保持固定不变。8 按解析时间(主键)和声明顺序(辅助键)对关键帧进行排序,即根据已解决的关键帧KeyTime值使用稳定排序。

 到此这篇关于WPF关键帧动画介绍与实现的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。