Compartir a través de


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.

Ejecutar este ejemplo

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.

Ejecutar este ejemplo

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

Ejecutar este ejemplo

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

BackEase

Gráficos EasingMode para BackEase.

BounceEase

Gráficos EasingMode para BounceEase.

CircleEase

Gráficos EasingMode para CircleEase.

CubicEase

Gráficos EasingMode para CubicEase.

ElasticEase

ElasticEase con gráficos de diferentes EasingMode.

ExponentialEase

Gráficos ExponentialEase de diferentes EasingMode.

PowerEase

QuarticEase con gráficos de diferentes EasingMode.

QuadraticEase

QuadraticEase con gráficos de la diferentes EasingMode

QuarticEase

QuarticEase con gráficos de diferentes EasingMode.

QuinticEase

QuinticEase con gráficos de diferentes EasingMode.

SineEase

SineEase para diferentes valores de EasingMode

NotaNota

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.

Ejecutar este ejemplo

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>