イージング関数
イージング関数では、独自の数式をアニメーションに適用できます。 たとえば、物体が自然に弾んだり、ばねが付いているような動きを与えることができます。 それに近い効果は、キー フレーム アニメーションや From/To/By アニメーションを使用して実現することもできますが、かなりの労力が伴ううえ、数式を使った場合に比べると、動きが不自然になる場合があります。
EasingFunctionBase を継承して独自のカスタム イージング関数を作成する以外にも、ランタイムに標準で備わっているいずれかのイージング関数を使用して、基本的な効果を作成できます。
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% の補間からイージング関数に関連付けられている数式の出力結果を差し引き、それに基づいて補間します。
次の図は、EasingMode のそれぞれの値の特徴をグラフで示したものです。f(x) は、アニメーションの進行を、t は時間を表します。
メモ |
---|
PowerEase の Power プロパティを使用して、CubicEase、QuadraticEase、QuarticEase、および QuinticEase と同じ動作を作成することができます。たとえば、CubicEase を PowerEase で代用するには、Power の値に 3 を指定します。 |
ランタイムに含まれているイージング関数を使用することに加え、EasingFunctionBase を継承することによって、独自のカスタム イージング関数を作成することもできます。 次の例は、簡単なカスタム イージング関数を作成する方法を示しています。 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>