Compartilhar via


Visão geral das animações de quadro-chave

Este tópico apresenta as animações de quadro-chave. As animações de quadro-chave permitem realizar animações usando mais de dois valores de destino e controlam o método de interpolação de uma animação.

Pré-requisitos

Para entender essa visão geral, você deve estar familiarizado com as animações e linhas do tempo do Windows Presentation Foundation (WPF). Para obter uma introdução às animações, consulte a Visão geral da animação. Ela também ajuda a se familiarizar com as animações De/Para/Por. Para obter mais informações, consulte a Visão geral das animações De/Para/Por.

O que é uma animação de quadro-chave?

Assim como uma animação De/Para/Por, uma animação de quadro-chave anima o valor de uma propriedade de destino. Ele cria uma transição entre seus valores de destino sobre seu Duration. No entanto, enquanto uma animação De/Para/Por cria uma transição entre dois valores, uma única animação de quadro-chave pode criar transições entre qualquer número de valores de destino. Ao contrário de uma animação De/Para/Por, uma animação de quadro-chave não tem nenhuma propriedade De, Para ou Por com a qual seus valores de destino são definidos. Os valores de destino de uma animação de quadro-chave são descritos com o uso de objetos de quadros-chave (daí o termo “animação de quadro-chave”). Para especificar os valores de destino da animação, crie objetos de quadro-chave e adicione-os à coleção da KeyFrames animação. Quando a animação é executada, ela faz a transição entre os quadros especificados.

Além de dar suporte a vários valores de destino, alguns métodos de quadro-chave até mesmo dão suporte a vários métodos de interpolação. O método de interpolação de uma animação define como ela faz a transição de um valor para o próximo. Há três tipos de interpolações: discreta, linear e spline.

Para realizar uma animação de quadro-chave, conclua as etapas a seguir.

  • Declare a animação e especifique seu Duration, assim como faria para uma animação de/para/por.

  • Para cada valor de destino, crie um quadro-chave do tipo apropriado, defina seu valor e KeyTime, e adicione-o à coleção da KeyFrames animação.

  • Associe a animação a uma propriedade, exatamente como você faria com uma animação De/Para/Por. Para obter mais informações sobre como aplicar uma animação a uma propriedade usando um storyboard, consulte Visão geral dos storyboards.

O exemplo a seguir usa a DoubleAnimationUsingKeyFrames para animar um Rectangle elemento em quatro locais diferentes.

<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>

Como uma animação From/To/By, uma animação de quadro-chave pode ser aplicada a uma propriedade usando uma Storyboard marcação in e code ou usando o BeginAnimation método in code. Você também pode usar uma animação de quadro-chave para criar uma AnimationClock e aplicá-la a uma ou mais propriedades. Para obter mais informações sobre os diferentes métodos para aplicação de animações, consulte a Visão geral das técnicas de animação de propriedades.

Tipos de animação de quadro-chave

Como as animações geram valores de propriedade, existem diferentes tipos de animação para diferentes tipos de propriedades. Para animar uma propriedade que usa um Double (como a propriedade de Width um elemento), use uma animação que produza Double valores. Para animar uma propriedade que usa um Point, use uma animação que produza Point valores e assim por diante.

As classes de animação de quadro-chave pertencem ao System.Windows.Media.Animation namespace e seguem a seguinte convenção de nomenclatura:

<Tipo>AnimationUsingKeyFrames

Onde <Type> é o tipo de valor que a classe anima.

O WPF fornece as seguintes classes de animação de quadro-chave.

Tipo de propriedade Classe de animação De/Para/Por correspondente Métodos de interpolação com suporte
Boolean BooleanAnimationUsingKeyFrames Discreto
Byte ByteAnimationUsingKeyFrames Discreto, linear, spline
Color ColorAnimationUsingKeyFrames Discreto, linear, spline
Decimal DecimalAnimationUsingKeyFrames Discreto, linear, spline
Double DoubleAnimationUsingKeyFrames Discreto, linear, spline
Int16 Int16AnimationUsingKeyFrames Discreto, linear, spline
Int32 Int32AnimationUsingKeyFrames Discreto, linear, spline
Int64 Int64AnimationUsingKeyFrames Discreto, linear, spline
Matrix MatrixAnimationUsingKeyFrames Discreto
Object ObjectAnimationUsingKeyFrames Discreto
Point PointAnimationUsingKeyFrames Discreto, linear, spline
Quaternion QuaternionAnimationUsingKeyFrames Discreto, linear, spline
Rect RectAnimationUsingKeyFrames Discreto, linear, spline
Rotation3D Rotation3DAnimationUsingKeyFrames Discreto, linear, spline
Single SingleAnimationUsingKeyFrames Discreto, linear, spline
String StringAnimationUsingKeyFrames Discreto
Size SizeAnimationUsingKeyFrames Discreto, linear, spline
Thickness ThicknessAnimationUsingKeyFrames Discreto, linear, spline
Vector3D Vector3DAnimationUsingKeyFrames Discreto, linear, spline
Vector VectorAnimationUsingKeyFrames Discreto, linear, spline

Valores de destino (quadros-chave) e tempos-chave

Assim como há diferentes tipos de animações de quadro-chave para animar diferentes tipos de propriedades, também existem diferentes tipos de objetos de quadro-chave: um para cada tipo de valor animado e o método de interpolação com suporte. Os tipos de quadro-chave seguem esta convenção de nomenclatura:

> de método de interpolaçãoKeyFrame

Onde > é o método de interpolação que o quadro-chave usa e> é o tipo de valor que a classe anima. Uma animação de quadro-chave que dá suporte aos três métodos de interpolação terá três tipos de quadro-chave que podem ser usados. Por exemplo, você pode usar três tipos de quadros-chave com : DoubleAnimationUsingKeyFramesDiscreteDoubleKeyFrame, LinearDoubleKeyFramee SplineDoubleKeyFrame. (Os métodos de interpolação são descritos detalhadamente em uma seção posterior.)

O objetivo principal de um quadro-chave é especificar um KeyTime e um Value. Cada tipo de quadro-chave fornece essas duas propriedades.

  • A Value propriedade especifica o valor de destino para esse quadro-chave.

  • A KeyTime propriedade especifica quando (dentro da animação) Durationum quadro-chave Value é atingido.

Quando uma animação de quadro-chave é iniciada, ela itera por meio de seus quadros-chave na ordem definida por suas KeyTime propriedades.

  • Se não houver nenhum quadro-chave no tempo 0, a animação criará uma transição entre o valor atual da propriedade de destino e o Value do primeiro quadro-chave; caso contrário, o valor de saída da animação se tornará o valor do primeiro quadro-chave.

  • A animação cria uma transição entre o primeiro e o segundo quadros-chave Value usando o método de interpolação especificado pelo segundo quadro-chave. A transição começa no primeiro quadro-chave KeyTime e termina quando o segundo quadro-chave KeyTime é alcançado.

  • A animação continua, criando transições entre cada próximo quadro-chave e seu quadro-chave anterior.

  • Por fim, a animação faz a transição para o valor do quadro-chave com o maior tempo de chave igual ou menor que o Duration.

Se a animação Duration for Automatic igual Duration à hora do último quadro-chave, a animação será encerrada. Caso contrário, se a animação Duration for maior que o tempo-chave do último quadro-chave, a animação manterá o valor do quadro-chave até atingir o final de seu Duration. Como todas as animações, uma animação de quadro-chave usa sua FillBehavior propriedade para determinar se ela mantém seu valor final quando atinge o final de seu período ativo. Para obter mais informações, consulte a Visão geral dos comportamentos de tempo.

O exemplo a seguir usa o DoubleAnimationUsingKeyFrames objeto definido no exemplo anterior para demonstrar como as Value propriedades e KeyTime funcionam.

  • O primeiro quadro-chave define imediatamente o valor de saída da animação como 0.

  • O segundo quadro-chave é animado de 0 a 350. Ele é iniciado após o término do primeiro quadro-chave (no tempo = 0 segundo) e é reproduzido por 2 segundos, sendo encerrado no tempo = 0:0:2.

  • O terceiro quadro-chave é animado de 350 a 50. Ele é iniciado após o término do segundo quadro-chave (no tempo = 2 segundos) e é reproduzido por 5 segundos, sendo encerrado no tempo = 0:0:7.

  • O quarto quadro-chave é animado de 50 a 200. Ele é iniciado após o término do terceiro quadro-chave (no tempo = 7 segundos) e é reproduzido por 1 segundo, sendo encerrado no tempo = 0:0:8.

  • Como a Duration propriedade da animação foi definida como 10 segundos, a animação mantém seu valor final por dois segundos antes de terminar no tempo = 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>

Métodos de interpolação

As seções anteriores mencionaram que algumas animações de quadro-chave dão suporte a vários métodos de interpolação. A interpolação de uma animação descreve como uma animação faz a transição entre valores ao longo de sua duração. Ao selecionar o tipo de quadro-chave usado na animação, você poderá definir o método de interpolação para esse segmento de quadro-chave. Há três tipos de métodos de interpolação diferentes: linear, discreto e spline.

Interpolação linear

Com a interpolação linear, a animação progride a uma taxa constante da duração do segmento. Por exemplo, se um segmento de quadro-chave fizer a transição de 0 a 10 em uma duração de 5 segundos, a animação gerará os seguintes valores nos tempos especificados:

Hora Valor de saída
0 0
1 2
2 4
3 6
4 8
4.25 8.5
4.5 9
5 10

Interpolação discreta

Com a interpolação discreta, a função de animação salta de um valor para o próximo sem interpolação. Se um segmento de quadro-chave fizer a transição de 0 a 10 em uma duração de 5 segundos, a animação gerará os seguintes valores nos tempos especificados:

Hora Valor de saída
0 0
1 0
2 0
3 0
4 0
4.25 0
4.5 0
5 10

Observe como a animação não altera seu valor de saída até exatamente o final da duração do segmento.

A interpolação spline é mais complexa. Ela é descrita na próxima seção.

Interpolação spline

A interpolação spline pode ser usada para obter efeitos de tempo mais realistas. Como as animações costumam ser usadas para imitar efeitos que ocorrem no mundo real, os desenvolvedores podem precisar de um controle refinado sobre a aceleração e desaceleração de objetos e uma manipulação minuciosa dos segmentos de tempo. Os quadros-chave spline permitem realizar animações com interpolação spline. Com outros quadros-chave, você especifica um Value e KeyTime. Com um quadro-chave de spline, você também especifica um KeySpline. O exemplo a seguir mostra um único quadro-chave de spline para um DoubleAnimationUsingKeyFrames. Observe a KeySpline propriedade; é isso que torna um quadro-chave spline diferente dos outros tipos de quadros-chave.

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

Uma curva de Bézier cúbica é definida por um ponto inicial, um ponto final e dois pontos de controle. A KeySpline propriedade de um quadro-chave de spline define os dois pontos de controle de uma curva de Bézier que se estende de (0,0) a (1,1). O primeiro ponto de controle controla o fator de curva da primeira metade da curva de Bézier e o segundo ponto de controle controla o fator de curva da segunda metade do segmento de Bézier. A curva resultante descreve a taxa de alteração desse quadro-chave spline. Quanto mais íngreme for a curva, mais rápido o quadro-chave mudará seus valores. Conforme a curva fica mais plana, o quadro-chave muda seus valores mais lentamente.

Você pode usar KeySpline para simular trajetórias físicas, como queda de água ou bolas quicando, ou aplicar outros efeitos de "facilitação" e "atenuação" a animações de movimento. Para efeitos de interação do usuário como esmaecimento da tela de fundo ou reassociação do botão de controle, você poderá aplicar a interpolação spline para acelerar ou diminuir a taxa de alteração de uma animação de uma maneira específica.

O exemplo a seguir especifica um KeySpline de 0,1 1,0, que cria a curva de Bézier a seguir.

Uma curva de Bézier
Um spline-chave com pontos de controle (0,0, 1,0) e (1,0, 0,0)

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

Esse quadro-chave é animado rapidamente quando é iniciado, desacelera e, em seguida, acelera novamente antes de ser encerrado.

O exemplo a seguir especifica um KeySpline de 0,5,0,25 0,75,1,0, que cria a seguinte curva de Bézier.

Um segundo exemplo de curva de Bézier.
Um spline-chave com pontos de controle (0,25, 0,5) e (0,75, 1,0)

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

Como a curvatura da curva de Bézier muda muito pouco, esse quadro-chave é animado a uma taxa quase constante; ele desacelera um pouco quase no final.

O exemplo a seguir usa a DoubleAnimationUsingKeyFrames para animar a posição do retângulo. Como os DoubleAnimationUsingKeyFrames objetos using SplineDoubleKeyFrame , a transição entre cada valor de quadro-chave usa interpolação spline.

<!-- 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>

A interpolação spline pode ser difícil de entender; pode ser útil testar diferentes configurações. A Amostra de animação de spline-chave permite alterar os valores do spline-chave e ver o resultado na animação.

Combinando métodos de interpolação

É possível usar quadros-chave com diferentes tipos de interpolação em uma única animação de quadro-chave. Quando duas animações de quadro-chave com diferentes interpolações ocorrem uma após a outra, o método de interpolação do segundo quadro-chave é usado para criar a transição do primeiro valor para o segundo.

No exemplo a seguir, é criado um que usa interpolação DoubleAnimationUsingKeyFrames linear, splined e discreta.

<!-- 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>

Mais informações sobre duração e tempos-chave

Como outras animações, as animações de quadro-chave têm uma Duration propriedade. Além de especificar o Duration, você precisa especificar qual parte dessa duração é dada a cada quadro-chave. Você faz isso descrevendo a para cada um KeyTime dos quadros-chave da animação. Cada quadro-chave KeyTime especifica quando esse quadro-chave termina.

A KeyTime propriedade não especifica por quanto tempo o tempo de chave é reproduzido. O tempo durante o qual um quadro-chave é reproduzido é determinado pelo tempo em que o quadro-chave é encerrado, pelo tempo em que o quadro-chave anterior foi encerrado e pela duração da animação. Os tempos-chave podem ser especificados como um valor de tempo, uma porcentagem ou como os valores Uniform especiais ou Paced.

A lista a seguir descreve as diferentes maneiras de especificar os tempos-chave.

Valores TimeSpan

Você pode usar TimeSpan valores para especificar um KeyTime. O valor deve ser maior ou igual a 0 e menor ou igual à duração da animação. O exemplo a seguir mostra uma animação com uma duração de 10 segundos e quatro quadros-chave cujos tempos-chave são especificados como valores temporais.

  • O primeiro quadro-chave é animado do valor base para 100 durante os primeiros 3 segundos, sendo encerrado no tempo = 0:0:03.

  • O segundo quadro-chave é animado de 100 a 200. Ele é iniciado após o término do primeiro quadro-chave (no tempo = 3 segundos) e é reproduzido por 5 segundos, sendo encerrado no tempo = 0:0:8.

  • O terceiro quadro-chave é animado de 200 a 500. Ele é iniciado após o término do segundo quadro-chave (no tempo = 8 segundos) e é reproduzido por 1 segundo, sendo encerrado no tempo = 0:0:9.

  • O quarto quadro-chave é animado de 500 a 600. Ele é iniciado após o término do terceiro quadro-chave (no tempo = 9 segundos) e é reproduzido por 1 segundo, sendo encerrado no tempo = 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>

Valores percentuais

Um valor percentual especifica que o quadro-chave termina em alguma porcentagem do Duration. Em XAML, você especifica a porcentagem como um número seguido pelo % símbolo. No código, você usa o FromPercent método e passa a ele indicando Double a porcentagem. O valor deve ser maior ou igual a 0 e menor ou igual a 100%. O exemplo a seguir mostra uma animação com uma duração de 10 segundos e quatro quadros-chave cujos tempos-chave são especificados como percentuais.

  • O primeiro quadro-chave é animado do valor base para 100 durante os primeiros 3 segundos, sendo encerrado no tempo = 0:0:3.

  • O segundo quadro-chave é animado de 100 a 200. Ele é iniciado após o término do primeiro quadro-chave (no tempo = 3 segundos) e é reproduzido por 5 segundos, sendo encerrado no tempo = 0:0:8 (0,8 * 10 = 8).

  • O terceiro quadro-chave é animado de 200 a 500. Ele é iniciado após o término do segundo quadro-chave (no tempo = 8 segundos) e é reproduzido por 1 segundo, sendo encerrado no tempo = 0:0:9 (0,9 * 10 = 9).

  • O quarto quadro-chave é animado de 500 a 600. Ele é iniciado após o término do terceiro quadro-chave (no tempo = 9 segundos) e é reproduzido por 1 segundo, sendo encerrado no tempo = 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>

Valor especial, uniforme

Use Uniform o tempo quando quiser que cada quadro-chave leve o mesmo tempo.

Um Uniform tempo-chave divide o tempo disponível igualmente pelo número de quadros-chave para determinar a hora de término de cada quadro-chave. O exemplo a seguir mostra uma animação com duração de 10 segundos e quatro quadros-chave cujos tempos-chave são especificados como Uniform.

  • O primeiro quadro-chave é animado do valor base para 100 durante os primeiros 2,5 segundos, sendo encerrado no tempo = 0:0:2.5.

  • O segundo quadro-chave é animado de 100 a 200. Ele é iniciado após o término do primeiro quadro-chave (no tempo = 2,5 segundos) e é reproduzido por aproximadamente 2,5 segundos, sendo encerrado no tempo = 0:0:5.

  • O terceiro quadro-chave é animado de 200 a 500. Ele é iniciado após o término do segundo quadro-chave (no tempo = 5 segundos) e é reproduzido por 2,5 segundos, sendo encerrado no tempo = 0:0:7.5.

  • O quarto quadro-chave é animado de 500 a 600. Ele é iniciado após o término do segundo quadro-chave (no tempo = 7,5 segundos) e é reproduzido por 2,5 segundos, sendo encerrado no tempo = 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>

Valor especial, personalizado

Use Paced o tempo quando quiser animar a uma taxa constante.

Um Paced tempo-chave aloca o tempo disponível de acordo com o comprimento de cada um dos quadros-chave para determinar a duração de cada quadro. Isso fornecerá o comportamento em que a velocidade ou o ritmo da animação permanece constante. O exemplo a seguir mostra uma animação com duração de 10 segundos e três quadros-chave cujos tempos-chave são especificados como 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>

Observe que, se o tempo de chave do último quadro-chave for Paced ou Uniform, seu tempo de chave resolvido será definido como 100 por cento. Se o primeiro quadro-chave em uma animação com vários quadros for personalizado, seu tempo-chave resolvido será definido como 0. (Se a coleção de quadros-chave contiver apenas um único quadro-chave e ele for um quadro-chave personalizado, seu tempo-chave resolvido será definido como 100%.)

Diferentes quadros-chave em uma animação de quadro-chave único podem usar diferentes tipos de tempos-chave.

Combinando tempos-chave e quadros-chave fora de ordem

Você pode usar quadros-chave com diferentes KeyTime tipos de valor na mesma animação. E, embora seja recomendável adicionar quadros-chave na ordem em que eles devem ser reproduzidos, isso não é necessário. O sistema de animação e tempo pode resolver quadros-chave fora de ordem. Os quadros-chave com tempos-chave inválidos são ignorados.

A lista a seguir descreve o procedimento pelo qual os tempos-chave são resolvidos para os quadros-chave de uma animação de quadro-chave.

  1. Resolva TimeSpanKeyTime valores.

  2. Determine o tempo total de interpolação da animação, o tempo total necessário para que a animação de quadro-chave conclua uma interação progressiva.

    1. Se a animação Duration não for ou Automatic, o tempo total de interpolação será o valor da propriedade da Forever animaçãoDuration.

    2. Caso contrário, o tempo total de interpolação será o maior TimeSpanKeyTime valor especificado entre seus quadros-chave, se houver.

    3. Caso contrário, o tempo total de interpolação será de 1 segundo.

  3. Use o valor de tempo total de interpolação para resolver PercentKeyTime valores.

  4. Resolva o último quadro-chave, caso ele ainda não tenha sido resolvido nas etapas anteriores. Se o KeyTime último quadro-chave for Uniform ou Paced, seu tempo resolvido será igual ao tempo total de interpolação.

    Se o KeyTime do primeiro quadro-chave for Paced e essa animação tiver mais do que em quadros-chave, resolva seu KeyTime valor como zero; se houver apenas um quadro-chave e seu KeyTime valor for Paced, ele será resolvido para o tempo total de interpolação, conforme descrito na etapa anterior.

  5. Resolva os valores restantes UniformKeyTime : cada um deles recebe uma parcela igual do tempo disponível. Durante esse processo, os valores não resolvidos PacedKeyTime são temporariamente tratados como UniformKeyTime valores e obtêm um tempo de resolução temporário.

  6. Resolva os KeyTime valores de quadros-chave com tempos-chave não especificados usando os quadros-chave declarados mais próximos deles que resolveram KeyTime valores.

  7. Resolva os valores restantes PacedKeyTime . PacedKeyTime Use os KeyTime valores dos quadros-chave vizinhos para determinar o tempo resolvido. O objetivo é garantir que a velocidade da animação é constante em relação ao tempo resolvido desse quadro-chave.

  8. Classifique os quadros-chave em ordem de tempo resolvido (chave primária) e ordem de declaração (chave secundária), ou seja, use uma classificação estável com base nos valores de quadros-chave KeyTime resolvidos.

Confira também