WPF 生成一个字母L动画(自定义缓动函数)
在学习WPF中老师讲了一个简单有趣的动画:
可以使用结束时间来定位一个字母(当然,也可定位一个汉字、一个图形等等,个人感觉字母最简单(* ̄︶ ̄)所以就用字母)首先你得明白以下几个步骤
创建自定义缓动函数一般需要以下几个步骤:
- 新建一个类,让其继承自EasingFunctionBase类。
- 重写EaseInCore()方法和CreateInstanceCore()方法。
- 定义依赖属性。
- 引用。
xaml代码:
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Canvas.Left)" From="0" To="400" Duration="0:0:5" BeginTime="0:0:6"/>
<DoubleAnimation Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Canvas.Left)" From="240" To="400" Duration="0:0:7" BeginTime="0:0:4"/>
<DoubleAnimation Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Canvas.Left)" From="480" To="400" Duration="0:0:9" BeginTime="0:0:2"/>
<DoubleAnimation Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Canvas.Left)" From="720" To="400" Duration="0:0:11" BeginTime="0:0:0"/>
<DoubleAnimation Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Canvas.Left)" From="240" To="400" Duration="0:0:11" BeginTime="0:0:0"/>
<DoubleAnimation Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Canvas.Left)" From="480" To="400" Duration="0:0:9" BeginTime="0:0:2"/>
<DoubleAnimation Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Canvas.Left)" From="720" To="400" Duration="0:0:7" BeginTime="0:0:4"/>
<DoubleAnimation Storyboard.TargetName="ellipse8" Storyboard.TargetProperty="(Canvas.Left)" From="960" To="400" Duration="0:0:5" BeginTime="0:0:6"/>
<DoubleAnimation Storyboard.TargetName="ellipse9" Storyboard.TargetProperty="(Canvas.Left)" From="720" To="425" Duration="0:0:7" BeginTime="0:0:4"/>
<DoubleAnimation Storyboard.TargetName="ellipse10" Storyboard.TargetProperty="(Canvas.Left)" From="720" To="450" Duration="0:0:7" BeginTime="0:0:4"/>
<DoubleAnimation Storyboard.TargetName="ellipse11" Storyboard.TargetProperty="(Canvas.Left)" From="720" To="475" Duration="0:0:7" BeginTime="0:0:4"/>
<DoubleAnimation Storyboard.TargetName="ellipse12" Storyboard.TargetProperty="(Canvas.Left)" From="720" To="500" Duration="0:0:11">
<DoubleAnimation.EasingFunction>
<!--调用自定义缓动函数类-->
<local:RandomJitterEase EasingMode="EaseIn" Jitter="1500"></local:RandomJitterEase>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Canvas ClipToBounds="True">
<Ellipse Margin="0,0,0,0" Name="ellipse1" Width="25" Height="25" Fill="Violet"/>
<Ellipse Margin="0,25,0,0" Name="ellipse2" Width="25" Height="25" Fill="Violet"/>
<Ellipse Margin="0,50,0,0" Name="ellipse3" Width="25" Height="25" Fill="BlueViolet"/>
<Ellipse Margin="0,75,0,0" Name="ellipse4" Width="25" Height="25" Fill="MediumSpringGreen"/>
<Ellipse Margin="0,100,0,0" Name="ellipse5" Width="25" Height="25" Fill="MediumSpringGreen"/>
<Ellipse Margin="0,125,0,0" Name="ellipse6" Width="25" Height="25" Fill="Violet"/>
<Ellipse Margin="0,150,0,0" Name="ellipse7" Width="25" Height="25" Fill="BlueViolet"/>
<Ellipse Margin="0,175,0,0" Name="ellipse8" Width="25" Height="25" Fill="BlueViolet"/>
<Ellipse Margin="0,175,0,0" Name="ellipse9" Width="25" Height="25" Fill="BlueViolet"/>
<Ellipse Margin="0,175,0,0" Name="ellipse10" Width="25" Height="25" Fill="BlueViolet"/>
<Ellipse Margin="0,175,0,0" Name="ellipse11" Width="25" Height="25" Fill="BlueViolet"/>
<Ellipse Margin="0,175,0,0" Name="ellipse12" Width="25" Height="25" Fill="Red"/>
</Canvas>
Duration :是整个动画执行的时间
BeginTime:代表了开始时的时间
From :元素属性开始值
To :元素属性结束值
Fill :背景颜色
C#代码:
namespace WPFDemo01
{
/// <summary>
/// 自定义缓动函数.xaml 的交互逻辑
/// </summary>
public partial class 自定义缓动函数 : Window
{
public 自定义缓动函数()
{
InitializeComponent();
}
}
public class RandomJitterEase : EasingFunctionBase
{
//声明一个Random类,用于声明随机数。
Random rand = new Random();
/// <summary>
/// 重写EaseCore方法。
/// </summary>
/// <param name="normalizedTime"></param>
/// <returns></returns>
protected override double EaseInCore(double normalizedTime)
{
//几乎所有逻辑代码都在EaseInCore方法中运行。该方法接受一个规范化的时间值,本质上是表示动画进度从
//0到1之间的值,当动画开始时,规范化的时间值是0,它从该点开始增加,直到在动画结束点达到1.
//在动画运行期间,每次更新动画的值时,WPF都会调用EaseInCore方法,确切的调用频率取决于动画的帧率。
if (normalizedTime == 1)
{
return 1;
}
else
{
return Math.Abs(normalizedTime - (double)rand.Next(0, 10) / (2010 - Jitter));
}
}
protected override System.Windows.Freezable CreateInstanceCore()
{
return new RandomJitterEase();
}
//定义一个依赖属性。
public static readonly DependencyProperty JitterProperty;
//在静态方法中注册依赖属性
static RandomJitterEase()
{
JitterProperty = DependencyProperty.Register("Jitter", typeof(int), typeof(RandomJitterEase), new UIPropertyMetadata(1000), new ValidateValueCallback(ValidateJitter));
}
public int Jitter
{
get { return (int)GetValue(JitterProperty); }
set { SetValue(JitterProperty, value); }
}
//此方法用于判断值。
private static bool ValidateJitter(object value)
{
int jitterValue = (int)value;
if (jitterValue <= 2000 && jitterValue >= 0)
{
return true;
}
else
{
return false;
}
}
}
}
刚开始效果:
结束后动画: