イージング関数

イージング関数を使うと、独自の数式をアニメーションに適用することができます。 たとえば、オブジェクトをリアルにバウンドさせたり、バネに乗っているように動作させたりすることができます。 キー フレーム アニメーションや From/To/By アニメーションを使ってこれらの効果を近似することもできますが、大量の作業が必要であり、アニメーションは数式を使うほど正確ではありません。

EasingFunctionBase から継承することによって独自のカスタム イージング関数を作成するだけでなく、ランタイムによって提供されるいくつかのイージング関数の 1 つを使用して一般的な効果を作成できます。

  • BackEase:示されているパスでアニメーション化を開始する直前に、アニメーションの動作を逆行させます。

  • BounceEase:バウンス効果を作成します。

  • CircleEase:円関数を使って加速や減速するアニメーションを作成します。

  • CubicEase:数式 f(t) = t3 を使用して、加速や減速するアニメーションを作成します。

  • ElasticEase:静止するまで前後に振れるバネのようなアニメーションを作成します。

  • ExponentialEase:指数式を使って、加速や減速するアニメーションを作成します。

  • PowerEase:数式 f(t) = tp (この場合、p は Power プロパティと等しい) を使用して、加速や減速するアニメーションを作成します。

  • QuadraticEase:数式 f(t) = t2 を使用して、加速や減速するアニメーションを作成します。

  • QuarticEase:数式 f(t) = t4 を使用して、加速や減速するアニメーションを作成します。

  • QuinticEase:数式 f(t) = t5 を使用して、加速や減速するアニメーションを作成します。

  • SineEase:正弦公式を使用して、加速または減速するアニメーションを作成します。

アニメーションにイージング関数を適用するには、アニメーションの EasingFunction プロパティを使って、アニメーションに適用するイージング関数を指定します。 次の例は、BounceEase イージング関数を DoubleAnimation に適用して、バウンス効果を作成します。

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

前の例では、イージング関数を From/To/By アニメーションに適用しました。 キー フレーム アニメーションにこれらのイージング関数を適用することもできます。 次の例では、キー フレームとそれらに関連付けられたイージング関数を使って、四角形が上方に縮まり、遅くなり、下方に延び (落下するように)、停止するアニメーションを作成します。

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

EasingMode プロパティを使用して、イージング関数の動作を変更する、つまり、アニメーションの補間方法を変更することができます。 EasingMode に指定できる値は次の 3 つです。

  • EaseIn:補間は、イージング関数に関連付けられている数式に従います。

  • EaseOut:補間は、100% の補間から、イージング関数に関連付けられている数式の出力を引いた値に従います。

  • EaseInOut:補間は、アニメーションの最初の半分には EaseIn を使用し、残りの半分には EaseOut を使用します。

次のグラフは、EasingMode のさまざまな値を示しています。f(x) はアニメーションの進行状況を表し、t は時間を表します。

BackEase

BackEase EasingMode graphs.

BounceEase

BounceEase EasingMode graphs.

CircleEase

CircleEase EasingMode graphs.

CubicEase

CubicEase EasingMode graphs.

ElasticEase

ElasticEase with graphs of different easingmodes.

ExponentialEase

ExponentialEase graphs of different easingmodes.

PowerEase

QuarticEase with graphs of different easingmodes.

QuadraticEase

QuadraticEase with graphs of different easingmodes

QuarticEase

QuarticEase with graphs of different easingmodes.

QuinticEase

QuinticEase with graphs of different easingmodes.

SineEase

SineEase for different EasingMode values

注意

PowerEase を使用すると、Power プロパティを使って CubicEaseQuadraticEaseQuarticEase、および QuinticEase と同じ動作を作成できます。 たとえば、PowerEase を使用して CubicEase を置き換える場合は、Power 値 3 を指定します。

ランタイムに含まれるイージング関数を使うだけでなく、EasingFunctionBase から継承することによって独自のイージング関数を作成できます。 次の例では、簡単なカスタム イージング関数を作成する方法を示します。 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>