Общие сведения об анимации по ключевым кадрам

В этом разделе рассказывается об анимации по ключевым кадрам. Методика анимации по ключевым кадрам позволяет использовать более двух целевых значений и контролировать применяемый метод интерполяции.

Необходимые компоненты

Для понимания предлагаемого материала необходимо знакомство с принципами анимации Windows Presentation Foundation (WPF) и понятием временной шкалы. Общие сведения об анимации см. в разделе Общие сведения об анимации. Также полезно иметь знания по анимации From/To/By. Дополнительные сведения см. в разделе "Общие сведения об анимации From/To/By".

Что такое анимации по ключевым кадрам?

Так же как при анимации From/To/By при анимации по ключевым кадрам выполняется анимация значения целевого свойства. Создаются переходы между целевыми значениями на интервале Duration. Но в отличие от анимации From/To/By, при которой создается переход между двумя значениями, при анимации по ключевым кадрам можно создавать переходы между любым числом целевых значений за один раз. В анимации по ключевым кадрам не используются свойства From, To и By для задания целевых значений. Целевые значения для анимации по ключевым кадрам описываются с помощью объектов ключевых кадров (отсюда термин — "анимация по ключевым кадрам"). Для указания целевых значений анимации создайте объекты ключевых кадров и добавьте их в коллекцию ключевых кадров анимации KeyFrames. При выполнении анимации создаются переходы между заданными кадрами.

Кроме того, что при анимации по ключевым кадрам поддерживается обработка нескольких целевых значений, некоторые методы анимации по ключевым кадрам поддерживают использование нескольких методов интерполяции. Метод интерполяции анимации определяет, как выполняется переход от одного значения к другому. Существует три типа интерполяции: дискретная, линейная и интерполяция сплайнами.

Чтобы выполнить анимацию по ключевым кадрам, сделайте следующее.

  • Объявите анимацию и задайте ее продолжительность Duration так же как при анимации From/To/By.

  • Для каждого целевого значения создайте ключевой кадр соответствующего типа, задайте его значение, задайте параметр KeyTime и добавьте в коллекцию KeyFrames анимации.

  • Свяжите анимацию со свойством так же как при анимации From/To/By. Дополнительные сведения о применении анимации к свойству с помощью раскадровки см. в разделе Общие сведения о раскадровке.

В следующем примере используется метод DoubleAnimationUsingKeyFrames для анимации элемента Rectangle в четырех разных местах.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="Microsoft.Samples.KeyFrameAnimations.KeyFramesIntroduction"
  WindowTitle="KeyFrame Animations">

  <Border Width="400" BorderBrush="Black">  
    
    <Rectangle Fill="Blue" 
      Width="50" Height="50"
      HorizontalAlignment="Left">
      <Rectangle.RenderTransform>
        <TranslateTransform 
          x:Name="MyAnimatedTranslateTransform" 
          X="0" Y="0" />
      </Rectangle.RenderTransform>
      <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Rectangle.MouseLeftButtonDown">
          <BeginStoryboard>
            <Storyboard>
            
              <!-- Animate the TranslateTransform's X property
                   from 0 to 350, then 50,
                   then 200 over 10 seconds. -->

              <DoubleAnimationUsingKeyFrames
                Storyboard.TargetName="MyAnimatedTranslateTransform"
                Storyboard.TargetProperty="X"
                Duration="0:0:10">
                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0" />
                <LinearDoubleKeyFrame Value="350" KeyTime="0:0:2" />
                <LinearDoubleKeyFrame Value="50" KeyTime="0:0:7" />
                <LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" />                          
              </DoubleAnimationUsingKeyFrames>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Rectangle.Triggers> 
    </Rectangle>
  </Border> 
</Page>

Так же как анимация From/To/By, анимация по ключевым кадрам может применяться к свойству с помощью раскадровки Storyboard в разметке и коде или с помощью метода BeginAnimation в коде. Анимацию по ключевым кадрам можно также использовать для создания объекта AnimationClock и применения его к одному или нескольким свойствам. Дополнительные сведения о различных способах применения анимации см. в разделе Общие сведения о методах анимации свойств.

Типы анимации по ключевым кадрам

Так как при анимации создаются значения свойств, существуют различные типы анимаций для различных типов свойств. Для анимации свойства, которое принимает Double (например, свойства Width элемента), используйте анимацию, создающую значения Double. Для анимации свойства, принимающего Point, используйте анимацию, создающую значения Point и так далее.

Классы анимации по ключевым кадрам принадлежат пространству имен System.Windows.Media.Animation и удовлетворяют требованиям следующего соглашения об именовании:

<Тип> AnimationUsingKeyFrames

Где <Type> — тип значения, которое анимируется классом.

WPF предоставляет указанные ниже классы анимации по ключевым кадрам.

Тип свойства Соответствующий класс анимации From/To/By Поддерживаемые методы интерполяции
Boolean BooleanAnimationUsingKeyFrames Discrete
Byte ByteAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Color ColorAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Decimal DecimalAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Double DoubleAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Int16 Int16AnimationUsingKeyFrames Дискретная, линейная, сплайнами
Int32 Int32AnimationUsingKeyFrames Дискретная, линейная, сплайнами
Int64 Int64AnimationUsingKeyFrames Дискретная, линейная, сплайнами
Matrix MatrixAnimationUsingKeyFrames Discrete
Object ObjectAnimationUsingKeyFrames Discrete
Point PointAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Quaternion QuaternionAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Rect RectAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Rotation3D Rotation3DAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Single SingleAnimationUsingKeyFrames Дискретная, линейная, сплайнами
String StringAnimationUsingKeyFrames Discrete
Size SizeAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Thickness ThicknessAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Vector3D Vector3DAnimationUsingKeyFrames Дискретная, линейная, сплайнами
Vector VectorAnimationUsingKeyFrames Дискретная, линейная, сплайнами

Целевые значения (ключевые кадры) и временная шкала

Для анимации различных типов свойств существуют различные типы анимации по ключевым кадрам и, соответственно, различные типы объектов ключевых кадров — по одному для каждого типа анимированного значения и поддерживаемого метода интерполяции. Типы ключевых кадров удовлетворяют требованиям следующего соглашения об именах.

<Тип> ИнтерполяцииMethod>< KeyFrame

Где <InterpolationMethod> — метод интерполяции, используемый при анимации по ключевым кадрам, а <Type> — тип значения, которое анимируется классом. Метод анимации по ключевым кадрам, поддерживающий все три метода интерполяции, будет включать в себя три типа ключевых кадров, которые можно использовать. Например, можно использовать три типа ключевых кадров с DoubleAnimationUsingKeyFrames: DiscreteDoubleKeyFrame, LinearDoubleKeyFrame и SplineDoubleKeyFrame. (Методы интерполяции подробно описаны в следующем разделе.)

Основной целью ключевого кадра является указание свойств KeyTime и Value. Все типы ключевых кадров предоставляют эти два свойства.

  • Свойство Value задает целевое значение для этого ключевого кадра.

  • Свойство KeyTime указывает, когда (в пределах Value анимации) достигается Duration ключевого кадра.

При выполнении анимации по ключевым кадрам происходит итерация по ключевым кадрам в порядке, определяемом их свойствами KeyTime.

  • Если в момент 0 нет ключевого кадра, анимация создает переход от текущего значения целевого свойства к значению Value первого ключевого кадра. В противном случае выходным значением анимации становится значение первого ключевого кадра.

  • Анимация создает переход от значения Value первого ключевого кадра к значению второго с помощью метода интерполяции, определяемого вторым ключевым кадром. Переход начинается в момент KeyTime первого ключевого кадра и заканчивается при достижении момента KeyTime второго ключевого кадра.

  • Анимация продолжается, создавая переходы от каждого предыдущего ключевого кадра к последующему.

  • Наконец, анимация переходит к значению ключевого кадра с наиболее поздним моментом времени, находящимся в пределах продолжительности Duration анимации.

Если продолжительность анимации Duration имеет значение Automatic или ее продолжительность Duration равна времени последнего ключевого кадра, анимация завершается. В противном случае, если продолжительность Duration анимации больше, чем время последнего ключевого кадра, анимация удерживает значение ключевого кадра до окончания периода Duration. Как и в других анимациях при анимации по ключевым кадрам используется свойство FillBehavior, чтобы определить, следует ли удерживать конечное значение при достижении окончания активного периода. Дополнительные сведения см. в разделе Общие сведения о характере поведения во времени.

В следующем примере используется объект DoubleAnimationUsingKeyFrames, определенный в предыдущем примере, чтобы продемонстрировать, как работают свойства Value и KeyTime.

  • Первый кадр немедленно устанавливает выходное значение анимации равное 0.

  • Второй ключевой кадр выполняет анимацию от 0 до 350. Она запускается после окончания первого ключевого кадра (в момент времени 0 секунд), выполняется в течение 2 секунд и заканчивается в момент времени = 0:0:2.

  • Третий ключевой кадр выполняет анимацию от 350 до 50. Она запускается после окончания второго ключевого кадра (в момент времени 2 секунды), выполняется в течение 5 секунд и заканчивается в момент времени = 0:0:7.

  • Четвертый ключевой кадр выполняет анимацию от 50 до 200. Она запускается после окончания третьего ключевого кадра (в момент времени 7 секунд), выполняется в течение 1 секунды и заканчивается в момент времени = 0:0:8.

  • Так как была задана продолжительность анимации Duration, равная 10 секундам, анимация удерживает конечное значение еще в течение двух секунд до окончания в момент времени, равный 0:0:10.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="Microsoft.Samples.KeyFrameAnimations.KeyFramesIntroduction"
  WindowTitle="KeyFrame Animations">

  <Border Width="400" BorderBrush="Black">  
    
    <Rectangle Fill="Blue" 
      Width="50" Height="50"
      HorizontalAlignment="Left">
      <Rectangle.RenderTransform>
        <TranslateTransform 
          x:Name="MyAnimatedTranslateTransform" 
          X="0" Y="0" />
      </Rectangle.RenderTransform>
      <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Rectangle.MouseLeftButtonDown">
          <BeginStoryboard>
            <Storyboard>
            
              <!-- Animate the TranslateTransform's X property
                   from 0 to 350, then 50,
                   then 200 over 10 seconds. -->

              <DoubleAnimationUsingKeyFrames
                Storyboard.TargetName="MyAnimatedTranslateTransform"
                Storyboard.TargetProperty="X"
                Duration="0:0:10">
                <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0" />
                <LinearDoubleKeyFrame Value="350" KeyTime="0:0:2" />
                <LinearDoubleKeyFrame Value="50" KeyTime="0:0:7" />
                <LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" />                          
              </DoubleAnimationUsingKeyFrames>
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Rectangle.Triggers> 
    </Rectangle>
  </Border> 
</Page>

Методы интерполяции

В предыдущих разделах упоминалось, что некоторые методы анимации по ключевым кадрам поддерживают несколько методов интерполяции. Метод интерполяции определяет, как должен выполняться переход от одного значения к другому во время анимации. Выбрав тип ключевого кадра, используемого при анимации, можно определить метод интерполяции для этого сегмента ключевого кадра. Существуют три метода интерполяции: линейная интерполяция, дискретная и интерполяция сплайнами.

Линейная интерполяция

При линейной интерполяции переход выполняется с постоянной скоростью на протяжении сегмента. Например, если в сегменте ключевого кадра происходит переход от 0 до 10 в течение 5 секунд, выходные данные анимации будут принимать следующие значения в указанные моменты времени.

Время Выходное значение
0 0
1 2
2 4
3 6
4 8
4.25 8.5
4,5 9
5 10

Дискретная интерполяция

При дискретной интерполяции функция анимации выполняет переходы от одного значения к другому без интерполяции. Если в сегменте ключевого кадра происходит переход от 0 до 10 в течение 5 секунд, выходные данные анимации будут принимать следующие значения в указанные моменты времени.

Время Выходное значение
0 0
1 0
2 0
3 0
4 0
4.25 0
4,5 0
5 10

Обратите внимание на то, что выходное значение не изменяется до окончания длительности сегмента.

Интерполяция сплайнами более сложная. Она описана в следующем разделе.

Интерполяция сплайнами

Интерполяция сплайнами может использоваться для достижения более реалистичных временных эффектов. Так как анимация часто используется для имитации эффектов, возникающих в реальном мире, разработчикам могут потребоваться полный контроль над ускорением и замедлением объектов и точная манипуляция временными сегментами. Ключевые кадры-сплайны позволяют выполнять анимацию с интерполяцией сплайнами. С другими ключевыми кадрами задаются свойства Value и KeyTime. С ключевым кадром-сплайном также задается свойство KeySpline. В следующем примере показан отдельный ключевой кадр-сплайн для DoubleAnimationUsingKeyFrames. Обратите внимание на свойство KeySpline. Это то, что отличает ключевой кадр-сплайн от других типов ключевых кадров.

<SplineDoubleKeyFrame Value="500" KeyTime="0:0:7" KeySpline="0.0,1.0 1.0,0.0" />

Кривая Безье третьего порядка определяется начальной точкой, конечной точкой и двумя контрольными точками. Свойство KeySpline ключевого кадра-сплайна определяет две контрольные точки кривой Безье, проведенной от точки (0,0) до точки (1,1). Первая контрольная точка управляет коэффициентом кривизны первой половины кривой Безье, а вторая контрольная точка — коэффициентом кривизны второй половины сегмента. Полученная кривая описывает скорость изменения для этого ключевого кадра-сплайна. Чем круче кривая, тем быстрее ключевой кадр изменяет свои значения. Когда кривая становится более пологой, ключевой кадр медленнее изменяет свои значения.

Можно использовать KeySpline для имитации физических траекторий, таких как падающая вода или прыгающий шарик, или применить другие эффекты анимации типа "замедлить в начале" и "замедлить в конце". Для реализации эффектов взаимодействия с пользователем, таких как затухание фона или отпускание кнопки элемента управления, можно применять интерполяцию сплайнами, чтобы ускорить или замедлить скорость изменения при анимации конкретных движений.

В следующем примере определяется KeySpline с точкой (0,1, 1,0), который создает приведенную ниже кривую Безье.

Кривая Безье
Ключевой сплайн с контрольными точками (0,0, 1,0) и (1,0, 0,0)

<SplineDoubleKeyFrame Value="500" KeyTime="0:0:7" KeySpline="0.0,1.0 1.0,0.0" />

Этот ключевой кадр вначале выполняет быстрое движение, затем замедляется и снова ускоряется перед завершением.

В следующем примере определяется KeySpline с точками (0,5, 0,25) (0,75, 1,0), который создает приведенную ниже кривую Безье.

Второй пример кривой Bezier.
Ключевой сплайн с контрольными точками (0,25, 0,5) и (0,75, 1,0)

<SplineDoubleKeyFrame Value="350" KeyTime="0:0:15"  KeySpline="0.25,0.5 0.75,1" />

Так как кривизна кривой Безье изменяется незначительно, этот ключевой кадр выполняет движение почти с постоянной скоростью, несколько замедляясь перед завершением.

В следующем примере используется DoubleAnimationUsingKeyFrames для анимации положения прямоугольника. Так как DoubleAnimationUsingKeyFrames использует объекты SplineDoubleKeyFrame, для перехода от одного значения ключевого кадра к другому используется интерполяция сплайнами.

<!-- This rectangle is animated using a key frame animation
     with splined interpolation. -->
<Rectangle 
  Width="50"
  Height="50"
  Fill="Purple">  
  <Rectangle.RenderTransform>
    <TranslateTransform 
      x:Name="SplineAnimatedTranslateTransform" 
      X="0" Y="0" />
  </Rectangle.RenderTransform>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard>

          <!-- Animate the TranslateTransform's X property
               from its base value (0) to 500, then 200,
               then 350 over 15 seconds. -->
          <DoubleAnimationUsingKeyFrames
            Storyboard.TargetName="SplineAnimatedTranslateTransform"
            Storyboard.TargetProperty="X"
            Duration="0:0:15"
            RepeatBehavior="Forever">                
            <SplineDoubleKeyFrame Value="500" KeyTime="0:0:7" KeySpline="0.0,1.0 1.0,0.0" />
            
            <SplineDoubleKeyFrame Value="200" KeyTime="0:0:10"  KeySpline="0.0,0.0 1.0,0.0" />

            <SplineDoubleKeyFrame Value="350" KeyTime="0:0:15"  KeySpline="0.25,0.5 0.75,1" />
          </DoubleAnimationUsingKeyFrames>           
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers> 
</Rectangle>

Интерполяцию сплайнами не так просто понять. Попробуйте поэкспериментировать с различными параметрами. Пример анимации по ключевым сплайнам позволяет, изменяя значения ключевого сплайна, просмотреть результат на анимации.

Комбинирование методов интерполяции

Можно использовать ключевые кадры с различными типами интерполяции в одной операции анимации. Если два ключевых кадра анимации с различными методами интерполяции следуют друг за другом, то для создания перехода от первого значения ко второму используется метод интерполяции второго ключевого кадра.

В следующем примере создается DoubleAnimationUsingKeyFrames, который использует линейную интерполяцию, интерполяцию сплайнами и дискретную интерполяцию.

<!-- This rectangle is animated using a key frame animation
     with a combination of interpolation methods. -->
<Rectangle 
  Width="50"
  Height="50"
  Fill="Orange">  
  <Rectangle.RenderTransform>
    <TranslateTransform 
      x:Name="ComboAnimatedTranslateTransform" 
      X="0" Y="0" />
  </Rectangle.RenderTransform>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard>

          <!-- Animate the TranslateTransform's X property
               from its base value (0) to 500, then 200,
               then 350 over 15 seconds. -->
          <DoubleAnimationUsingKeyFrames
            Storyboard.TargetName="ComboAnimatedTranslateTransform"
            Storyboard.TargetProperty="X"
            Duration="0:0:15"
            RepeatBehavior="Forever">
            <DiscreteDoubleKeyFrame Value="500" KeyTime="0:0:7" />
            <LinearDoubleKeyFrame Value="200" KeyTime="0:0:10" />
            <SplineDoubleKeyFrame Value="350" KeyTime="0:0:15"  
              KeySpline="0.25,0.5 0.75,1" />                      
          </DoubleAnimationUsingKeyFrames>           
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Rectangle.Triggers> 
</Rectangle>

Дополнительные сведения о длительности и временной шкале

Как и другие виды анимации анимация по ключевым кадрам имеет свойство Duration. Помимо задания длительности Duration анимации, необходимо указать, какая часть длительности предоставляется для каждого ключевого кадра. Это можно сделать, определив временную шкалу KeyTime для каждого из ключевых кадров анимации. Временная шкала KeyTime каждого ключевого кадра определяет, когда заканчивается этот ключевой кадр.

Свойство KeyTime не определяет продолжительность выполнения ключевого кадра. Продолжительность выполнения ключевого кадра определяется моментом окончания ключевого кадра, моментом окончания предыдущего ключевого кадра и длительностью анимации. Время может быть указано в виде значения времени, в процентах, либо в виде специальных значений Uniform или Paced.

Ниже описаны различные способы определения времени ключевого кадра.

Значения временного диапазона

Можно использовать значения TimeSpan для указания KeyTime. Значение должно быть больше или равно 0 и меньше или равно длительности анимации. В следующем примере показана анимация длительностью 10 секунд с четырьмя ключевыми кадрами, время которых указывается в виде значений времени.

  • Первый ключевой кадр выполняет анимацию от базового значения до 100 в течение первых 3 секунд и заканчивает в момент времени = 0:0:03.

  • Второй ключевой кадр выполняет анимацию от 100 до 200. Она запускается после окончания первого ключевого кадра (в момент времени 3 секунды), выполняется в течение 5 секунд и заканчивается в момент времени = 0:0:8.

  • Третий ключевой кадр выполняет анимацию от 200 до 500. Она запускается после окончания второго ключевого кадра (в момент времени 8 секунд), выполняется в течение 1 секунды и заканчивается в момент времени = 0:0:9.

  • Четвертый ключевой кадр выполняет анимацию от 500 до 600. Она запускается после окончания третьего ключевого кадра (в момент времени 9 секунд), выполняется в течение 1 секунды и заканчивается в момент времени = 0:0:10.

<!-- This rectangle is animated with KeyTimes using TimeSpan values. 
     Goes to 100 in the first 3 seconds, 100 to 200 in 
     the next 5 seconds, 300 to 500 in the next second,
     and 500 to 600 in the final second. -->
<Rectangle Width="50" Height="50" Fill="Blue">
  <Rectangle.RenderTransform>
    <TranslateTransform x:Name="TranslateTransform01" X="10" Y="30" />
  </Rectangle.RenderTransform>
  <Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.Loaded">
      <BeginStoryboard>
        <Storyboard>
          <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 секунд с четырьмя ключевыми кадрами, время которых указывается в виде значений в процентах.

  • Первый ключевой кадр выполняет анимацию от базового значения до 100 в течение первых 3 секунд и заканчивает в момент времени = 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).

<!-- Identical animation behavior to the previous rectangle 
     but using percentage values for KeyTimes rather then TimeSpan. -->
<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 указывает, что доступное время делится поровну на все ключевые кадры для определения времени окончания каждого из них. В следующем примере показана анимация длительностью 10 секунд с четырьмя ключевыми кадрами, время которых указывается в виде значений Uniform.

  • Первый ключевой кадр выполняет анимацию от базового значения до 100 в течение первых 2,5 секунды и заканчивает в момент времени = 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.

<!-- This rectangle is animated with KeyTimes using Uniform values.  -->
<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 указывает, что доступное время делится в соответствии с длиной каждого ключевого кадра для определения длительности кадра. Это приводит к тому, что скорость или темп анимации остается постоянной. В следующем примере показана анимация длительностью 10 секунд с тремя ключевыми кадрами, время которых указывается в виде значений Paced.

<!-- Using Paced Values. 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 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 with 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>

Обратите внимание, что, если используется параметр времени последнего ключевого кадра Paced или Uniform, его расчетное время будет задано в размере 100 %. Если первый ключевой кадр в многокадровой анимации является пошаговым, его расчетное время будет задано в размере 0. (Если коллекция ключевых кадров содержит только один кадр и этот кадр пошаговый, его расчетное время будет задано в размере 100 %.)

Разные ключевые кадры в однокадровой анимации могут использовать разные типы времени кадра.

Объединение времени ключевых кадров, неупорядоченные ключевые кадры

В одной анимации можно использовать ключевые кадры с разными типами значения KeyTime. И хотя рекомендуется добавлять ключевые кадры в том порядке, в каком они должны выполняться, в этом нет необходимости. Система выполнения анимации и расчета времени способна обрабатывать неупорядоченные ключевые кадры. Ключевые кадры с недопустимым временем игнорируются.

Ниже приводятся процедуры, с помощью которых рассчитывается время кадра при анимации по ключевым кадрам.

  1. Разрешение TimeSpan KeyTime значений.

  2. Определение общего времени интерполяции анимации (общего времени, необходимого для выполнения прямой итерации при анимации по ключевым кадрам).

    1. Если продолжительность Duration анимации имеет значение, отличное от Automatic или Forever, общее время интерполяции равно значению свойства Duration анимации.

    2. В противном случае общее время интерполяции — это наибольшее TimeSpan KeyTime значение, указанное среди ключевых кадров, если таковые существуют.

    3. В остальных случаях общее время интерполяции равно 1 секунде.

  3. Используйте общее значение времени интерполяции для разрешения Percent KeyTime значений.

  4. Расчет времени последнего кадра в случае, если оно не было рассчитано на предыдущих шагах. Если для параметра KeyTime последнего ключевого кадра задано значение Uniform или Paced, его расчетное время будет равно общему времени интерполяции.

    Если для параметра KeyTime первого ключевого кадра задано значение Paced и в этой анимации больше одного ключевого кадра, значение KeyTime будет разрешено как нуль. Если есть только один ключевой кадр и его значение KeyTime равно Paced, расчетное значение будет равно общему времени интерполяции, как было описано в предыдущем шаге.

  5. Устраните оставшиеся Uniform KeyTime значения: они получают равный объем доступного времени. Во время этого процесса неразрешенные Paced KeyTime значения временно обрабатываются как Uniform KeyTime значения и получают временно разрешенное время.

  6. Расчет значений KeyTime ключевых кадров с неуказанным временем кадра с использованием соседних объявленных ключевых кадров, имеющих рассчитанные значения KeyTime.

  7. Устраните оставшиеся Paced KeyTime значения. PacedKeyTime KeyTime используйте значения соседних ключевых кадров, чтобы определить их разрешенное время. Цель — убедиться, что скорость анимации является постоянной в течение расчетного времени этого ключевого кадра.

  8. Сортировка ключевых кадров в порядке расчетного времени (первичный ключ) и в порядке объявления (вторичный ключ), т. е. использование строгой сортировки по расчетным значениям KeyTime ключевых кадров.

См. также