缓动函数

利用缓动函数可将自定义数学公式应用于动画。 例如,您可能希望某对象真实地弹跳或其行为如同在弹簧上一样。 您可以使用关键帧动画甚至 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:创建使用正弦公式加速和/或减速的动画。

可使用下面的示例查看这些缓动函数的行为。

Run this sample(运行此示例)

若要将缓动函数应用于某一动画,请使用该动画的 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

  • EaseIn:内插遵循与缓动函数相关联的数学公式。

  • EaseOut:内插遵循 100% 内插减去与缓动函数相关联的公式输出。

  • EaseInOut:内插将 EaseIn 用于动画的前半部分,将 EaseOut 用于动画的后半部分。

下图演示了 EasingMode 的不同值,其中 f(x) 表示动画进度,t 表示时间。

BackEase

BackEase EasingMode 图。

BounceEase

BounceEase EasingMode 图。

CircleEase

CircleEase EasingMode 图。

CubicEase

CubicEase EasingMode 图。

ElasticEase

带不同缓动模式图的 ElasticEase。

ExponentialEase

具有不同缓动模式的 ExponentialEase 图。

PowerEase

带不同缓动模式图的 QuarticEase。

QuadraticEase

带不同缓动模式图的 QuadraticEase

QuarticEase

带不同缓动模式图的 QuarticEase。

QuinticEase

带不同缓动模式图的 QuinticEase。

SineEase

不同 EasingMode 值的 SineEase

注意注意

您可以使用 PowerEase 创建与使用 Power 属性的 CubicEaseQuadraticEaseQuarticEaseQuinticEase 的相同的行为。例如,若要使用 PowerEase 替代 CubicEase,请指定 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>