基于C#WPF框架——动画
WPF提供了一个更高级的模型,通过该模型可以只关注动画的定义,而不必考虑它们的渲染方式。这个模型基于依赖项属性基础架构。本质上,WPF动画只不过是在一段时间间隔内修染方式。这个模型基于依赖项属性基础架构。本质上,WPF动画只不过是在一段时间间隔内修改依赖项属性值的一种方式。
尽管目前WPF可为动画使用三种方法(线性插值、关键帧以及路径),但完全也可以创建更多的使用完全不同的方式来修改值的动画类.唯一要求是自定义的动画类必须根据时间修改值。
多的使用完全不同的方式来修改值的动画类.唯一要求是自定义的动画类必须根据时间修改值。
Animation 类
所有动画类都以“类型名+Animation”方式命名。这种观点很接近实际情况,但不是非常准确。
- 17个“类型名+Animation”类,这些类使用插值。
- 22 个“类型名+AnimationUsingKeyFrames"类,这些类使用关键帧动画。
- 3个“类型名+AnimationUsingPath"类,这些类使用基于路径的动画。
所有这些动画类都继承自抽象的“类型名+AnimationBase”类,这些基类实现了一些基本功能,从而为创建自定义动画类提供了快捷方式。如果某个数据类型支持多种类型的动画,那么所有的动画类都继承自抽象的动画基类。
这42个类并不是System.Windows.Media.Animation名称空间中的唯- -内容。每个关键帧动画还使用自己的关键帧类和关键帧集合类,这两部分类会导致一些混乱。 总之,在System.Windows.Media.Animation名称空间中有100多个类。
| BooleanAnimationUsingKeyFrames | ByteAnimation |
|---|---|
| ByteAnimationUsingKeyFrames | CharAnimationUsingKeyFrames |
| ColorAnimation | ColorAnimationUsingKeyFrames |
| DecimalAnimation | DecimalAnimationUsingKeyFrames |
| DoubleAnimation | DoubleAnimationUsingKeyFrames |
| DoubleAnimationUsingPath | Int16Animation |
| Intl 6AnimationUsingKeyFrames | Int32Animation |
| Int32AnimationUsingKeyFrames | Int64Animation |
| Int64AnimationUsingKeyFrames | MatrixAnimationUsingKeyFrames |
| MatrixAnimationUsingPath | ObjectAnimationUsingKeyFrames . |
| PointAnimation | PointAnimationUsingKeyFrames |
| PointAnimationUsingPath | Point3DAnimation |
| Point3DAnimationUsingKeyFrames | QuarternionAnimation |
| QuarternionAnimationUsingKeyFrames | RectAnimation |
| RectAnimationUsingKeyFrames | Rotation3DAnimation |
| Rotation3DAnimationUsingKeyFrames | SingleAnimation |
| SingleAnimationUsingKeyFrames | SizeAnimation |
| SizeAnimationUsingKeyFrames | StringAnimationUsingKeyFrames |
| ThicknessAnimation | ThicknessAnimationUsingKeyFrames |
| VectorAnimation | VectorAnimationUsingKeyFrames |
| Vector3DAnimation | Vector3DAnimationUsingKeyFrames |
这42个类开不是System. Windows.Media.Animation名称空间中的唯一内 谷.每个关键帧动画
还使用自己的关键帧类和关键帧集合类,这两部分类会导致一些混乱。总之,在System.Windows.
Media.Animation名称空间中有100多个类。
任何使用线性插值的动画最少需要三个细节:
开始值(From)、结束值(To)和整个动画执行的时间(Duration)。
即使不使用To属性,也可以使用By属性。By属性用于创建按设置的数量改变值的动画,而不是按给定目标改变值。
可结合使用By和From属性,但这并不会减少任何工作. By值被简单地增加到From值上,使其达到To值。
大部分使用插值的动画类通常都提供了By属性,但并非全部如此。例如,对于非数值数据类型来说,By 属性是没有意义的,比如ColorAnimation类使用的Color结构。
另有一种方法可得到类似的行为,而不需要使用By属性一可通 过设置IsAdditive属性创建增加数值的动画。当创建这种动画时,当前值被自动添加到From值和To值。
动画的生命周期
单向动画(如增长按钮的动画)在运行结束后会保持处于活动状态,这是因为动画需要将按钮的宽度保持为新值。这会导致如下不常见的问题一如 果尝试使用代码在动画完成后修改属性值,代码将不起作用。因为代码只是为属性指定了一个新的本地值,但仍会优先使用动画之后的属性值。
根据准备完成的工作,可通过如下几种方法解决这个问题:
● 创建将元素 重新设置为原始状态的动画。可通过创建不设置To属性的动画达到该目的。
例如,将按钮的宽度减小到最后设置的尺寸的按钮缩小动画,之后就可以使用代码改变该属性了。
●创建可翻转的动画。通过将AutoReverse属性设置为true 来创建可翻转的动画。例如,当按钮增-长动画不再增加按钮的宽度时,将反向播放动画,返回到原始宽度。动画的总持续时间也将翻倍。
●改变FillBehavior属性。通常,FillBehavior 属性被设置为HoldEnd,这意味着当动画结束时,会继续为目标元素应用最后的值。如果将FillBehavior 属性改为Stop,只要动画结束,属性就会恢复为原来的值。
●当动画完成时通过处理动画对象的Completed事件删除动画对象。
前3种方法改变了动画的行为。不管使用哪种方法,它们都将动画后的属性设置为原来的数值。如果这并非所希望的,那就需要使用最后-种方法。
首先,在启动动画前,关联事件处理程序以响应动画完成事件:
widthAnimation. Completed += animation_ Completed;
注意:
Completed事件是常规的.NET事件,使用常规的没有附加信息的EventArgs 对象。该事件不是路由事件。
Timeline类
| 名称 | 说明 |
|---|---|
| BeginTime | 设置将被添加到动画开始之前的延迟时间(TimeSpan类型)。这一-延迟时间被加到总时间,所以具有5秒延迟的5秒动画,总时间是10秒。当同步在同一时间开始,但按顺序应用效果的不同动画时,BeginTime 属性是很有用的 |
| Duration | 使用Duration对象设置动画从开始到结束的运行时间 |
| SpeedRatio | 提高或减慢动画速度。通常,SpeedRatio 属性值是1。如果增加该属性值,动画会加快(例如,如果SpeedRatio属性的值为5,动画的速度会变为原来的5倍);如果减小该属性值,动画会变慢(例如,如果SpeedRatio属性的值为0.5,动画时间将变为原来的两倍)。可通过改变动画的Duration属性值得到相同结果。当应用BeginTime 延迟时,不考虑SpeedRatio属性的值 |
| AccclerationRatio;DecelerationRatio | 使动画不是线性的,从而开始时较慢,然后增速(通过增加AcelerationRatio 属性值):或者结束时降低速度(通过增加DecelerationRatio属性值)。这两个属性的值都在0~1之间,并且开始时都设置为0。此外,这两个属性值之和不能超过1 |
| AutoReverse | 如果为true,当动画完成时会自动反向播放,返回到原始值。这也会使动画的运行时间加倍。如果增加SpeedRatio属性值,就会应用到最初的动画播放以及反向的动画播放。BeginTime属性值只应用于动画的开始一不 延迟反向动画 |
| FillBehavior | 决定当动结束时如何操作。通常,可将属性值保持为固定的结束值(FillBchavior. HoldEnd),但是也可选择将属性值返回为原来的数(FillBehavior Stop) |
| RepeatBehavior | 通过该属性,可以使用指定的次数或时间间隔重复动画。用于设置这个属性的RepeatBehavior对象决定了确切的行为 |
故事板
在所有声明式动画中都会用到如下两个要素:
故事板: 故事板是BeginAnimation( )方法的XAML等价物。通过故事板将动画指定到合适的元素和属性。
事件触发器: 事件触发器响应属性变化或事件(如按钮的Click事件),并控制故事板。例如,为了开始动画,事件触发器必须开始故事板。
小案例:

以上小案例为点单击按钮时,原形先向右移动到达To值后继续向左移动,矩形向右下角移动,当到达To值后原路返回向左上角移动,此动画为重复执行动画
首先需要引入动画类命名空间;
using System.Windows.Media.Animation;
创建故事板:
Storyboard sto = new Storyboard(); // 故事板
Storyboard stt = new Storyboard(); // 向下故事板
初始化图形大小,位置:
Border bod = new Border(); // 圆形
bod.Width = 100;
bod.Height = 100;
bod.BorderThickness =new Thickness(10); // 设置原形边框厚度
bod.BorderBrush = Brushes.Yellow; // 边框颜色
bod.Background = Brushes.Purple; // 圆形背景色
bod.CornerRadius = new CornerRadius(50); // 画圆
BG.Children.Add(bod);
Border boo = new Border(); // 矩形
boo.Width = 100;
boo.Height = 100;
boo.Background = Brushes.Cyan;
Canvas.SetLeft(boo, 100);
Canvas.SetTop(boo, 300);
boo.CornerRadius = new CornerRadius(20);
BG.Children.Add(boo);
动画情节:
DoubleAnimation move = new DoubleAnimation(); // 移动情节
move.From = 0; // 初始值
move.To = 400; // 结束值
move.Duration = new Duration(new TimeSpan(0, 0, 0, 3, 0)); // 需要的时间
move.AutoReverse = true; // 设置成返回
move.RepeatBehavior = RepeatBehavior.Forever; // 重复执行
Storyboard.SetTarget(move,bod); // 情节添加给对象
//Storyboard.SetTargetProperty(move, new PropertyPath(Canvas.LeftProperty)); // 改变lef位置
Storyboard.SetTargetProperty(move, new PropertyPath("(Canvas.Left)"));
sto.Children.Add(move);
ColorAnimation bianSe = new ColorAnimation(Colors.Purple,Colors.Orange,TimeSpan.FromMilliseconds(300)); // 改背景色情节
Storyboard.SetTarget(bianSe, bod);
Storyboard.SetTargetProperty(bianSe, new PropertyPath("(Border.Background).(SolidColorBrush.Color)"));
sto.Children.Add(bianSe);
ColorAnimation biankuSe = new ColorAnimation(Colors.Blue, Colors.DarkViolet,TimeSpan.FromSeconds(3)); // 改变边框颜色
Storyboard.SetTarget(biankuSe, bod);
Storyboard.SetTargetProperty(biankuSe, new PropertyPath("(Border.BorderBrush).(SolidColorBrush.Color)"));
sto.Children.Add(biankuSe);
ThicknessAnimation kuang=new ThicknessAnimation(new Thickness(10),new Thickness(20),TimeSpan.FromMilliseconds(30)); // 改变边框厚度
Storyboard.SetTarget(kuang, bod);
Storyboard.SetTargetProperty(kuang, new PropertyPath("BorderThickness"));
sto.Children.Add(kuang);
DoubleAnimation zhuan = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(3))); // 旋转情节
Storyboard.SetTarget(zhuan, bod);
zhuan.AutoReverse = true;
zhuan.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTargetProperty(zhuan, new PropertyPath("RenderTransform.Angle"));
sto.Children.Add(zhuan);
RotateTransform xuanZhuan = new RotateTransform(); // 旋转对象
bod.RenderTransform = xuanZhuan;
bod.RenderTransformOrigin = new Point(0.5,0.5);
// 控制boo 向下移动并 旋转
DoubleAnimation yidong = new DoubleAnimation();// 移动右
yidong.From = 0;
yidong.To = 500;
yidong.Duration = new Duration(TimeSpan.FromSeconds(3)); // 设置毫秒数
yidong.AutoReverse = true; // 返回原路
yidong.RepeatBehavior = RepeatBehavior.Forever; // 重复执行
Storyboard.SetTarget(yidong, boo);
Storyboard.SetTargetProperty(yidong, new PropertyPath("(Canvas.Left)"));
stt.Children.Add(yidong);
DoubleAnimation yidong_ = new DoubleAnimation(Canvas.GetTop(boo),(Canvas.GetTop(boo)+400),new Duration(TimeSpan.FromSeconds(3))); // 移动下
yidong_.AutoReverse = true;
yidong_.RepeatBehavior = RepeatBehavior.Forever;
Storyboard.SetTarget(yidong_, boo);
Storyboard.SetTargetProperty(yidong_,new PropertyPath("(Canvas.Top)"));
stt.Children.Add(yidong_);
DoubleAnimation xiazhuan = new DoubleAnimation(0, 360, new Duration(TimeSpan.FromSeconds(3))); //旋转情节
Storyboard.SetTarget(xiazhuan, boo);
xiazhuan.AutoReverse = true; //可原路返回
xiazhuan.RepeatBehavior = RepeatBehavior.Forever;// 重复执行
Storyboard.SetTargetProperty(xiazhuan, new PropertyPath("RenderTransform.Angle"));
stt.Children.Add(xiazhuan);
RotateTransform xuanzhuan = new RotateTransform(); // 旋转对象
boo.RenderTransform = xuanzhuan;
boo.RenderTransformOrigin = new Point(0.5, 0.5);
点击按钮:
private void btn_Click(object sender, RoutedEventArgs e)
{
sto.Begin(); // 开启动画
stt.Begin();
}
基于C#WPF框架——动画的更多相关文章
- 基于C# WPF框架的贪吃蛇
游戏开始界面 游戏开始 共有两条蛇,吃到红色食物加1分,吃到绿色毒食物减1分,知道0不减: 碰到墙壁游戏结束,碰到对方游戏结束,碰到自己游戏结束 此游戏通过Canvas画布布局,通过C#代码实现 游戏 ...
- 一个基于Net Core3.0的WPF框架Hello World实例
目录 一个基于Net Core3.0的WPF框架Hello World实例 1.创建WPF解决方案 1.1 创建Net Core版本的WPF工程 1.2 指定项目名称,路径,解决方案名称 2. 依赖库 ...
- wpf 创建动画三种方式
动画类型 : 故事版,CompositionTarget,DispachTime 那么到此,三种动态创建动画的方法都已经详细介绍过了,大家可能会有种感觉,比较钟情于第一种WPF/Silverlight ...
- WPF实现动画的几种方式及其小案例
WPF实现动画的方式: 基于计时器的动画 建立一个定时器,然后根据其频率循环调用函数或者一个事件处理函数,在这个函数中可以手工更新目标属性,直到达到最终值,这时可以停止计时器. 案例: 效果图: XA ...
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...
- WPF之动画
原文:WPF之动画 线性关键帧.不连续关键帧动画: <Window.Triggers> <EventTrigger RoutedEvent="Window.Loaded&q ...
- 基于Java Netty框架构建高性能的部标808协议的GPS服务器
使用Java语言开发一个高质量和高性能的jt808 协议的GPS通信服务器,并不是一件简单容易的事情,开发出来一段程序和能够承受数十万台车载接入是两码事,除去开发部标808协议的固有复杂性和几个月长周 ...
- 基于Typecho CMS框架开发大中型应用
基于Typecho CMS框架开发大中型应用 大中型应用暂且定义为:大于等于3个数据表的应用!汗吧! Typecho原本是一款博客系统,其框架体系有别于市面上一般意义MVC框架,主体代码以自创的Wid ...
- WPF利用动画实现圆形进度条
原文:WPF利用动画实现圆形进度条 这是我的第一篇随笔,最近因为工作需要,开始学习WPF相关技术,自己想实现以下圆形进度条的效果,逛了园子发现基本都是很久以前的文章,实现方式一般都是GDI实现的,想到 ...
随机推荐
- 【Spring】简述@Configuration配置类注册BeanDefinition到Spring容器的过程
概述 本文以SpringBoot应用为基础,尝试分析基于注解@Configuration的配置类是如何向Spring容器注册BeanDefinition的过程 其中主要分析了 Configuratio ...
- W5500设计方案
W5500是韩国一款集成全硬件 TCP/IP 协议栈的嵌入式以太网控制器,W5500同时也是一颗工业级以太网控制芯片,最近发现我们国内也有和W5500 芯片一样芯片 介绍给大家 如下图:
- Ubuntu中使用Nginx+rtmp模块搭建流媒体视频点播服务
1. 背景 不知不觉笔者来到流媒体部门已经一年半多了,积攒了不少的流媒体知识,但平时工作也比较忙,很少进行总结性的梳理,最近准备花几个周末时间写一个流媒体系列的实践文章,也算是给自己做总结的同时帮助有 ...
- RobotFramework自动化测试框架-Selenium Web自动化(三)关于在RobotFramework中如何使用Selenium很全的总结(下)
本文紧接着RobotFramework自动化测试框架-Selenium Web自动化(二)关于在RobotFramework中如何使用Selenium很全的总结(上)继续分享RobotFramewor ...
- 科学使用Log4View2
目录 目录 前言 科学使用 编辑和调试程序集 调试程序集 编辑程序集 结语 推荐文献 目录 NLog日志框架使用探究-1 NLog日志框架使用探究-2 科学使用Log4View2 前言 这个标题很低调 ...
- Elasticsearch系列---并发控制及乐观锁实现原理
概要 本篇主要介绍一下Elasticsearch的并发控制和乐观锁的实现原理,列举常见的电商场景,关系型数据库的并发控制.ES的并发控制实践. 并发场景 不论是关系型数据库的应用,还是使用Elasti ...
- typedef & #defiine & struct
#define(宏定义)只是简单的字符串代换(原地扩展),它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了. typedef是为了增加可读性而为标识符另起的新名称(仅仅只是个别名), ...
- css多行文本溢出显示省略号(兼容ie)
在日常编写页面中,我们经常遇到内容行数过多时,需要出现 “...” 来处理.但是又要考虑IE浏览器或IE内核浏览器的兼容性. 普通实现方法: display: -webkit-box; -webkit ...
- MySQL主从介绍、配置主从、测试主从同步
6月28日任务 说明:有不少同学不能一次性把实验做成功,这是因为还不熟悉,建议至少做3遍17.1 MySQL主从介绍17.2 准备工作17.3 配置主17.4 配置从17.5 测试主从同步有的同学,遇 ...
- 【Python成长之路】python 基础篇 -- 装饰器【华为云分享】
[写在前面] 有时候看到大神们的代码,偶尔会用到@来装饰函数.当时查了资料,大致了解装饰器一般用于在不改变原函数的基础上 ,对原函数功能进行修改/增强.使用场景是:日志级别设置.权限校验.性能测试等. ...