WPF之小动画一
定义动画:
直接使用Element进行BeginAnimation
DoubleAnimation animation = new DoubleAnimation();
animation.By = ;
animation.Duration = TimeSpan.FromSeconds();
btnTest.BeginAnimation(Button.WidthProperty, animation);
也可以将Animation添加到StoryBoard中去,这样可以一次执行多个动画:
Storyboard sb = new Storyboard();
DoubleAnimation animation = new DoubleAnimation();
animation.By = ;
animation.Duration = TimeSpan.FromSeconds();
Storyboard.SetTarget(animation, btnTest);
Storyboard.SetTargetProperty(animation, new PropertyPath("Width"));
sb.Children.Add(animation);
sb.Begin();
我们称Storyboard为动画面板,顾名思义就是专门来执行动画的,可以向其Children中添加多个Animation,这样在Begin的时候就可以执行多个动画。
也可以使用Trigger触发器来触发动画:
<Button Width="200" Height="50" Name="btnTest" Content="动画">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width"
To="{Binding ElementName=window,Path=Width}" Duration="0:0:2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
EventTrigger表示事件触发器,RoutedEvent表示哪个事件的时候触发对应的Action,当前是Button.Click事件,当点击按钮则会执行Storyboard中的动画。在这里使用了一个BeginStoryboard,这样就不用手动对Storyboard调用Begin方法。
在Style中使用触发器Trigger:
FrameElement.Triggers仅支持EventTrigger,还好有其它的触发器可以使用,那就是Styles.Triggers、DataTemplate.Triggers、ControlTemplate.Triggers它们支持属性触发、数据触发以及事件触发。
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="500" Duration="0:0:3"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="200" Duration="0:0:3"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
上述代码是在样式中使用Trigger,Style没有指定Key,仅指定了TargetType,则表示对所有类型应用此样式。在Style中添加IsMouseOver时候的触发器,即当鼠标悬浮时执行,Property表示元素的属性变化,可以是IsPressed或者IsMouseOver等。EnterActions表示鼠标悬浮时候执行,将Width动画执行到500;ExitActions表示鼠标离开时候执行重新将Width设置为原始;然后运行程序鼠标选择则执行Width变大动画,离开则复原。
动画的重叠:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<!-- This Style specifies mouseover and mouseout behaviors. The button gets larger when
the cursor moves over it and smaller when the cursor moves away. Note that the same Properties
(ScaleX and ScaleY) are being targeted by both animations. The BeginStoryboard for each animation
uses a HandoffBehavior of "Compose" which causes the old animation to interpolate more gradually into
the new one. -->
<Style x:Key="ButtonWithCompose" TargetType="{x:Type Button}">
<Setter Property="Button.RenderTransform">
<Setter.Value>
<ScaleTransform CenterX="50" CenterY="50" ScaleX="1" ScaleY="1" />
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleX" To="3" />
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleY" To="3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard HandoffBehavior="Compose">
<Storyboard>
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleX" />
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleY" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
<!-- For this button style, BeginStoryboard uses the default HandoffBehavior of "SnapShotAndReplace" -->
<Style x:Key="ButtonWithSnapShotAndReplace" TargetType="{x:Type Button}">
<Setter Property="Button.RenderTransform">
<Setter.Value>
<ScaleTransform CenterX="50" CenterY="50" ScaleX="1" ScaleY="1" />
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard >
<Storyboard>
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleX" To="3" />
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleY" To="3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleX" />
<DoubleAnimation Duration="0:0:2" Storyboard.TargetProperty="RenderTransform.ScaleY" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Canvas>
<Button Style="{StaticResource ButtonWithSnapShotAndReplace}" Canvas.Top="200" Canvas.Left="200" Width="100" Height="100">
SnapShotAndReplace
</Button>
<Button Style="{StaticResource ButtonWithCompose}" Canvas.Top="200" Canvas.Left="400" Width="100" Height="100">
Compose
</Button>
</Canvas>
</Page>
使用BeginStoryboard的HandoffBehavior 属性进行设置,此属性一共两个值可选;Compose 将通过把新动画追加到组合链的末尾来组合新动画和现有动画;
SnapshotAndReplace 新动画将替换它们所应用到的属性上的任何现有动画。
当鼠标光标移到这两个按钮上时,它们将变大,当鼠标光标移开时,它们将变小。 如果将鼠标移到一个按钮上然后快速移走光标,则在第一个动画完成之前将应用第二个动画。 当两个动画像这样重叠时,您可以看到 Compose 和 SnapshotAndReplace 的 HandoffBehavior 值之间存在差异。 如果值为 Compose,在出现动画重叠时,动画之间的过渡将较为平滑,而如果值为 SnapshotAndReplace,则会使新动画立即取代之前的重叠动画。
注:上文代码来自MSDN
控制动画:
PauseStoryboard 暂停动画;
ResumeStoryboard 恢复暂停的动画;
StopStoryboard 停止动画;
SeekStoryboard 将动画定位到指定位置;
SetStoryboardSpeedRatio 设置动画速度比;
SkipStoryboardToFill 将动画跳转至结束;
RemoveStoryboard 删除动画。
控制动画有两个代码实现方式,一种是使用Trigger一种是通过后置代码实现。
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="MainWindow" Name="window" Height="400" Width="500">
<Window.Triggers>
<EventTrigger SourceName="btnStart" RoutedEvent="Button.Click">
<BeginStoryboard Name="testBeginStory">
<Storyboard Name="testStory">
<DoubleAnimation Storyboard.TargetName="imgDay" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:10">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="btnPause" RoutedEvent="Button.Click">
<PauseStoryboard BeginStoryboardName="testBeginStory"></PauseStoryboard>
</EventTrigger>
<EventTrigger SourceName="btnResume" RoutedEvent="Button.Click">
<ResumeStoryboard BeginStoryboardName="testBeginStory"></ResumeStoryboard>
</EventTrigger>
<EventTrigger SourceName="btnStop" RoutedEvent="Button.Click">
<StopStoryboard BeginStoryboardName="testBeginStory"></StopStoryboard>
</EventTrigger>
<EventTrigger SourceName="btnSeek" RoutedEvent="Button.Click">
<SeekStoryboard BeginStoryboardName="btnSeek" Offset="0:0:5"></SeekStoryboard>
</EventTrigger>
</Window.Triggers>
<StackPanel>
<Grid>
<Image Source="night.jpg" Width="400" Height="300" Stretch="Fill"></Image>
<Image Source="day.jpg" Name="imgDay" Width="400" Height="300" Stretch="Fill"></Image>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="开始" Height="30" Width="50" Name="btnStart" Margin="5"></Button>
<Button Content="暂停" Height="30" Width="50" Name="btnPause" Margin="5"></Button>
<Button Content="继续" Height="30" Width="50" Name="btnResume" Margin="5"></Button>
<Button Content="停止" Height="30" Width="50" Name="btnStop" Margin="5"></Button>
<Button Content="跳转至中间" Height="30" Width="70" Name="btnSeek" Margin="5"></Button>
</StackPanel>
</StackPanel>
</Window>
代码中有两个图片,一个是白天,一个是黑夜。通过动画修改白天图片的透明度一直到0,然后显示黑夜的图片,这是一个完整的动画。
在Windows.Triggers中放置了五个事件触发器,分别对应五个按钮,通过设置EventTrigger的SourceName为按钮的名称,RoutedEvent同样为Click事件,在每一个EventTrigger中放置对应的Storyboard的操作,每个Storyboard操作的BeginStoryboardName就是BeginStory的Name。有一个特殊就是SeekStory中的Offset表示将动画定位到指定的偏移量,也就是指定的动画时间点。
通过后置代码实现的方式是使用StoryBoard的方法进行实现,大家可以查询MSDN。
注:虽然我们可以去操作动画,但是当动画开始之后属性是无法直接修改的,比如速度比,这些属性都是在XAML中配置的,所以如果我们修改了这个属性也是无效的,好在有对应的函数可以调用
修改上述代码片段,在外层StackPanel中添加一个Slider,用于控制速度比。
<Slider Grid.Column="1" Name="sldSpeed"
Minimum="0" Maximum="3" Value="1" TickPlacement="BottomRight" TickFrequency="0.1"
ValueChanged="sldSpeed_ValueChanged_1"></Slider>
private void sldSpeed_ValueChanged_1(object sender, RoutedPropertyChangedEventArgs<double> e)
{
testStory.SetSpeedRatio(this, sldSpeed.Value);
}
testStory为Storyboard对象,使用SetSpeedRatio设置速度比,第一个参数为动画的最高层容器,当前就是窗体所以是this,第二个就是一个double的值,当前使用的是silder的value。
监视动画过程:
通过专门的方法得到动画的当前执行时间(动画的整个Duration)和当前的进度(0--1),详情见下文。
Storyboar的事件:
Completed | 动画完成 |
CurrentGlobalSpeedInvalidated | 暂停、继续、反转、加速、减速、查找、停止或更改时钟的交互速度可触发此事件 |
CurrentStateInvalidated | 当状态发生变化的时候发生(启动、停止或填充时) |
CurrentTimeInvalidated | 当执行时间点发生变化时触发 |
RemoveRequested | 当动画被移除 |
在此例子中我们要使用到的事件是CurrentTimeInvalidated,当时间点变化就触发此事件。首先,我们继续修改XAML代码添加一个Label和一个ProgressBar,Label显示当前的时间,ProgressBar显示进度。代码修改如下:
<Label Name="lblTime" HorizontalContentAlignment="Center"></Label>
<ProgressBar Name="progressbar" Height="30" Margin="0 5 0 0" Minimum="0" Maximum="1"></ProgressBar>
事件代码如下:
private void testStory_CurrentTimeInvalidated_1(object sender, EventArgs e)
{
Clock storyboardeClock = sender as Clock;
if (storyboardeClock.CurrentProgress == null)
{
lblTime.Content = "[Stop]";
progressbar.Value = ;
}
else
{
lblTime.Content = storyboardeClock.CurrentTime.ToString();
progressbar.Value = storyboardeClock.CurrentProgress.Value;
}
}
事件的第一个参数sender为Clock对象,表示TimeLine类型的运行时间状态。通过GetCurrentTime()和GetCurrentProgress()得到当前动画的执行点和当前动画的执行进度。
WPF之小动画一的更多相关文章
- WPF之小动画三
如果前两篇的博客太为普通,那么接下来的内容将让你动画实在是太厉害了.本文将会介绍两个关于纯手工实现动画的形式,当然动画效果就不用我多说了. 基于帧的动画: 此处的帧并不是之前介绍的Animation这 ...
- WPF之小动画二
上一篇文章简单介绍了动画的定义方法和一些控制动画的方法,并没有涉及复杂属性的动画处理方式,本文将继续动画的其它方面的使用. 写在前面(对于一些动画操作时候的建议): 1.如果希望某个元素从显示到消失, ...
- WPF 有趣的动画效果
WPF 有趣的动画效果 这一次我要呈上一个简单的文章,关于给你的WPF apps加入美丽的光线动画,可是我对动画这东西可能有点入迷了. 实际上.我对动画如此的入迷,以至 ...
- WPF特效-粒子动画
原文:WPF特效-粒子动画 WPF实现泡泡龙小游戏效果. /// -Ball to Ball Collision - Detection and Handling /// http:// ...
- WPF中的动画——(三)时间线(TimeLine)
WPF中的动画——(三)时间线(TimeLine) 时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下 ...
- CSS3-实现单选框radio的小动画
在微信上看到一个教程文,觉得制作的小动画还是很有意思的,自己也试验了一下.一开始动画怎么都不执行(我用的HB),因为内置浏览器对css3的不兼容.加上各种浏览器前缀后就好了.但是旋转那个效果,在HB里 ...
- TabbarItem超炫小动画
本文转载自 不灭的小灯灯 的博客 Tabbar点击时候超炫小动画 感谢这位大神的分享! 对UITabBarController上TabBar按钮动画详细介绍-->>保证你有意外收获,如有 ...
- 如何制作网页小动画?——gif or png
一.场景与动画 为了拉动网站氛围,或者吸引用户浏览焦点,需要使用一些小动画.这种动画不是(gif)单纯的重复,而是需要需要一些控制和交互,比如在动画完成后打开一个对话框.动画有几个基本要素(时间控制, ...
- WPF编程学习——动画
前言 使用动画,是增强用户体验的一种有效的手段.合理的动画,可以让应用程序的界面看起来更加自然.真实.流畅.舒适,更有效地向用户展现信息,用户也更容易接受.同时也增加了软件使用的乐趣,提高用户粘度.( ...
随机推荐
- c#索引器的简单用法
abstract class Bird { protected string name; public abstract string Name { get; set; } public abstra ...
- ubuntu 阿里云安全配置
1. 添加新用户, 加入 root 组, 赋予 sudo 权限 2. 禁用 root 3.
- iOS 非ARC基本内存管理系列 4-autorelease方法和@autoreleasepool
1.autorelease 基本用法 对象执行autorelease方法时会将对象添加到自动释放池中 当自动释放池销毁时自动释放池中所有对象作release操作 对象执行autorelease方法后自 ...
- mysql的时间函数
from_unixtime()是MySQL里的时间函数 date为需要处理的参数(该参数是Unix 时间戳),可以是字段名,也可以直接是Unix 时间戳字符串 后面的 '%Y%m%d' 主要是将返回值 ...
- ng-src作用
... <ul class="phones"> <li ng-repeat="phone in $ctrl.phones | filter:$ctrl. ...
- DTCMS自定义标签,tags分割
DTcms.Web.UI\Label\article.cs /// <summary> /// 自定义:分割tags /// </summary> /// <param ...
- 关于html的下载功能
新项目基本告一段落,第一次完成前后端分离的集成,遇到的坑自然不少. 来说说第一天遇到的其中一个坑吧. ——关于下载的问题... 以前的做法,大家都喜爱用<a></a>标签吧.而 ...
- asp:HyperLink vs asp:LinkButton
asp:HyperLink NavigateUrl - 页面刷新为新的页面 pageload ispostback = false asp:LinkButton PostbackUrl - postb ...
- 四个基数任意次数组合相加得到一个数N,求所有可能组合
#include <iostream> #include <vector> usingnamespace std; vector<int> vec; constin ...
- poj 3641 Pseudoprime numbers Miller_Rabin测素裸题
题目链接 题意:题目定义了Carmichael Numbers 即 a^p % p = a.并且p不是素数.之后输入p,a问p是否为Carmichael Numbers? 坑点:先是各种RE,因为po ...