Condividi tramite


Funzioni di interpolazione

Le funzioni di facilitazione permettono di usare formule matematiche personalizzate nelle vostre animazioni. Ad esempio, è possibile che un oggetto rimbalzi o si comporti in modo realistico come se fosse in primavera. È possibile usare Key-Frame o persino animazioni From/To/By per approssimare questi effetti, ma richiederebbe una quantità significativa di lavoro e l'animazione sarebbe meno accurata rispetto all'uso di una formula matematica.

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

  • BackEase: ritrae leggermente il movimento di un'animazione prima che inizi ad animare nel percorso indicato.

  • BounceEase: crea un effetto di rimbalzo.

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

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

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

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

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

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

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

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

  • SineEase: Crea un'animazione che accelera e/o decelera utilizzando una funzione seno.

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

<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 di tipo From/To/By. Puoi anche applicare queste funzioni di interpolazione alle animazioni Key-Frame. Nell'esempio seguente viene illustrato come usare fotogrammi chiave con funzioni di interpolazione associate per creare un'animazione di un rettangolo che si contrae verso l'alto, rallenta, quindi si espande verso il basso (come se cadesse) e quindi rimbalza fino a fermarsi.

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

Puoi utilizzare la proprietà EasingMode per alterare il comportamento della funzione di easing, ossia cambiare il modo in cui l'animazione si sviluppa. Esistono tre possibili valori che è possibile assegnare per EasingMode:

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

  • EaseOut: L'interpolazione segue 100% con l'interpolazione meno l'output della formula associata alla funzione di attenuazione.

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

I grafici seguenti illustrano i diversi valori di EasingMode in cui f(x) rappresenta lo stato di avanzamento dell'animazione e t rappresenta l'ora.

BackEase

grafici di BackEase EasingMode.

BounceEase

grafici di BounceEase EasingMode.

CircleEase

grafici di CircleEase EasingMode.

CubicEase

grafici CubicEase EasingMode.

ElasticEase

ElasticEase con grafici di diverse modalità di easing.

ExponentialEase

Grafici di ExponentialEase di diverse modalità di interpolazione.

PowerEase

QuarticEase con grafici di diverse modalità di easing.

QuadraticEase

QuadraticEase con grafici di diverse interpolazioni

QuarticEase

QuarticEase con grafici di diverse modalità di smorzamento.

QuinticEase

QuinticEase con grafici di modalità di easing diverse.

SineEase

SineEase per modalità di easing diverse

Nota

È possibile usare PowerEase per creare lo stesso comportamento di CubicEase, QuadraticEase, QuarticEasee QuinticEase usando la proprietà Power. Ad esempio, se si vuole usare PowerEase per sostituire CubicEase, specificare un valore Power pari a 3.

Oltre a usare 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 easing personalizzata. È possibile aggiungere una logica matematica personalizzata per come si comporta la funzione di easing sovrascrivendo il metodo EaseInCore.

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();
        }
    }
}
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
<Window x:Class="CustomEasingFunction.Window1"
        xmlns:CustomEase="clr-namespace:CustomEasingFunction"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://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>