精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。
最近开发大屏软件,发现例子里面的动画非常酷,找了些codeproject上面的文章,翻译学习下,也给大家共享下。例子里的效果比本文的效果好上百倍,有兴趣要例子联系锐英源软件。
WPF 中的动画变得更容易,因为 WPF 通过修改元素的属性来实现动画,而在 Windows 窗体中,开发人员必须创建一个计时器并在计时器的滴答事件上修改元素的外观。WPF 使用自己的计时系统,可以使用托管代码和 XAML 编写。重绘屏幕的内部工作由 WPF 高效处理。使用 WPF 进行动画制作时,您只需专注于想要创建的效果,而无需担心如何实现这些效果。
注:从这点来看,WPF的界面底层机制比Winform要强大且复杂,有点UI和逻辑完全分离的味道。
为了演示这一点,我创建了一个挥舞旗帜动画,它使用一系列按顺序显示的图像。
WPF 通过动画元素属性来实现动画。例如,如果您想为矩形生成放大或缩小效果,您可以为宽度和高度属性设置动画。以下代码通过修改其宽度和高度属性来为矩形设置动画。
<Rectangle Name="myrect" Width="1" Height="1">
<Rectangle.Fill>
<SolidColorBrush Color="Red"/>
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Width" From="1" To="350"
Duration="0:0:1" BeginTime="0:0:0"/>
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Height" From="1" To="250"
Duration="0:0:1" BeginTime="0:0:1"/>
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Height" From="250"
To="1" Duration="0:0:1" BeginTime="0:0:2"/>
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Width" From="350" To="1"
Duration="0:0:1" BeginTime="0:0:3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
此代码在加载窗口时自动触发动画。代码EventTrigger向矩形添加一个。该BeginStoryboard动作运行一个故事板。该故事板使用四个DoubleAnimations。第一个DoubleAnimation将矩形的宽度从 1 增加到 350。第二个将高度从 1 增加到 250。第三个和第四个通过将高度和宽度减小回 1 来执行相反的操作。使四个DoubleAnimations 运行在一个通过设置属性来排序,BeginTime使得每个动画在前一个结束时开始。Storyboard的RepeatBehavior属性被赋值为“ Forever”,这使得动画无限期地运行。
可以从代码隐藏中控制动画,方法是创建一个故事板作为窗口资源并使用以下 TryFindResource方法在代码中定位它:
Storyboard s = (Storyboard)TryFindResource( " sb" );
以下是创建 Storyboard 资源的代码:
<Window.Resources>
<Storyboard x:Key="sb" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Width" From="1" To="350"
Duration="0:0:1" BeginTime="0:0:0"/>
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Height" From="1" To="250"
Duration="0:0:1" BeginTime="0:0:1"/>
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Height" From="250" To="1"
Duration="0:0:1" BeginTime="0:0:2"/>
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Width" From="350" To="1"
Duration="0:0:1" BeginTime="0:0:3"/>
</Storyboard>
</Window.Resources>
以下是以编程方式控制动画的代码:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void btnStart_Click(object sender, RoutedEventArgs e) { // Locate Storyboard resource Storyboard s = (Storyboard)TryFindResource("sb"); s.Begin(); // Start animation } private void btnStop_Click(object sender, RoutedEventArgs e) { Storyboard s = (Storyboard)TryFindResource("sb"); s.Stop(); // Stop animation } private void btnPause_Click(object sender, RoutedEventArgs e) { Storyboard s = (Storyboard)TryFindResource("sb"); s.Pause(); // Pause animation } private void btnResume_Click(object sender, RoutedEventArgs e) { Storyboard s = (Storyboard)TryFindResource("sb"); s.Resume(); // Resume animation } }
可以使用以下属性创建淡入和淡出动画效果Opacity:
<Rectangle Name="myrect" Width="350" Height="250">
<Rectangle.Fill>
<SolidColorBrush x:Name="brush" Color="Red"/>
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="myrect"
Storyboard.TargetProperty="Opacity" From="0" To="1"
Duration="0:0:1" BeginTime="0:0:0" AutoReverse="True"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
上面的代码将矩形的不透明度从 0(完全透明)更改为 1(完全不透明)。
我们可以使用ColorAnimation动画Color矩形的属性。以下是生成彩色动画的代码:
<Rectangle Name="myrect" Width="350" Height="250">
<Rectangle.Fill>
<SolidColorBrush x:Name="brush" Color="Red"/>
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<ColorAnimation Storyboard.TargetName="brush"
Storyboard.TargetProperty="Color" From="Red" To="Green"
Duration="0:0:1" BeginTime="0:0:0"/>
<ColorAnimation Storyboard.TargetName="brush"
Storyboard.TargetProperty="Color" From="Green" To="Blue"
Duration="0:0:1" BeginTime="0:0:1"/>
<ColorAnimation Storyboard.TargetName="brush"
Storyboard.TargetProperty="Color" From="Blue" To="Yellow"
Duration="0:0:1" BeginTime="0:0:2"/>
<ColorAnimation Storyboard.TargetName="brush"
Storyboard.TargetProperty="Color" From="Yellow"
To="Red" Duration="0:0:1" BeginTime="0:0:3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
此代码使用四个ColorAnimations 来更改矩形的颜色。通过使用该BeginTime属性来控制颜色变化的时间。
ColorAnimation也可用于创建渐变动画。以下代码可用于此:
<Rectangle Name="myrect" Width="350" Height="250">
<Rectangle.Fill>
<LinearGradientBrush x:Name="brush" StartPoint="0,0" EndPoint="1,1">
<GradientStop x:Name="stop1" Offset="0" Color="Red"/>
<GradientStop x:Name="stop2" Offset="0.5" Color="Green"/>
<GradientStop x:Name="stop3" Offset="1" Color="Blue"/>
</LinearGradientBrush>
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<ColorAnimation Storyboard.TargetName="stop1" Storyboard.TargetProperty="Color"
From="Red" To="Green" Duration="0:0:1" BeginTime="0:0:0"/>
<ColorAnimation Storyboard.TargetName="stop1" Storyboard.TargetProperty="Color"
From="Green" To="Blue" Duration="0:0:1" BeginTime="0:0:0.5"/>
<ColorAnimation Storyboard.TargetName="stop1" Storyboard.TargetProperty="Color"
From="Blue" To="Red" Duration="0:0:1" BeginTime="0:0:1"/>
<ColorAnimation Storyboard.TargetName="stop2" Storyboard.TargetProperty="Color"
From="Green" To="Blue" Duration="0:0:1" BeginTime="0:0:0"/>
<ColorAnimation Storyboard.TargetName="stop2" Storyboard.TargetProperty="Color"
From="Blue" To="Red" Duration="0:0:1" BeginTime="0:0:0.5"/>
<ColorAnimation Storyboard.TargetName="stop2" Storyboard.TargetProperty="Color"
From="Red" To="Green" Duration="0:0:1" BeginTime="0:0:1"/>
<ColorAnimation Storyboard.TargetName="stop3" Storyboard.TargetProperty="Color"
From="Blue" To="Red" Duration="0:0:1" BeginTime="0:0:0"/>
<ColorAnimation Storyboard.TargetName="stop3" Storyboard.TargetProperty="Color"
From="Red" To="Green" Duration="0:0:1" BeginTime="0:0:0.5"/>
<ColorAnimation Storyboard.TargetName="stop3" Storyboard.TargetProperty="Color"
From="Green" To="Blue" Duration="0:0:1" BeginTime="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
上面的代码最初创建了一个具有红色、绿色和蓝色线性渐变的矩形。然后它为每个渐变设置动画以更改其颜色。
我创建了一个显示动画印度国旗的应用程序。应用程序的完整 XAML 代码如下:
<Window x:Class="AnimatedFlag.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Indian Flag" Height="350" Width="525">
<Grid>
<Image Name="flagImage" Margin="12">
<Image.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Name="da" Storyboard.TargetName="flagImage"
Storyboard.TargetProperty="Width" From="200" To="200"
Duration="0:0:0.1" Completed="DoubleAnimation_Completed"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
</Window>
此代码创建一个虚拟动画。我称它为虚拟动画,因为它实际上并没有改变任何属性。该<DoubleAnimation>元素仅使用Width图像的属性,但From和To属性的值相同(200)。Duration属性将动画持续时间指定为 0.1 秒。它使用Completed事件处理程序在完成后重新启动动画。隐藏代码如下:
public partial class MainWindow : Window { int ctr = 1; public MainWindow() { InitializeComponent(); } private void DoubleAnimation_Completed(object sender, EventArgs e) { ShowImage(); // Display Image da.BeginAnimation(Image.WidthProperty, da); // Start Animation } private void ShowImage() { string filename = "Images/Flag" + ctr + ".jpg"; BitmapImage image = new BitmapImage(); image.BeginInit(); image.UriSource = new Uri(filename, UriKind.Relative); image.EndInit(); flagImage.Source = image; ctr++; if (ctr > 6) { ctr = 1; // Display first image after the last image } } }
在上面的代码中,DoubleAnimation_Completed事件处理程序调用该ShowImage()函数依次显示六张图像。它使用DoubleAnimation类的 BeginAnimation()方法来重新启动动画。该BeginAnimation 方法的第一个参数Image.WidthProperty是 DependencyProperty。第二个参数是AnimationTimeline对象。