WPF中创建一个矩形圆角动画
WPF
中内置了好几种动画,大多数场景可以坐到开箱即用,不过并没有内置 CornerRadiusAnimation
,本文将会介绍怎么实现一个 CornerRadiusAnimation
动画,实现 Border
的 CornerRadius
属性动画效果。
动画类 CornerRadiusAnimation
在 WPF
中,所有的动画都是继承于 AnimationTimeline
类型,我们自定义的 CornerRadiusAnimation
类也应该继承于该类。
public class CornerRadiusAnimation : AnimationTimeline
{
}
照猫画虎,在动画中,我们需要定义一个 From
,一个 To
,用来表示动画的初始状态和结束状态,我们的动画是应用于 CornerRadius
属性,那 From
和 To
都应该是 CornerRadius
类型。然后注册对应的依赖属性,用于在 xaml
中进行绑定。
public CornerRadius From
{
get => (CornerRadius)GetValue(FromProperty);
set => SetValue(FromProperty, value);
}
public static readonly DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(CornerRadius), typeof(CornerRadiusAnimation));
public CornerRadius To
{
get => (CornerRadius)GetValue(ToProperty);
set => SetValue(ToProperty, value);
}
public static readonly DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(CornerRadius), typeof(CornerRadiusAnimation));
接下来,我们要对基类的属性和方法进行重写, TargetPropertyType
属性用来定义我们的动画需要作用的类型,CreateInstanceCore()
方法实现了创建动画实例,GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
方法实现了当前的值,在动画播放时会被重复调用,达到动画效果。
public override Type TargetPropertyType => typeof(CornerRadius);
public override Freezable CreateInstanceCore(){
return new CornerRadiusAnimation();
}
public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
{
if(animationClock.CurrentProgress == null)
{
return From;
}
double progress = animationClock.CurrentProgress.Value;
return new CornerRadius(
From.TopLeft + (To.TopLeft = From.TopLeft) * progress,
From.TopRight + (To.TopRight = From.TopRight ) * progress,
From.BottomRight + (To.BottomRight = From.BottomRight ) * progress,
From.BottomLeft + (To.BottomLeft = From.BottomLeft ) * progress
);
}
使用
XAML
在 xaml
中定义一个 Border
控件,设置初始状态下的 CornerRadius
属性值,在资源中引入我们写好的 CornerRadiusAnimation
,设置 From
和 To
属性值,这里设置为 0 和 30,预期结果是 Border
控件的会从直角矩形慢慢变成圆角矩形。
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Storyboard x:Key="CornerRadiusAnimation">
<local:CornerRadiusAnimation Storyboard.TargetProperty="(Border.CornerRadius)"
Storyboard.TargetName="MyBorder"
From="0,0,0,0" To="30,30,30,30"
Duration="0:0:2" />
</Storyboard>
</Window.Resources>
<Grid>
<Border x:Name="MyBorder" Width="200" Height="200" Background="LightBlue" CornerRadius="0,0,0,0">
</Border>
<Button Content="播放" Margin="0,0,0,20" Click="Button_Click"/>
</Grid>
</Window>
C#
在窗体的后台代码中,我们来实现 Button_Click
事件,在事件中调用动画对象的 Begin()
方法进行播放。
using System.Windows;
using System.Windows.Media.Animation;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Storyboard sb = (Storyboard)this.Resources["CornerRadiusAnimation"];
sb.Begin();
}
}
}