Funciones de aceleración
Las funciones de aceleración permiten aplicar fórmulas matemáticas personalizadas a las animaciones. Por ejemplo, tal vez desee que un objeto rebote de forma realista o se comporte como si fuera un muelle. Puede usar animaciones de fotogramas clave o incluso animaciones From/To/By para conseguir efectos aproximados a estos, pero se necesitaría bastante trabajo y la animación sería menos precisa que si se empleara una fórmula matemática.
Además de crear su propia función de aceleración heredando de la clase EasingFunctionBase, puede usar una de las funciones de aceleración proporcionadas por el motor en tiempo de ejecución con el fin de crear efectos comunes.
BackEase: contrae el movimiento de una animación justo antes de que empiece a animarse en el trazado indicado.
BounceEase: crea un efecto de rebote.
CircleEase: crea una animación que acelera y/o desacelera mediante una función circular.
CubicEase: crea una animación que acelera y/o desacelera mediante la fórmula f(t) = t3.
ElasticEase: crea una animación que parece un resorte que oscila de un lado a otro hasta detenerse.
ExponentialEase: crea una animación que acelera y/o desacelera mediante una fórmula exponencial.
PowerEase: crea una animación que acelera y/o desacelera mediante la fórmula f(t) = tp, donde p es igual a la propiedad Power.
QuadraticEase: crea una animación que acelera y/o desacelera mediante la fórmula f(t) = t2.
QuarticEase: crea una animación que acelera y/o desacelera mediante la fórmula f(t) = t4.
QuinticEase: crea una animación que acelera y/o desacelera mediante la fórmula f(t) = t5.
SineEase: crea una animación que acelera y/o desacelera mediante una fórmula sinusoidal.
Puede explorar el comportamiento de estas funciones de aceleración con el ejemplo siguiente.
Para aplicar una función de aceleración a una animación, use la propiedad EasingFunction de la animación para especificar la función que debe aplicarse a la animación. En el ejemplo siguiente se aplica una función de aceleración BounceEase a un objeto DoubleAnimation para crear un efecto de rebote.
<Rectangle Name="myRectangle" Width="200" Height="30" Fill="Blue">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseDown">
<BeginStoryboard>
<Storyboard>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation From="30" To="200" Duration="00:00:3"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="Height">
<DoubleAnimation.EasingFunction>
<BounceEase Bounces="2" EasingMode="EaseOut"
Bounciness="2" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
En el ejemplo anterior, la función de aceleración se aplicó a una animación From/To/By. Estas funciones de aceleración también se pueden aplicar a las animaciones de fotogramas clave. En el ejemplo siguiente se muestra cómo usar fotogramas clave con funciones de aceleración asociadas a ellos con el fin de crear una animación de un rectángulo que se contrae hacia arriba, se desacelera, se expande hacia abajo (como si cayera) y, a continuación, rebota hasta detenerse.
<Rectangle Name="myRectangle" Width="200" Height="200" Fill="Blue">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="Height"
Storyboard.TargetName="myRectangle">
<!-- This keyframe animates the ellipse up to the crest
where it slows down and stops. -->
<EasingDoubleKeyFrame Value="30" KeyTime="00:00:02">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<!-- This keyframe animates the ellipse back down and makes
it bounce. -->
<EasingDoubleKeyFrame Value="200" KeyTime="00:00:06">
<EasingDoubleKeyFrame.EasingFunction>
<BounceEase Bounces="5" EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Puede usar la propiedad EasingMode para modificar el comportamiento de la función de aceleración; es decir, para cambiar cómo se interpola la animación. Hay tres valores posibles que puede proporcionar para EasingMode:
EaseIn: la interpolación sigue la fórmula matemática asociada a la función de aceleración.
EaseOut: la interpolación sigue la interpolación al 100% menos el resultado de la fórmula asociada a la función de aceleración.
EaseInOut: la interpolación usa EaseIn para la primera mitad de la animación y EaseOut para la segunda mitad.
En los gráficos siguientes se muestran los diferentes valores de EasingMode, donde f(t) representa el progreso de la animación y t representa el tiempo.
Nota |
---|
Puede utilizar PowerEase para crear el mismo comportamiento que CubicEase, QuadraticEase, QuarticEase y QuinticEase usando la propiedad Power.Por ejemplo, si desea usar PowerEase en lugar de CubicEase, especifique el valor 3 para la propiedad Power. |
Además de usar las funciones de aceleración incluidas en el motor en tiempo de ejecución, puede crear funciones personalizadas heredando de EasingFunctionBase. En el ejemplo siguiente se muestra cómo crear una función simple de aceleración personalizada. Puede agregar su propia lógica matemática para el comportamiento de la función de aceleración invalidando el método EaseInCore.
Namespace CustomEasingFunction
Public Class CustomSeventhPowerEasingFunction
Inherits EasingFunctionBase
Public Sub New()
MyBase.New()
End Sub
' Specify your own logic for the easing function by overriding
' the EaseInCore method. Note that this logic applies to the "EaseIn"
' mode of interpolation.
Protected Overrides Function EaseInCore(ByVal normalizedTime As Double) As Double
' applies the formula of time to the seventh power.
Return Math.Pow(normalizedTime, 7)
End Function
' Typical implementation of CreateInstanceCore
Protected Overrides Function CreateInstanceCore() As Freezable
Return New CustomSeventhPowerEasingFunction()
End Function
End Class
End Namespace
namespace CustomEasingFunction
{
public class CustomSeventhPowerEasingFunction : EasingFunctionBase
{
public CustomSeventhPowerEasingFunction()
: base()
{
}
// Specify your own logic for the easing function by overriding
// the EaseInCore method. Note that this logic applies to the "EaseIn"
// mode of interpolation.
protected override double EaseInCore(double normalizedTime)
{
// applies the formula of time to the seventh power.
return Math.Pow(normalizedTime, 7);
}
// Typical implementation of CreateInstanceCore
protected override Freezable CreateInstanceCore()
{
return new CustomSeventhPowerEasingFunction();
}
}
}
<Window x:Class="CustomEasingFunction.Window1"
xmlns:CustomEase="clr-namespace:CustomEasingFunction"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="500" Width="300">
<StackPanel>
<TextBlock Margin="10" TextWrapping="Wrap">Click on the rectangle to start the animation</TextBlock>
<StackPanel x:Name="LayoutRoot" Background="White">
<Rectangle Name="myRectangle" Width="200" Height="30" Fill="Blue">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="30" To="300" Duration="00:00:3"
Storyboard.TargetName="myRectangle"
Storyboard.TargetProperty="Height">
<DoubleAnimation.EasingFunction>
<!-- You get the EasingMode property for free on your custom
easing function.-->
<CustomEase:CustomSeventhPowerEasingFunction EasingMode="EaseIn"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</StackPanel>
</StackPanel>
</Window>