缓动函数允许向动画应用自定义数学公式。 例如,你可能希望某个对象以现实方式弹跳或表现得像是处于弹簧上。 可以使用 Key-Frame 甚至 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 动画。 还可以将这些缓动函数应用于 Key-Frame 动画。 下面的示例演示如何使用与它们关联的缓动函数的关键帧来创建一个矩形的动画,该矩形向上收缩、放慢速度、向下展开(好像下降),然后弹跳到停止。
<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 设定三个可能的值如下:
下面的图展示了EasingMode的不同值,其中f(x) 表示动画进度,t 表示时间。
注释
可以使用PowerEase属性来创建与CubicEase、QuadraticEase、QuarticEase和QuinticEase相同的行为,使用Power属性。 例如,如果要用于 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>