WPF其中核心的一个模块就是对于动画的支持,我们知道之前更多人使用的是flash来制作动画,但是现在flash已经不被ios支持,并且众多平台开始排斥flash,但是动画的基本制作是不会变得,就好像最开始的时候,而WPF框架自带动画支持,确实是一个巨大的进步,意味着我们可以在我们的应用程序中构建更复杂,更具有互动性的界面,虽然很多人说只要实现功能就可以,华而不实的东西没什么用,但是我觉得不管是从哪个地方切入,动画是任何一个程序员都要会的东西。
<Grid>
<Button Name="bt1" Content="Button" HorizontalAlignment="Center" VerticalAlignment="Top" Width="50" Click="Button_Click"/>
</Grid>
一个简单的按钮,然后点击按钮,让按钮的宽度变化,就是一个动画效果
DoubleAnimation da = new DoubleAnimation();
da.From = 50;
da.To = this.Width;
da.Duration =TimeSpan.FromSeconds(5);
bt1.BeginAnimation(Button.WidthProperty,da);
当然可以直接在xaml页面中用故事板完成刚刚的动画,这个例子里面动画直接放在了按钮的事件触发器里面。
<Button Content="Button" HorizontalAlignment="Left" Margin="154,121,0,0" VerticalAlignment="Top" Width="75">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard >
<Storyboard >
<DoubleAnimation From="10" To="100" Duration="0:0:5" Storyboard.TargetProperty="Width" >
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
还可以把动画放在资源里面,然后一样的使用样式关联触发器
<Grid>
<Grid.Resources>
<Style x:Key="Mystyle" TargetType="Button">
<Style.Triggers >
<Trigger Property="IsPressed" Value="true">
<Trigger.EnterActions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation From="75" To="200" Duration="0:0:5" Storyboard.TargetProperty="Width"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions >
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Button Content="Button" Style="{StaticResource Mystyle}" HorizontalAlignment="Left" Margin="154,121,0,0" VerticalAlignment="Top" Width="75">
</Button>
</Grid>
通过以上三个例子,理解了这个动画是基于属性的,就是在一定时间内,不断修改动画对应的元素的某一个属性,既然这样,那么要改什么属性,只要去找对应的动画类,前面加了那个属性的数据类型的名字,如果实在没有就自己去实现。
还有一个有点意思的是一个故事板(storyboard)里面可以放多个动画 , 这个例子就是一个圆,不仅top在变,left也在变。
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation From="0" To="300" Duration="0:0:20" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Top)"></DoubleAnimation>
<DoubleAnimation From="0" To="300" Duration="0:0:20" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Left)"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Canvas>
<Ellipse Name="ee" Width="100" Height="100" Fill="Red"></Ellipse>
</Canvas>
</Window>
AutoReverse属性,就是当他是true的时候,动画结束之后会自动反转,fillbehavior属性,是个枚举值,Stop表示动画结束,就会恢复到原来的值,而holdend则是继续保持在动画结束的地方。而这些都是TimeLine类的属性,里面有好多,比如是不是延迟,加速或减速运行动画,包括上面的自动翻转,fillbehavio,repetbehavior等,多用几次我反正是很快就记住了。
控制播放,前面已经接触到了beginstoryboard,还有包括Pausestoryboard,ResumeStoryboard,stopstoryboard,seekstoryboard,setstoryboardspeedratio,skipstoryboardtofill,removestoryboard,看名字就可以大概看出是干什么用的。
下面的例子就阐述了如何控制动画的开始,结束,暂停,恢复和跳转,完全使用的是XAML。
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Triggers>
<EventTrigger SourceName="cmdstart" RoutedEvent="Button.Click">
<BeginStoryboard Name="mybs">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="im1" From="1" To="0" Duration="0:0:10" Storyboard.TargetProperty="Opacity"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="cmdpause" RoutedEvent="Button.Click">
<PauseStoryboard BeginStoryboardName="mybs"></PauseStoryboard>
</EventTrigger>
<EventTrigger SourceName="cmdresume" RoutedEvent="Button.Click">
<ResumeStoryboard BeginStoryboardName="mybs"></ResumeStoryboard>
</EventTrigger>
<EventTrigger SourceName="cmdstop" RoutedEvent="Button.Click">
<StopStoryboard BeginStoryboardName="mybs"></StopStoryboard>
</EventTrigger>
<EventTrigger SourceName="cmdmiddle" RoutedEvent="Button.Click">
<SeekStoryboard BeginStoryboardName="mybs" Offset="0:0:5"></SeekStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<StackPanel>
<Image Name="im1" Height="100" Source="c:\users\hongbo\documents\visual studio 2013\Projects\WpfApplication5\WpfApplication5\Images\Alarm.png"></Image>
<Image Height="100" Source="c:\users\hongbo\documents\visual studio 2013\Projects\WpfApplication5\WpfApplication5\Images\AlarmGroup.png"></Image>
<StackPanel>
<Button Name="cmdstart">开始</Button>
<Button Name="cmdpause">暂停</Button>
<Button Name="cmdresume">恢复</Button>
<Button Name="cmdstop">停止</Button>
<Button Name="cmdmiddle">移到中间</Button>
</StackPanel>
</StackPanel>
</Grid>
</Window>
还有一个就是动画缓动,可以简单理解为为动画增加一些效果,否则动画就是线性地改变某个属性值,不自然弥补生动,但是这个玩意儿我怎么感觉应该交给设计师来做呢?好吧,咱们立志成为full statck,以下实例就是一个缓动函数的应用。
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation AutoReverse="True" From="0" To="300" Duration="0:0:10" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Top)"></DoubleAnimation>
<DoubleAnimation FillBehavior="Stop" From="0" To="300" Duration="0:0:10" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Left)"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Canvas>
<Ellipse Name="ee" Width="100" Height="100" Fill="Red"></Ellipse>
</Canvas>
</Window>