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编程学习——动画
前言 使用动画,是增强用户体验的一种有效的手段.合理的动画,可以让应用程序的界面看起来更加自然.真实.流畅.舒适,更有效地向用户展现信息,用户也更容易接受.同时也增加了软件使用的乐趣,提高用户粘度.( ...
随机推荐
- spring aop配置及用例说明(1)
欢迎转载交流,博客地址http://www.cnblogs.com/shizhongtao/p/3469776.html 首先,什么是aop,其实通俗一点讲就是,再方法执行时候我们加入其它业务逻辑.比 ...
- stl的实现原理简单讲解,通熟易懂
总结 需要经常随机访问请用vector 2.list list就是双向链表,元素也是在堆中存放,每个元素都是放在一块内存中,它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随机存 ...
- C++描述基础算法之直接插入排序
由于此博文并不难,所以并不需要搬出C++特性的这些大山,所以就使用简单的C++代码描述了.^_^ 直接插入排序是一种简单的插入排序法,所以适用于少量数据的排序,直接插入排序是比较稳定的一种排序算法. ...
- vs2008+qt进行开发
第一次接触qt vs,完全小白,网上找资料,各种乱,还大部分是很早以前的,挣扎了好几天终于搞定了, 在此给大家分享. 首先是下载vs2008 (我的项目组项目要求用这个版本),这个比较容易下载:然后是 ...
- html的3要素
在HTML标记语言中可以将每个网页源码分成3部分: 1.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" &q ...
- HTTP 错误 404.2 解决方案
HTTP 错误 404.2 - Not Found 由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面 详细错误:HTTP 错误 404.2 - Not Found ...
- JasperReport原理解析之(一)
1. [加载原始文件]有iReport生成jrxml文件后,由jasperreport包中的类JRXml文件 加载和解析 jrxml文件. 文件解析后生成 JasperDesign对象. Jaspe ...
- HttpClient 建立http连接,https连接,传输数据文件
package com.bluedon.bsmon.http; import java.io.File; import java.nio.charset.Charset; import java.se ...
- 如何使用Git——(一)
一.git与github git 是一款自由和开源的分布式版本控制系统,用于敏捷高效地处理任何或大或小的项目. github 是一个网站,给用户提供git仓库托管服务,是开源代码库以及版本控制系统.在 ...
- sizeof的用法的一些归纳
1 sizeof 是运算符,不是函数 2 sizeof 不能求得void类型的长度,能求得 void*类型的指针的长度 sizeof(void) 会导致编译错误.因为声明一个变量的最重要的作用就是告诉 ...