如何:控制关键帧动画的计时

此示例演示如何在关键帧动画内控制关键帧的计时。 像其他动画一样,关键帧动画具有 Duration 属性。 除了指定动画的持续时间外,您还需要指定为动画的各个关键帧分配持续时间内的一段多长时间。 若要分配时间,请为动画中的每个关键帧指定 KeyTime

每个关键帧的 KeyTime 指定关键帧在何时结束(它未指定关键帧播放的时间长度)。 您可以采用以下形式指定 KeyTimeTimeSpan 值、百分比或者 UniformPaced 特殊值。

示例

下面的示例使用 DoubleAnimationUsingKeyFrames 对横跨屏幕的矩形进行动画处理。 关键帧的关键时间是用 TimeSpan 值设置的。

'            
'               This Rectangle is animated with KeyTimes using TimeSpan Values. 
'               It moves horizontally to 100 in the first 3 seconds, 100 to 300 in 
'               the next second, and 300 to 500 in the last 6 seconds.
'            

            ' Create the a rectangle.
            Dim aRectangle As New Rectangle()
            aRectangle.Fill = Brushes.Blue
            aRectangle.Stroke = Brushes.Black
            aRectangle.StrokeThickness = 5
            aRectangle.Width = 50
            aRectangle.Height = 50

            ' Create a transform to move the rectangle
            ' across the screen.
            Dim translateTransform1 As New TranslateTransform()
            aRectangle.RenderTransform = translateTransform1

            ' Create a DoubleAnimationUsingKeyFrames
            ' to animate the transform.
            Dim transformAnimation As New DoubleAnimationUsingKeyFrames()
            transformAnimation.Duration = TimeSpan.FromSeconds(10)

            ' Animate to 100 at 3 seconds.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(100, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(3))))

            ' Animate to 300 at 4 seconds.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(300, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(4))))

            ' Animate to 500 at 10 seconds.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(500, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(10))))

            ' Start the animation when the rectangle is loaded.
            AddHandler aRectangle.Loaded, Sub(sender As Object, e As RoutedEventArgs) translateTransform1.BeginAnimation(TranslateTransform.XProperty, transformAnimation)

            /*
               This Rectangle is animated with KeyTimes using TimeSpan Values. 
               It moves horizontally to 100 in the first 3 seconds, 100 to 300 in 
               the next second, and 300 to 500 in the last 6 seconds.
            */

            // Create the a rectangle.
            Rectangle aRectangle = new Rectangle();
            aRectangle.Fill = Brushes.Blue;
            aRectangle.Stroke = Brushes.Black;
            aRectangle.StrokeThickness = 5;
            aRectangle.Width = 50;
            aRectangle.Height = 50;

            // Create a transform to move the rectangle
            // across the screen.
            TranslateTransform translateTransform1 = 
                new TranslateTransform();
            aRectangle.RenderTransform = translateTransform1;

            // Create a DoubleAnimationUsingKeyFrames
            // to animate the transform.
            DoubleAnimationUsingKeyFrames transformAnimation = 
                new DoubleAnimationUsingKeyFrames();
            transformAnimation.Duration = TimeSpan.FromSeconds(10);

            // Animate to 100 at 3 seconds.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(100, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(3))));

            // Animate to 300 at 4 seconds.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(300, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(4))));

            // Animate to 500 at 10 seconds.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(500, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(10))));

            // Start the animation when the rectangle is loaded.
            aRectangle.Loaded += delegate(object sender, RoutedEventArgs e)
            {
                translateTransform1.BeginAnimation(TranslateTransform.XProperty, transformAnimation);
            };

<!-- This Rectangle is animated with KeyTimes using TimeSpan Values. 
     It moves horizontally to 100 in the first 3 seconds, 100 to 300 in 
     the next second, and 300 to 500 in the last 6 seconds. -->
<Rectangle Fill="Blue" Stroke="Black" StrokeThickness="5"
  Width="50" Height="50">
  <Rectangle.RenderTransform>
    <TranslateTransform x:Name="TranslateTransform1" />
  </Rectangle.RenderTransform>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimationUsingKeyFrames 
            Storyboard.TargetName="TranslateTransform1" 
            Storyboard.TargetProperty="X"
            Duration="0:0:10">

            <!-- These KeyTime properties are specified as TimeSpan values 
                 which are in the form of "hours:minutes:seconds". -->
            <LinearDoubleKeyFrame Value="100" KeyTime="0:0:3" />
            <LinearDoubleKeyFrame Value="300" KeyTime="0:0:4" />
            <LinearDoubleKeyFrame Value="500" KeyTime="0:0:10" />
          </DoubleAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers>
</Rectangle>

下图显示达到每个关键帧的值的时间。

在 3、4 和 10 秒时达到的关键值

下一示例演示一个相同的动画,只是关键帧的关键时间是用百分比值设置的。

'            
'              This rectangle moves horizontally to 100 in the first 3 seconds, 
'              100 to 300 in  the next second, and 300 to 500 in the last 6 seconds.
'            

            ' Create the a rectangle.
            Dim aRectangle As New Rectangle()
            aRectangle.Fill = Brushes.Purple
            aRectangle.Stroke = Brushes.Black
            aRectangle.StrokeThickness = 5
            aRectangle.Width = 50
            aRectangle.Height = 50

            ' Create a transform to move the rectangle
            ' across the screen.
            Dim translateTransform2 As New TranslateTransform()
            aRectangle.RenderTransform = translateTransform2

            ' Create a DoubleAnimationUsingKeyFrames
            ' to animate the transform.
            Dim transformAnimation As New DoubleAnimationUsingKeyFrames()
            transformAnimation.Duration = TimeSpan.FromSeconds(10)

            ' Animate to 100 at 30% of the animation's duration.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(100, KeyTime.FromPercent(0.3)))

            ' Animate to 300 at 40% of the animation's duration.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(300, KeyTime.FromPercent(0.4)))

            ' Animate to 500 at 100% of the animation's duration.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(500, KeyTime.FromPercent(1.0)))

            ' Start the animation when the rectangle is loaded.
            AddHandler aRectangle.Loaded, Sub(sender As Object, e As RoutedEventArgs) translateTransform2.BeginAnimation(TranslateTransform.XProperty, transformAnimation)
/*
  This rectangle moves horizontally to 100 in the first 3 seconds, 
  100 to 300 in  the next second, and 300 to 500 in the last 6 seconds.
*/

// Create the a rectangle.
Rectangle aRectangle = new Rectangle();
aRectangle.Fill = Brushes.Purple;
aRectangle.Stroke = Brushes.Black;
aRectangle.StrokeThickness = 5;
aRectangle.Width = 50;
aRectangle.Height = 50;

// Create a transform to move the rectangle
// across the screen.
TranslateTransform translateTransform2 =
    new TranslateTransform();
aRectangle.RenderTransform = translateTransform2;

// Create a DoubleAnimationUsingKeyFrames
// to animate the transform.
DoubleAnimationUsingKeyFrames transformAnimation =
    new DoubleAnimationUsingKeyFrames();
transformAnimation.Duration = TimeSpan.FromSeconds(10);

// Animate to 100 at 30% of the animation's duration.
transformAnimation.KeyFrames.Add(
    new LinearDoubleKeyFrame(100, KeyTime.FromPercent(0.3)));

// Animate to 300 at 40% of the animation's duration.
transformAnimation.KeyFrames.Add(
    new LinearDoubleKeyFrame(300, KeyTime.FromPercent(0.4)));

// Animate to 500 at 100% of the animation's duration.
transformAnimation.KeyFrames.Add(
    new LinearDoubleKeyFrame(500, KeyTime.FromPercent(1.0)));

// Start the animation when the rectangle is loaded.
aRectangle.Loaded += delegate(object sender, RoutedEventArgs e)
{
    translateTransform2.BeginAnimation(TranslateTransform.XProperty, transformAnimation);
};
<!-- This rectangle moves horizontally to 100 in the first 3 seconds, 
     100 to 300 in  the next second, and 300 to 500 in the last 6 seconds.-->
<Rectangle Fill="Purple" Stroke="Black" StrokeThickness="5"
  Width="50" Height="50">
  <Rectangle.RenderTransform>
    <TranslateTransform x:Name="TranslateTransform2" />
  </Rectangle.RenderTransform>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimationUsingKeyFrames 
            Storyboard.TargetName="TranslateTransform2" 
            Storyboard.TargetProperty="X"
            Duration="0:0:10">

            <!-- KeyTime properties are expressed as Percentages. -->
            <LinearDoubleKeyFrame Value="100" KeyTime="30%" />
            <LinearDoubleKeyFrame Value="300" KeyTime="40%" />
            <LinearDoubleKeyFrame Value="500" KeyTime="100%" />
          </DoubleAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers>
</Rectangle>

下图显示达到每个关键帧的值的时间。

在 3、4 和 10 秒时达到的关键值

下一示例使用 Uniform 关键时间值。

'            
'               This rectangle is animated with KeyTimes using Uniform values. 
'               Goes to 100 in the first 3.3 seconds, 100 to
'               300 in the next 3.3 seconds, 300 to 500 in the last 3.3 seconds.
'            

            ' Create the a rectangle.
            Dim aRectangle As New Rectangle()
            aRectangle.Fill = Brushes.Red
            aRectangle.Stroke = Brushes.Black
            aRectangle.StrokeThickness = 5
            aRectangle.Width = 50
            aRectangle.Height = 50

            ' Create a transform to move the rectangle
            ' across the screen.
            Dim translateTransform3 As New TranslateTransform()
            aRectangle.RenderTransform = translateTransform3

            ' Create a DoubleAnimationUsingKeyFrames
            ' to animate the transform.
            Dim transformAnimation As New DoubleAnimationUsingKeyFrames()
            transformAnimation.Duration = TimeSpan.FromSeconds(10)

'            
'               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).
'             

            ' Animate to 100.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(100, KeyTime.Uniform))

            ' Animate to 300.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(300, KeyTime.Uniform))

            ' Animate to 500.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(500, KeyTime.Uniform))

            ' Start the animation when the rectangle is loaded.
            AddHandler aRectangle.Loaded, Sub(sender As Object, e As RoutedEventArgs) translateTransform3.BeginAnimation(TranslateTransform.XProperty, transformAnimation)

            /*
               This rectangle is animated with KeyTimes using Uniform values. 
               Goes to 100 in the first 3.3 seconds, 100 to
               300 in the next 3.3 seconds, 300 to 500 in the last 3.3 seconds.
            */

            // Create the a rectangle.
            Rectangle aRectangle = new Rectangle();
            aRectangle.Fill = Brushes.Red;
            aRectangle.Stroke = Brushes.Black;
            aRectangle.StrokeThickness = 5;
            aRectangle.Width = 50;
            aRectangle.Height = 50;

            // Create a transform to move the rectangle
            // across the screen.
            TranslateTransform translateTransform3 =
                new TranslateTransform();
            aRectangle.RenderTransform = translateTransform3;

            // Create a DoubleAnimationUsingKeyFrames
            // to animate the transform.
            DoubleAnimationUsingKeyFrames transformAnimation =
                new DoubleAnimationUsingKeyFrames();
            transformAnimation.Duration = TimeSpan.FromSeconds(10);

            /*
               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).
             */

            // Animate to 100.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(100, KeyTime.Uniform));

            // Animate to 300.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(300, KeyTime.Uniform));

            // Animate to 500.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(500, KeyTime.Uniform));

            // Start the animation when the rectangle is loaded.
            aRectangle.Loaded += delegate(object sender, RoutedEventArgs e)
            {
                translateTransform3.BeginAnimation(TranslateTransform.XProperty, transformAnimation);
            };

<!-- This rectangle is animated with KeyTimes using Uniform values. 
     Goes to 100 in the first 3.3 seconds, 100 to
     300 in the next 3.3 seconds, 300 to 500 in the last 3.3 seconds. -->
<Rectangle Fill="Red" Stroke="Black" StrokeThickness="5"
  Width="50" Height="50">
  <Rectangle.RenderTransform>
    <TranslateTransform x:Name="TranslateTransform3" />
  </Rectangle.RenderTransform>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimationUsingKeyFrames 
            Storyboard.TargetName="TranslateTransform3" 
            Storyboard.TargetProperty="X"
            Duration="0:0:10">

            <!--   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="300" KeyTime="Uniform" />
            <LinearDoubleKeyFrame Value="500" KeyTime="Uniform" />
          </DoubleAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers>
</Rectangle>

下图显示达到每个关键帧的值的时间。

在 3.3、6.6 和 9.9 秒时达到的关键值

最后一个示例使用 Paced 关键时间值。

'            
'               This rectangle is animated with KeyTimes using Paced Values. 
'               The rectangle moves between key frames at uniform rate except for first key frame
'               because using a Paced value on the first KeyFrame in a collection of frames gives a time of zero.
'            

            ' Create the a rectangle.
            Dim aRectangle As New Rectangle()
            aRectangle.Fill = Brushes.Orange
            aRectangle.Stroke = Brushes.Black
            aRectangle.StrokeThickness = 5
            aRectangle.Width = 50
            aRectangle.Height = 50

            ' Create a transform to move the rectangle
            ' across the screen.
            Dim translateTransform4 As New TranslateTransform()
            aRectangle.RenderTransform = translateTransform4

            ' Create a DoubleAnimationUsingKeyFrames
            ' to animate the transform.
            Dim transformAnimation As New DoubleAnimationUsingKeyFrames()
            transformAnimation.Duration = TimeSpan.FromSeconds(10)

'            
'               Use Paced values 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.
'             

            ' Animate to 100.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(100, KeyTime.Paced))

            ' Animate to 300.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(300, KeyTime.Paced))

            ' Animate to 500.
            transformAnimation.KeyFrames.Add(New LinearDoubleKeyFrame(500, KeyTime.Paced))

            ' Start the animation when the rectangle is loaded.
            AddHandler aRectangle.Loaded, Sub(sender As Object, e As RoutedEventArgs) translateTransform4.BeginAnimation(TranslateTransform.XProperty, transformAnimation)

            /*
               This rectangle is animated with KeyTimes using Paced Values. 
               The rectangle moves between key frames at uniform rate except for first key frame
               because using a Paced value on the first KeyFrame in a collection of frames gives a time of zero.
            */

            // Create the a rectangle.
            Rectangle aRectangle = new Rectangle();
            aRectangle.Fill = Brushes.Orange;
            aRectangle.Stroke = Brushes.Black;
            aRectangle.StrokeThickness = 5;
            aRectangle.Width = 50;
            aRectangle.Height = 50;

            // Create a transform to move the rectangle
            // across the screen.
            TranslateTransform translateTransform4 =
                new TranslateTransform();
            aRectangle.RenderTransform = translateTransform4;

            // Create a DoubleAnimationUsingKeyFrames
            // to animate the transform.
            DoubleAnimationUsingKeyFrames transformAnimation =
                new DoubleAnimationUsingKeyFrames();
            transformAnimation.Duration = TimeSpan.FromSeconds(10);

            /*
               Use Paced values 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.
             */

            // Animate to 100.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(100, KeyTime.Paced));

            // Animate to 300.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(300, KeyTime.Paced));

            // Animate to 500.
            transformAnimation.KeyFrames.Add(
                new LinearDoubleKeyFrame(500, KeyTime.Paced));

            // Start the animation when the rectangle is loaded.
            aRectangle.Loaded += delegate(object sender, RoutedEventArgs e)
            {
                translateTransform4.BeginAnimation(TranslateTransform.XProperty, transformAnimation);
            };

<!-- This rectangle is animated with KeyTimes using Paced Values. 
     The rectangle moves between key frames at uniform rate except for first key frame
     because using a Paced value on the first KeyFrame in a collection of frames gives a time of zero. -->
<Rectangle Fill="Orange" Stroke="Black" StrokeThickness="5"
  Width="50" Height="50">
  <Rectangle.RenderTransform>
    <TranslateTransform x:Name="TranslateTransform4" />
  </Rectangle.RenderTransform>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimationUsingKeyFrames 
            Storyboard.TargetName="TranslateTransform4" 
            Storyboard.TargetProperty="X"
            Duration="0:0:10">

            <!-- Use Paced values 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="300" KeyTime="Paced" />
            <LinearDoubleKeyFrame Value="500" KeyTime="Paced" />
          </DoubleAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers>
</Rectangle>

下图显示达到每个关键帧的值的时间。

在 0、5 和 10 秒时达到的关键值

为了简单起见,此示例的代码版本使用本地动画(而不是演示图板),原因是只会将单一动画应用于单一属性,但您可以修改示例以改用演示图板。 有关演示如何在代码中声明演示图板的示例,请参见如何:使用演示图板对属性进行动画处理

有关完整示例,请参见 KeyFrame Animation Sample(KeyFrame 动画示例)。 有关关键帧动画的更多信息,请参见关键帧动画概述

请参见

概念

关键帧动画概述

动画概述

其他资源

动画和计时帮助主题