Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Animações lineares com quadros-chave, animações com quadros-chave que usam um valor KeySpline ou funções de easing são três técnicas diferentes para um cenário essencialmente semelhante: criar uma animação com storyboard um pouco mais complexa, que usa um comportamento de animação não linear entre um estado inicial e um estado final.
Pré-requisitos
Leia o tópico Animações com storyboard. Este tópico se baseia nos conceitos de animação que foram explicados em animações com storyboard e não os revisará novamente. Por exemplo, Animações com storyboard descreve como direcionar animações, storyboards como recursos, os valores de propriedade Timeline, como Duration, FillBehavior e assim por diante.
Animando usando animações de quadro-chave
As animações com quadros-chave permitem mais de um valor de destino, atingido em determinado ponto da linha do tempo da animação. Em outras palavras, cada quadro-chave pode especificar um valor intermediário diferente e o último quadro de chave atingido é o valor final da animação. Ao especificar vários valores a serem animados, você pode criar animações mais complexas. As animações de quadro-chave também habilitam uma lógica de interpolação diferente, que são implementadas como uma subclasse KeyFrame diferente por tipo de animação. Especificamente, cada tipo de animação de quadro-chave tem uma variação discreta, 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 em uma única coleção KeyFrames para alterar a interpolação sempre que um novo quadro-chave for atingido.
Quanto ao comportamento de interpolação, cada quadro-chave controla a interpolação até que seu tempo KeyTime seja atingido. Seu Valor é também atingido nesse momento. Se houver mais quadros-chave na sequência, o valor se torna o valor inicial do próximo quadro-chave.
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 ao funcionamento de uma animação From/To/By quando não há From.
A duração de uma animação com quadros-chave é implicitamente igual ao maior valor de KeyTime definido em qualquer um de seus quadros-chave. Você pode definir uma Duração explícita se desejar, mas tenha cuidado para que não seja menor que um KeyTime em seus próprios quadros-chave ou você cortará parte da animação.
Além de Duration, você pode definir todas as propriedades baseadas em Timeline em uma animação com quadros-chave, assim como pode fazer com uma animação From/To/By, pois as classes de animação com quadros-chave também são derivadas de Timeline. Estes são:
- AutoReverse: depois que o último quadro-chave é atingido, 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 dos valores KeyTime nos quadros não começa a ser contada até que BeginTime seja atingido, portanto não há risco de os quadros serem interrompidos
- FillBehavior: controla o que acontece quando o último quadro-chave é atingido. FillBehavior não tem efeito em nenhum quadro de chave intermediário.
-
RepeatBehavior:
- Se definido como Forever, os quadros-chave e sua linha do tempo se repetirão infinitamente.
- Se definido para uma contagem de iterações, a linha do tempo se repetirá esse número de vezes.
- Se definido como uma Duração, a linha do tempo se repetirá até que cheguemos a esse tempo. Isso pode interromper a animação no meio da sequência de quadros-chave, caso não seja um fator inteiro da duração implícita da linha do tempo.
- SpeedRatio (não comumente usado)
Quadros de chave linear
Os quadros-chave lineares resultam em uma interpolação linear simples do valor até que o KeyTime do quadro seja atingido. Esse comportamento de interpolação é o mais semelhante ao das animações mais simples 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 ligeiramente e linearmente nos primeiros 4 segundos e, em seguida, é dimensionada rapidamente para o último segundo até que o retângulo seja 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
Quadros-chave discretos não utilizam absolutamente nenhuma interpolação. Quando um KeyTime é atingido, o novo Valor é simplesmente aplicado. Dependendo da propriedade da interface do usuário que está sendo animada, isso geralmente produz uma animação que parece “dar um salto”. Tenha certeza de que esse é 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 sua meta, talvez seja melhor usar quadros-chave lineares ou spline.
Observação
Quadros de 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 de spline
Um quadro de chave spline cria uma transição variável entre valores de acordo com o valor da propriedade KeySpline . Essa 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 de função ao longo do tempo em que o gráfico da função-tempo é a forma dessa curva de Bézier. Normalmente, você especifica um valor KeySpline em um atributo XAML de forma abreviada que tem quatro valores Double separados por espaços ou vírgulas. Esses valores são pares "X,Y" para dois pontos de controle da curva bezier. "X" é o tempo e "Y" é o modificador da função do valor. Cada valor deve estar sempre entre 0 e 1, inclusive. Sem modificação do ponto de controle em 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 grafo.
Este próximo exemplo mostra três quadros-chave diferentes aplicados a uma animação, sendo o último um quadro-chave de spline para um valor de Double (SplineDoubleKeyFrame). Observe a cadeia de caracteres "0.6,0.0 0.9,0.00" aplicada a KeySpline. Isso produz uma curva em que a animação parece ser executada lentamente no início, mas atinge rapidamente o valor pouco antes do KeyTime ser atingido.
<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>
Suavizando quadros-chave
Um quadro-chave de easing é um quadro-chave em que a interpolação está sendo aplicada, e a função ao longo do tempo da interpolação é controlada por várias fórmulas matemáticas predefinidas. Você pode obter praticamente o mesmo resultado com um quadro-chave de spline que obteria com alguns dos tipos de funções de easing, mas também há algumas funções de easing, como BackEase, que não podem ser reproduzidas com spline.
Para aplicar uma função de easing a um quadro-chave de easing, defina a propriedade EasingFunction como um elemento de propriedade em XAML para esse quadro-chave. Para o valor, especifique um elemento de objeto para um dos tipos de função de easing.
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 suavização. Abordaremos mais na próxima seção.
Funções de easing
As funções de easing permitem que você aplique fórmulas matemáticas personalizadas às suas animações. As operações matemáticas geralmente são úteis para produzir animações que simulam a física do mundo real em um sistema de coordenadas 2D. Por exemplo, talvez você queira que um objeto salte ou se comporte de forma realista 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 um trabalho considerável, e a animação seria menos precisa do que ao usar uma fórmula matemática.
As funções de easing podem ser aplicadas a animações de três maneiras:
- Ao usar um quadro-chave de easing em uma animação de quadro-chave, conforme descrito na seção anterior. Use EasingColorKeyFrame.EasingFunction, EasingDoubleKeyFrame.EasingFunction ou EasingPointKeyFrame.EasingFunction.
- Ao definir a propriedade EasingFunction em um dos tipos de animação From/To/By animation types. 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 estados visuais.
Aqui está uma lista das funções de easing:
- BackEase: retrai o movimento de uma animação ligeiramente antes de começar a animar 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 de um lado para o outro até parar.
- 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 em que 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 acelere ou desacelere usando a fórmula f(t) = t5.
- SineEase: cria uma animação que acelera ou desacelera usando uma fórmula de seno.
Algumas das funções de easing 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 easing, como CubicEase , não têm propriedades diferentes da propriedade EasingMode que todas as funções de easing compartilham e sempre produzem o mesmo comportamento de função ao longo do tempo.
Algumas dessas funções de functions apresentam certa sobreposição, dependendo de como você define as propriedades das funções de easing que têm propriedades próprias. Por exemplo, QuadraticEase é exatamente o mesmo que um PowerEase com Power igual a 2. E CircleEase é basicamente um ExponentialEase de valor padrão.
A função de easing BackEase é exclusiva porque pode alterar o valor para fora do intervalo normal definido pelos valores From/To ou pelos valores dos quadros-chave. Ela inicia a animação alterando o valor na direção oposta à esperada em um comportamento normal de From/To, retorna ao valor From ou valor inicial, e então executa a animação normalmente.
Em um exemplo anterior, mostramos como declarar uma função de easing para uma animação de quadro-chave. Este próximo exemplo aplica uma função de suavização a uma animação de 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 easing é aplicada a uma animação From/To/By, ela altera as características da função ao longo do tempo que determina como o valor é interpolado entre os valores From e To durante a Duration 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 Double, Point ou Color. Esta é a animação de quadro-chave ObjectAnimationUsingKeyFrames. Animar usando valores de objeto é diferente porque não há possibilidade de interpolar os valores entre os quadros. Quando o KeyTime do quadro de animação é atingido, o valor animado é imediatamente ajustado para 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 de chave ObjectAnimationUsingKeyFrames : DiscreteObjectKeyFrame.
O valor de um DiscreteObjectKeyFrame geralmente é definido usando a sintaxe do elemento de propriedade, pois o valor do objeto que você está tentando definir geralmente não é expressível como uma cadeia de caracteres para preencher Valor na sintaxe do atributo. Você ainda poderá usar a sintaxe de atributo se usar uma referência como StaticResource.
Um lugar em que 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 definidos como temas do sistema (ThemeDictionaries). Eles podem ser atribuídos diretamente a um valor do tipo Brush, como TextBlock.Foreground , e não precisam usar o 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 ela 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 ObjectAnimationUsingKeyFrames conjunto de quadros. 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 o qual vários valores de objeto podem ser úteis.
Tópicos relacionados
Windows developer