Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Animações lineares de quadros-chave, animações de quadros-chave com um valor KeySpline ou funções de atenuação são três técnicas diferentes para aproximadamente o mesmo cenário: criar uma animação storyboard um pouco mais complexa e que usa um comportamento de animação não linear de um estado inicial para um estado final.
Pré-requisitos
Certifique-se de que leu o tópico Animações com storyboard. Este tópico baseia-se nos conceitos de animação que foram explicados nas animações com Storyboard e não voltará a abordá-los. Por exemplo, animações com storyboards descrevem como direcionar animações, storyboards enquanto recursos, os valores da propriedade Timeline, tais como Duration, FillBehavior, e assim por diante.
Animação usando animações de quadro-chave
As animações de quadros-chave permitem mais de um valor-alvo que é atingido num ponto da linha temporal da animação. Em outras palavras, cada quadro-chave pode especificar um valor intermediário diferente, e o último quadro-chave alcançado é o valor final da animação. Ao especificar vários valores para animar, você pode criar animações mais complexas. As animações de quadros-chave também permitem lógicas de interpolação diferentes, cada uma implementada como uma subclasse KeyFrame diferente por tipo de animação. Especificamente, cada tipo de animação de quadro-chave tem uma variação Discrete, Linear, Spline e Easing de sua classe KeyFrame para especificar seus quadros-chave. Por exemplo, para especificar uma animação direcionada a um Double e usa quadros-chave, você pode declarar quadros-chave com DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFrame e EasingDoubleKeyFrame. Você pode usar qualquer um desses tipos dentro de uma única coleção KeyFrames , para alterar a interpolação cada vez que um novo quadro-chave é alcançado.
Para o comportamento de interpolação, cada quadro-chave controla a interpolação até que seu tempo KeyTime seja atingido. Seu valor é atingido nesse momento também. Se houver mais quadros-chave além disso, o valor torna-se o valor inicial para o próximo quadro-chave numa sequência.
No início da animação, se nenhum quadro-chave com KeyTime de "0:0:0" existir, o valor inicial será qualquer que seja o valor não animado da propriedade. Isso é semelhante a como uma animação From/To/By funciona se não houver From.
A duração de uma animação de quadro-chave é implicitamente igual à do maior valor KeyTime definido em qualquer um dos seus quadros-chave. Você pode definir uma Duração explícita se desejar, mas tenha cuidado para que ela não seja menor do que um KeyTime em seus próprios quadros-chave ou você cortará parte da animação.
Além de Duration, pode definir todas as propriedades baseadas em Timeline numa animação de quadro-chave, tal como pode com uma animação From/To/By, porque as classes de animação de quadro-chave também são derivadas de Timeline. São eles:
- AutoReverse: quando se atinge o último quadro-chave, os quadros são repetidos na ordem inversa a partir do final. Isso dobra a duração aparente da animação.
- BeginTime: atrasa o início da animação. A linha do tempo para os valores de KeyTime nos quadros só começa a contar quando BeginTime é alcançado, portanto, não há risco de cortar quadros.
- FillBehavior: controla o que acontece quando o último quadro-chave é atingido. FillBehavior não tem efeito em nenhum quadro-chave intermediário.
-
RepeatBehavior:
- Se definido como Para sempre, os quadros-chave e sua linha do tempo se repetem infinitamente.
- Se for definido um número de iterações, a linha do tempo repete-se esse número de vezes.
- Se definido como Duração, a linha do tempo se repete até que esse tempo seja atingido. Isso pode truncar a animação durante a sequência de fotogramas-chave, se não for um fator inteiro da duração prevista do cronograma.
- SpeedRatio (não usado com frequência)
Quadros-chave lineares
Os quadros-chave lineares resultam em uma interpolação linear simples do valor até que o KeyTime do quadro seja alcançado. Esse comportamento de interpolação é o mais semelhante às animações mais simples de From/To/By, descritas no tópico Animações com storyboard.
Veja como usar uma animação de quadro-chave para dimensionar a altura de renderização de um retângulo, usando quadros-chave lineares. Este exemplo executa uma animação em que a altura do retângulo aumenta ligeira e linearmente durante os primeiros 4 segundos e, em seguida, é dimensionada rapidamente no último segundo até que o retângulo tenha o dobro da altura inicial.
<StackPanel>
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
<LinearDoubleKeyFrame Value="1.2" KeyTime="0:0:4"/>
<LinearDoubleKeyFrame Value="2" KeyTime="0:0:5"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</StackPanel.Resources>
</StackPanel>
Quadros-chave discretos
Os quadros-chave discretos não usam nenhuma interpolação. Quando um KeyTime é atingido, o novo valor é simplesmente aplicado. Dependendo de qual propriedade da interface do usuário está sendo animada, isso geralmente produz uma animação que parece "saltar". Tenha certeza de que este é o comportamento estético que você realmente quer. Você pode minimizar os saltos aparentes aumentando o número de quadros-chave declarados, mas se uma animação suave for seu objetivo, talvez seja melhor usar quadros-chave lineares ou spline.
Observação
Quadros-chave discretos são a única maneira de animar um valor que não é do tipo Double, Point e Color, com um DiscreteObjectKeyFrame. Discutiremos isso mais detalhadamente mais adiante neste tópico.
Quadros-chave Spline
Um quadro-chave spline cria uma transição variável entre valores de acordo com o valor da propriedade KeySpline . Esta propriedade especifica o primeiro e o segundo pontos de controle de uma curva de Bezier, que descreve a aceleração da animação. Basicamente, um KeySpline define uma relação função-tempo em que o gráfico função-tempo é a forma dessa curva de Bezier. Normalmente, você especifica um valor KeySpline em uma cadeia de caracteres de atributo abreviado XAML que tem quatro valores Double separados por espaços ou vírgulas. Estes valores são pares "X,Y" para dois pontos de controlo da curva de Bezier. "X" é o tempo e "Y" é o modificador da função para o valor. Cada valor deve estar sempre entre 0 e 1 inclusive. Sem modificação do ponto de controle para um KeySpline, a linha reta de 0,0 a 1,1 é a representação de uma função ao longo do tempo para uma interpolação linear. Seus pontos de controle alteram a forma dessa curva e, portanto, o comportamento da função ao longo do tempo para a animação spline. Provavelmente é melhor ver isso visualmente como um gráfico.
Este próximo exemplo mostra três quadros-chave diferentes aplicados a uma animação, sendo o último uma animação spline de chave para um valor Double (SplineDoubleKeyFrame). Observe a cadeia de caracteres "0.6,0.0 0.9,0.00" aplicada para KeySpline. Isso produz uma curva onde a animação parece ser executada lentamente no início, mas depois atinge rapidamente o valor pouco antes do KeyTime ser alcançado.
<Storyboard x:Name="myStoryboard">
<!-- 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" EnableDependentAnimation="True">
<!-- Using a LinearDoubleKeyFrame, the rectangle moves
steadily from its starting position to 500 over
the first 3 seconds. -->
<LinearDoubleKeyFrame Value="500" KeyTime="0:0:3"/>
<!-- Using a DiscreteDoubleKeyFrame, the rectangle suddenly
appears at 400 after the fourth second of the animation. -->
<DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4"/>
<!-- Using a SplineDoubleKeyFrame, the rectangle moves
back to its starting point. The
animation starts out slowly at first and then speeds up.
This KeyFrame ends after the 6th second. -->
<SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00" Value="0" KeyTime="0:0:6"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Suavização de quadros-chave
Um quadro-chave de suavização é um quadro-chave onde a interpolação é aplicada, e a função ao longo do tempo da interpolação é controlada por várias fórmulas matemáticas predefinidas. Na verdade, você pode produzir o mesmo resultado com um quadro-chave spline como você pode com alguns dos tipos de função de flexibilização, mas também há algumas funções de flexibilização, como BackEase, que você não pode reproduzir com um spline.
Para aplicar uma função de atenuação a um quadro-chave de atenuação, defina a propriedade EasingFunction como um elemento de propriedade em XAML para esse quadro-chave. Para o valor, especifique um elemento object para um dos tipos de função de atenuação.
Este exemplo aplica um CubicEase e, em seguida, um BounceEase como quadros-chave sucessivos a um DoubleAnimation para criar um efeito de salto.
<Storyboard x:Name="myStoryboard">
<DoubleAnimationUsingKeyFrames Duration="0:0:10"
Storyboard.TargetProperty="Height"
Storyboard.TargetName="myEllipse">
<!-- This keyframe animates the ellipse up to the crest
where it slows down and stops. -->
<EasingDoubleKeyFrame Value="-300" KeyTime="00:00:02">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<!-- This keyframe animates the ellipse back down and makes
it bounce. -->
<EasingDoubleKeyFrame Value="0" KeyTime="00:00:06">
<EasingDoubleKeyFrame.EasingFunction>
<BounceEase Bounces="5"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Este é apenas um exemplo de função de flexibilização. Abordaremos mais na próxima seção.
Funções de suavização
As funções de atenuação permitem-lhe aplicar fórmulas matemáticas personalizadas às suas animações. As operações matemáticas são frequentemente úteis para produzir animações que simulam a física do mundo real num sistema de coordenadas 2D. Por exemplo, você pode querer que um objeto salte realisticamente ou se comporte como se estivesse em uma mola. Você poderia usar quadros-chave ou até mesmo animações From/To/By para aproximar esses efeitos, mas isso exigiria uma quantidade significativa de trabalho e a animação seria menos precisa do que usar uma fórmula matemática.
As funções de flexibilização podem ser aplicadas a animações de três maneiras:
- Usando um quadro-chave de atenuação em uma animação de quadro-chave, conforme descrito na seção anterior. Use EasingColorKeyFrame.EasingFunction, EasingDoubleKeyFrame.EasingFunction ou EasingPointKeyFrame.EasingFunction.
- Definindo a propriedade EasingFunction em um dos tipos de animação From/To/By. Use ColorAnimation.EasingFunction, DoubleAnimation.EasingFunction ou PointAnimation.EasingFunction.
- Definindo GeneratedEasingFunction como parte de um VisualTransition. Isso é específico para definir estados visuais para controles; para obter mais informações, consulte GeneratedEasingFunction ou Storyboards para obter estados visuais.
Aqui está uma lista das funções de flexibilização:
- BackEase: Retrai o movimento de uma animação um pouco antes que ela comece a ser animada no caminho indicado.
- BounceEase: Cria um efeito de salto.
- CircleEase: cria uma animação que acelera ou desacelera usando uma função circular.
- CubicEase: Cria uma animação que acelera ou desacelera usando a fórmula f(t) = t3.
- ElasticEase: Cria uma animação que se assemelha a uma mola oscilando para frente e para trás até descansar.
- ExponentialEase: cria uma animação que acelera ou desacelera usando uma fórmula exponencial.
- PowerEase: Cria uma animação que acelera ou desacelera usando a fórmula f(t) = tp onde p é igual à propriedade Power .
- QuadraticEase: Cria uma animação que acelera ou desacelera usando a fórmula f(t) = t2.
- QuarticEase: Cria uma animação que acelera ou desacelera usando a fórmula f(t) = t4.
- QuinticEase: Crie uma animação que acelera ou desacelera usando a fórmula f(t) = t5.
- SineEase: Cria uma animação que acelera ou desacelera usando uma fórmula seno.
Algumas das funções de flexibilização têm propriedades próprias. Por exemplo, BounceEase tem duas propriedades Bounces e Bounciness que modificam o comportamento de função ao longo do tempo desse BounceEase específico. Outras funções de flexibilização, como CubicEase , não têm propriedades diferentes da propriedade EasingMode que todas as funções de flexibilização compartilham e sempre produzem o mesmo comportamento de função ao longo do tempo.
Algumas destas funções de suavização apresentam alguma sobreposição, dependendo de como se definem propriedades nas funções de suavização que possuem propriedades. Por exemplo, QuadraticEase é exatamente o mesmo que um PowerEase com Power igual a 2. E CircleEase é basicamente um valor padrão ExponentialEase.
A função de flexibilização BackEase é exclusiva porque pode alterar o valor fora do intervalo normal, conforme definido por From/To ou valores de quadros-chave. Ele inicia a animação alterando o valor na direção oposta àquela esperada de um comportamento normal de De/Para, volta novamente ao valor inicial ou De e, em seguida, executa a animação normalmente.
Em um exemplo anterior, mostramos como declarar uma função de atenuação para uma animação de quadro-chave. Este próximo exemplo aplica uma função de alívio a uma animação From/To/By.
<StackPanel x:Name="LayoutRoot" Background="White">
<StackPanel.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation From="30" To="200" Duration="00:00:3"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<DoubleAnimation.EasingFunction>
<BounceEase Bounces="2" EasingMode="EaseOut"
Bounciness="2"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</StackPanel.Resources>
<Rectangle x:Name="myRectangle" Fill="Blue" Width="200" Height="30"/>
</StackPanel>
Quando uma função de aceleração é aplicada a uma animação From/To/By, ela está alterando as características da função ao longo do tempo, de como o valor interpola entre os valores From e To durante a Duração da animação. Sem uma função de flexibilização, isso seria uma interpolação linear.
Animações de valor de objeto discreto
Um tipo de animação merece menção especial porque é a única maneira de aplicar um valor animado a propriedades que não são do tipo Duplo, Ponto ou Cor. Esta é a animação de quadro-chave ObjectAnimationUsingKeyFrames. A animação usando valores Object é diferente porque não há possibilidade de interpolar os valores entre os quadros. Quando KeyTime do quadro é atingido, o valor animado é imediatamente definido como o valor especificado no Valor do quadro-chave. Como não há interpolação, há apenas um quadro-chave que você usa na coleção de quadros-chave ObjectAnimationUsingKeyFrames : DiscreteObjectKeyFrame.
O valor de um DiscreteObjectKeyFrame geralmente é definido usando a sintaxe do elemento de propriedade, porque o valor do objeto que você está tentando definir frequentemente não é expressável como uma cadeia de caracteres para preencher o valor na sintaxe do atributo. Você ainda pode usar a sintaxe de atributo se usar uma referência como StaticResource.
Um local onde você verá um ObjectAnimationUsingKeyFrames usado nos modelos padrão é quando uma propriedade de modelo faz referência a um recurso Brush . Esses recursos são objetos SolidColorBrush , não apenas um valor Color , e usam recursos que são definidos como temas do sistema (ThemeDictionaries). Eles podem ser atribuídos diretamente a um valor do tipo Pincel, como TextBlock.Foreground, e não precisam usar direcionamento indireto. Mas como um SolidColorBrush não é Double, Point ou Color, você precisa usar um ObjectAnimationUsingKeyFrames para usar o recurso.
<Style x:Key="TextButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<TextBlock x:Name="Text"
Text="{TemplateBinding Content}"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
...
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Você também pode usar ObjectAnimationUsingKeyFrames para animar propriedades que usam um valor de enumeração. Aqui está outro exemplo de um estilo nomeado que vem dos modelos padrão do Windows Runtime. Observe como ele define a propriedade Visibility que usa uma constante de enumeração Visibility . Nesse caso, você pode definir o valor usando a sintaxe do atributo. Você só precisa do nome da constante não qualificada de uma enumeração para definir uma propriedade com um valor de enumeração, por exemplo, "Collapsed".
<Style x:Key="BackButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="RootGrid">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
... <VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="Collapsed" KeyTime="0"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
...
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Você pode usar mais de um DiscreteObjectKeyFrame para um conjunto de quadros ObjectAnimationUsingKeyFrames . Essa pode ser uma maneira interessante de criar uma animação de "apresentação de slides" animando o valor de Image.Source, como um cenário de exemplo para onde vários valores de objeto podem ser úteis.
Tópicos relacionados
Windows developer