Funzioni di interpolazione

Le funzioni di interpolazione consentono di applicare formule matematiche personalizzate alle animazioni. È ad esempio possibile che si desideri creare un oggetto che rimbalzi in modo realistico o che si comporti come se si trovasse su una molla. A tale scopo è possibile utilizzare le animazioni Key-Frame o From/To/By per ottenere un'approssimazione di questi effetti, ma la quantità di lavoro richiesta sarebbe eccessiva e l'animazione risulterebbe meno accurata rispetto all'utilizzo di una formula matematica.

Oltre a creare una funzione di interpolazione personalizzata ereditando da EasingFunctionBase, è possibile utilizzare una delle diverse funzioni di interpolazione fornite dal runtime per la creazione di effetti comuni.

  • BackEase: contrae leggermente il movimento di un'animazione prima che inizi ad animarsi lungo il percorso indicato.

  • BounceEase: crea un effetto di rimbalzo.

  • CircleEase: crea un'animazione che accelera e/o decelera utilizzando una funzione circolare.

  • CubicEase: crea un'animazione che accelera e/o decelera utilizzando la formula f(t) = t3.

  • ElasticEase: crea un'animazione simile a una molla che oscilla avanti e indietro fino a quando non si ferma.

  • ExponentialEase: crea un'animazione che accelera e/o decelera utilizzando una formula esponenziale.

  • PowerEase: crea un'animazione che accelera e/o decelera utilizzando la formula f(t) = tp, dove p equivale alla proprietà Power.

  • QuadraticEase: crea un'animazione che accelera e/o decelera utilizzando la formula f(t) = t2.

  • QuarticEase: crea un'animazione che accelera e/o decelera utilizzando la formula f(t) = t4.

  • QuinticEase: crea un'animazione che accelera e/o decelera utilizzando la formula f(t) = t5.

  • SineEase: crea un'animazione che accelera e/o decelera utilizzando una formula sinusoidale.

È possibile osservare il comportamento di queste funzioni di interpolazione utilizzando l'esempio seguente.

Esegui questo esempio (la pagina potrebbe essere in inglese).

Per applicare una funzione di interpolazione a un'animazione, utilizzare la proprietà EasingFunction dell'animazione specificando la funzione di interpolazione da applicare all'animazione. Nell'esempio seguente viene applicata una funzione di interpolazione BounceEase a un oggetto DoubleAnimation per creare un effetto di rimbalzo.

Esegui questo esempio

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

Nell'esempio precedente la funzione di interpolazione è stata applicata a un'animazione From/To/By. È inoltre possibile applicare queste funzioni di interpolazione alle animazioni Key-Frame. Nell'esempio seguente viene illustrato come utilizzare fotogrammi chiave ai quali sono associate funzioni di interpolazione per creare un'animazione di un rettangolo che si contrae verso l'alto e verso il basso, quindi si espande verso il basso come se stesse cadendo e infine rimbalza fino a fermarsi.

Esegui questo esempio

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

È possibile utilizzare la proprietà EasingMode per modificare il comportamento della funzione di interpolazione, ovvero per modificare l'interpolazione dell'animazione. La proprietà EasingMode può avere tre valori diversi:

  • EaseIn: l'interpolazione segue la formula matematica associata alla funzione di interpolazione.

  • EaseOut: l'interpolazione segue completamente l'interpolazione, ma non l'output della formula associata alla funzione di interpolazione.

  • EaseInOut: l'interpolazione utilizza EaseIn per la prima metà dell'animazione e EaseOut per la seconda metà.

Nelle immagini seguenti vengono illustrati i diversi valori di EasingMode, dove f(x) rappresenta lo stato di avanzamento dell'animazione e t rappresenta il tempo.

BackEase

Grafici di EasingMode per BackEase.

BounceEase

Grafici di EasingMode per BounceEase.

CircleEase

Grafici di EasingMode per CircleEase.

CubicEase

Grafici di EasingMode per CubicEase.

ElasticEase

ElasticEase con grafici di EasingMode diversi.

ExponentialEase

Grafici di ExponentialEase con EasingMode diversi.

PowerEase

QuarticEase con grafici di EasingMode diversi.

QuadraticEase

QuadraticEase con grafici di EasingMode diversi

QuarticEase

QuarticEase con grafici di EasingMode diversi.

QuinticEase

QuinticEase con grafici di EasingMode diversi.

SineEase

SineEase per valori EasingMode diversi

NotaNota

È possibile utilizzare PowerEase per creare lo stesso comportamento di CubicEase, QuadraticEase, QuarticEase e QuinticEase utilizzando la proprietà Power.Se ad esempio si desidera utilizzare PowerEase in sostituzione di CubicEase, specificare 3 come valore di Power.

Oltre a utilizzare le funzioni di interpolazione incluse nel runtime, è possibile creare funzioni di interpolazione personalizzate ereditando da EasingFunctionBase. Nell'esempio seguente viene illustrato come creare una semplice funzione di interpolazione personalizzata. È possibile aggiungere la propria logica matematica per determinare il comportamento della funzione di interpolazione eseguendo l'override del metodo EaseInCore.

Esegui questo esempio

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>