博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转载)WPF中的动画——(一)基本概念
阅读量:5323 次
发布时间:2019-06-14

本文共 2151 字,大约阅读时间需要 7 分钟。

http://www.cnblogs.com/TianFang/p/4050845.html

 

WPF的一个特点就是支持动画,我们可以非常容易的实现漂亮大方的界面。首先,我们来复习一下动画的基本概念。计算机中的动画一般是,也称之为逐帧动画,它通过每帧不同的图像连续播放,从而欺骗眼和脑产生动画效果。其原理在上有比较详尽的解释,这里就不多介绍了。

也就是说,我们要产生动画,只需要连续刷新界面即可。例如,我们要实现一个宽度变化的按钮的动画,可以用如下方式来实现:

    

private void MainWindow_Loaded(object sender, RoutedEventArgs e)    {        var timer = new System.Windows.Threading.DispatcherTimer();        timer.Tick += new EventHandler(OnTimedEvent);        timer.Interval = TimeSpan.FromSeconds(1.0 / 20);        timer.Start();    }    int index = 0;    private void OnTimedEvent(object sender, EventArgs e)    {        index++;        if (index > 40)            index = 0;        button.Width = 8 * (index++);    }

 

这段代码不难理解,就是每隔1/20秒更新一次按钮的宽度,在2s内将其高度从0变为320,重复播放。

这段代码虽然实现了动画效果,但它是通过计时器更新的传统做法,在WinForm下也能实现。在WPF中,正统的实现动画方式为:

    

private void MainWindow_Loaded(object sender, RoutedEventArgs e)    {        var widthAnimation = new DoubleAnimation()        {            From = 0,            To = 320,            Duration = TimeSpan.FromSeconds(2),            RepeatBehavior = RepeatBehavior.Forever,        };        button.BeginAnimation(WidthProperty, widthAnimation);    }

 

相比较而言,WPF的动画的实现方式有如下优点:

一、简洁

这个是非常明显的,WPF的动画的代码非常容易理解,Timer的版本则要难懂得多。当然,我们也可以通过封装,使得用Timer也能用类似的API实现动画。但动画的API并不是仅仅这么一点,要把整个动画框架的API都封装也没有那么容易。

二、和XAML无缝集成

这个就是WPF的独有技术了,得益于XAML强大的表述能力,我们可以写出非常强大且容易维护的动画。(这里就不举例了,后续文章中再做介绍)这点WinFom的Timer版本是无法做到的。

三、流畅性

如果将这两种实现方式一起跑起来比较一下就会发现,Timer实现的版本明显要卡顿,并且并没有精准的按照我们设计的那样运动。具体原因为:

Timer精度的问题:由于是改UI控件的属性(按钮的宽度),因此必须在UI线程上进行,因此DispatcherTimer 操作与其他操作一样需要放置到 Dispatcher 队列中,它并不保证恰好在改时间间隔中。它并不适合动画这种间隔很短的计时。

帧率的问题:逐帧动画的流畅性一般取决于每秒更新的帧数,也就是常说的帧率。人眼睛上限是70帧,而我这里代码中的Timer的固定了为20帧,因此是能明显感觉到卡顿的。而WPF的动画则不然,从它的API中可以看到,它是没有帧率的设置的。实际上,它是根据计算机的性能和当前进程的繁忙程度尽可能增大帧率的,因此WPF的动画是远大于20帧的,因此要流畅得多。

那么,是否只要修改参数,加大Timer的版本的帧率,也可以实现同样流畅的动画呢? 试了一下,就算修改参数,也是无法达到WPF版本的流畅程度的。我认为原因主要有如下两点,

  1. DispatcherTimer精度不够,无法实现大帧率下准确刷新。
  2. 通过简单的设置参数很难像WPF那样帧率根据计算机的性能和当前进程的繁忙程度智能匹配帧率。帧率设置过低,动画不流畅,设置过大,处理不过来仍然不流畅。并且UI线程的忙碌程度是会动态变化的,帧率也需要相应调整,这些都无法通过Timer来简单的处理。

总之,通过Timer定时更新的方式并不适合用来实现动画。因此还是有必要学习一下WPF的动画框架的,后面我将陆续写一系列文章进行一些简单的介绍。如果要系统的学习,建议参看以下微软的官方文档: 

转载于:https://www.cnblogs.com/bincoding/p/7363512.html

你可能感兴趣的文章
C语言栈的实现
查看>>
SRM 628 DIV2
查看>>
2018-2019-2 20165314『网络对抗技术』Exp5:MSF基础应用
查看>>
SecureCRT的使用方法和技巧(详细使用教程)
查看>>
自建数据源(RSO2)、及数据源增强
查看>>
2018icpc徐州OnlineA Hard to prepare
查看>>
使用命令创建数据库和表
查看>>
【转】redo与undo
查看>>
安卓当中的线程和每秒刷一次
查看>>
wpf样式绑定 行为绑定 事件关联 路由事件实例
查看>>
TCL:表格(xls)中写入数据
查看>>
Oracle事务
查看>>
String类中的equals方法总结(转载)
查看>>
标识符
查看>>
一步步教你轻松学奇异值分解SVD降维算法
查看>>
内存地址对齐
查看>>
创新课程管理系统数据库设计心得
查看>>
Could not resolve view with name '***' in servlet with name 'dispatcher'
查看>>
[转载] redis 的两种持久化方式及原理
查看>>
MyBaits学习
查看>>