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

74

Существует еще один тип ключевых кадров: сплайновый ключевой кадр. Каждый класс, поддерживающий линейные ключевые кадры, поддерживает также и сплайновые ключевые кадры, и их имена формируются по шаблону SplineТипДанныхKeyFrame.

Подобно линейным ключевым кадрам, сплайновые ключевые кадры применяют интерполяцию для гладкого перемещения от одного ключевого значения к другому. Отличие состоит в том, что каждый сплайновый ключевой кадр оснащен свойством KeySpline. Используя это свойство, вы определяете кубическую кривую Безье, которая формирует путь интерполяции. Хотя здесь довольно трудно получить нужный эффект (по крайней мере, без инструментов графического дизайна, которые могут в этом помочь), все же эта техника предоставляет возможность создавать более плавное ускорение и замедление, а также другие естественные движения.

Кривая Безье определяется начальной точкой, конечной точкой и двумя опорными точками. В случае ключевого сплайна стартовая точка всегда находится в начале координат (0,0), а конечная точка — в (1,1). Вы просто задаете две опорных точки. Создаваемая кривая описывает отношение между временем (осью X) и анимируемым значением (ось Y).

Рассмотрим пример, демонстрирующий анимацию ключевого сплайна, сравнив движение двух эллипсов по поверхности Canvas. Первый эллипс использует DoubleAnimation для медленного равномерного перемещения по окну. Второй эллипс применяет DoubleAnimationUsingKeyFrames с двумя объектами SplineDoubleKeyFrame. Оба они достигают конечной точки одновременно (через 10 секунд), но второй ускоряется и замедляется на протяжении своего пути, обгоняя и отставая от первого эллипса:

<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
      <EventTrigger.Actions>
        <BeginStoryboard>
          <Storyboard>
            <DoubleAnimationUsingKeyFrames
             Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Canvas.Left)" >
              <SplineDoubleKeyFrame KeyTime="0:0:5" Value="250" KeySpline="0.25,0 0.5,0.7"></SplineDoubleKeyFrame>
              <SplineDoubleKeyFrame KeyTime="0:0:10" Value="500" KeySpline="0.25,0.8 0.2,0.4"></SplineDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimation
            Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Canvas.Left)"
            To="500" Duration="0:0:10">              
            </DoubleAnimation>
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger.Actions>
    </EventTrigger>
  </Window.Triggers>
  <Canvas Margin="10">
    <Ellipse Name="ellipse1" Canvas.Left="0" Fill="Red" Width="10" Height="10"></Ellipse>
    
    <Path Stroke="Blue" StrokeThickness="1" StrokeDashArray="2 1" Canvas.Top="25">
      <Path.Data>
        <PathGeometry>
          <PathFigure>
            <BezierSegment Point1="25,0" Point2="50,70" Point3="100,100" />
          </PathFigure>
        </PathGeometry>
      </Path.Data>
      <Path.RenderTransform>
        <ScaleTransform ScaleX="2.5"></ScaleTransform>
      </Path.RenderTransform>
    </Path>
    <Path Stroke="Blue" StrokeThickness="1" StrokeDashArray="2 1" Canvas.Left="250" Canvas.Top="25">
      <Path.Data>
        <PathGeometry>
          <PathFigure>            
            <BezierSegment Point1="25,80" Point2="20,40" Point3="100,100" />
          </PathFigure>
        </PathGeometry>
      </Path.Data>
      <Path.RenderTransform>
        <ScaleTransform ScaleX="2.5"></ScaleTransform>
      </Path.RenderTransform>
    </Path>
    
    <Ellipse Name="ellipse2" Canvas.Top="150" Canvas.Left="0" Fill="Red" Width="10" Height="10"></Ellipse>
  </Canvas>
</Window>
Сплайновая анимация

Наибольшее ускорение достигается вскоре после пятисекундной отметки, когда вступает в действие второй SplineDoubleKeyFrame. Его первая опорная точка соответствует относительно большому значению по оси Y, представляющему ход анимации (0.8), с относительно малым значением по оси X, представляющей время. В результате эллипс ускоряется на протяжении малого расстояния, прежде чем снова замедлиться.

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

Пройди тесты
Лучший чат для C# программистов