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 de quadro-chave, animações de quadro-chave com um valor KeySpline ou funções de easing são três técnicas diferentes para aproximadamente o mesmo cenário: criar uma animação planejada que é um pouco mais complexa e que aplica um comportamento de animação não linear, que transita de um estado inicial para um estado final.
Pré-requisitos
Certifique-se de ter lido o tópico de storyboarded animações. 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 de Timeline, como Duração, FillBehavior e assim por diante.
Animando usando animações de quadro-chave
As animações de quadro-chave permitem mais de um valor de destino que é atingido em um ponto ao longo 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.
Para o comportamento de interpolação, cada quadro-chave controla a interpolação até que o tempo de KeyTime seja atingido. Seu Valor é também atingido nesse momento. Se houver mais quadros-chave além, o valor se tornará o valor inicial do próximo quadro-chave em uma 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 a que equivale 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 Duração, você pode definir todas as propriedades baseadas em Linha do Tempo em uma animação de quadro-chave, assim como em uma animação From/To/By, porque as classes de animação de quadro-chave também são derivadas de Linha do Tempo. Estes são:
- AutoReverso: depois que o último quadro-chave é atingido, os quadros são repetidos em 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 KeyTime nos quadros não começa a contar até BeginTime ser 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 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 durante a sequência de quadros principais, se não for um fator inteiro da duração implícita do cronograma.
- SpeedRatio (não comumente usado)
Quadros de chave linear
Quadros de chave linear 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 às mais simples animações De/Para/Por, descritas no tópico de animações baseadas em 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 de qual propriedade da interface do usuário está sendo animada, isso geralmente produz uma animação que parece "saltar". 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 uma animação de spline de chave para um valor duplo (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 flexibilização é 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. Na verdade, você pode produzir praticamente o mesmo resultado com um quadro-chave do tipo spline, assim como com alguns dos tipos de funções de easing. No entanto, existem algumas funções de easing, como BackEase, que você não pode reproduzir com uma 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 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ê pode usar quadros-chave ou até mesmo animações De/Para/Por para aproximar esses efeitos, mas seria necessário um esforço significativo de trabalho, e as animações seriam menos precisas do que usar uma fórmula matemática.
As funções de easing podem ser aplicadas a animações de três maneiras:
- Ao utilizar um quadro-chave de suavização em uma animação de quadros-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 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 suas próprias propriedades. 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 easing têm um pouco de sobreposição, dependendo de como você define propriedades nas funções de easing que têm propriedades. 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 é única porque pode alterar o valor para além do intervalo normal, conforme definido por From/To ou pelos valores dos keyframes. Ele inicia a animação alterando o valor na direção oposta à esperada de um comportamento normal De/Para, retorna ao valor De ou inicial novamente, 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 de como a função interpola os valores From e To ao longo da 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 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