WPF中的動畫——(一)基本概念

原文:WPF中的動畫——(一)基本概念

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的動畫框架的,后面我將陸續寫一系列文章進行一些簡單的介紹。如果要系統的學習,建議參看以下微軟的官方文檔: http://msdn.microsoft.com/zh-cn/library/ms752312(v=vs.110).aspx

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/390454.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/390454.shtml
英文地址,請注明出處:http://en.pswp.cn/news/390454.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cloud 異步遠程調用_異步遠程工作的意外好處-以及如何擁抱它們

cloud 異步遠程調用In this article, Ill discuss the positive aspects of being a little out of sync with your team.在本文中,我將討論與您的團隊有點不同步的積極方面。 So you’ve started working from home.因此,您已經開始在家工作。 There …

linux 問題一 apt-get install 被 lock

問題: sudo apt-get install vim E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it? 解決: sudo rm /var/cac…

工信部高級軟件工程師_作為新軟件工程師的信

工信部高級軟件工程師Dear Self, 親愛的自我, You just graduated and you are ready to start your career in the IT field. I cannot spoil anything, but I assure you it will be an interesting ride. 您剛剛畢業,就可以開始在IT領域的職業了。 我…

Python高級網絡編程系列之基礎篇

一、Socket簡介 1、不同電腦上的進程如何通信? 進程間通信的首要問題是如何找到目標進程,也就是操作系統是如何唯一標識一個進程的! 在一臺電腦上是只通過進程號PID,但在網絡中是行不通的,因為每臺電腦的IP可能都是不一…

多線程編程和單線程編程_生活與編程的平行線程

多線程編程和單線程編程I’m convinced our deepest desire is, by paying the cost of time, to be shown a glimmer of some fundamental truth about the universe. To hear it whisper its lessons and point towards its purpose.我堅信,我們最深切的愿望是通過…

劍指 Offer 67. 把字符串轉換成整數

寫一個函數 StrToInt,實現把字符串轉換成整數這個功能。不能使用 atoi 或者其他類似的庫函數。 首先,該函數會根據需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符為止。 當我們尋找到的第一個非空字符為正或者負號時&#xff0c…

搭建MSSM框架(Maven+Spring+Spring MVC+MyBatis)

https://github.com/easonjim/ssm-framework 先欠著&#xff0c;后續再進行講解&#xff1a; 一、Spring內核集成 二、Spring MVC集成 三、MyBatis集成 四、代碼生成工具集成 >如有問題&#xff0c;請聯系我&#xff1a;easonjim#163.com&#xff0c;或者下方發表評論。<…

4.RabbitMQ Linux安裝

這里使用的Linux是CentOS6.2 將/etc/yum.repo.d/目錄下的所有repo文件刪除 先下載epel源 # wget -O /etc/yum.repos.d/epel-erlang.repo http://repos.fedorapeople.org/repos/peter/erlang/epel-erlang.repo 修改epel-erlang.repo文件&#xff0c;如下圖 添加CentOS 的下載源…

freecodecamp_如何對freeCodeCamp文章提供反饋

freecodecampWe at the freeCodeCamp editorial team do our best to ensure articles are as accurate as they can be.我們的freeCodeCamp編輯團隊竭盡所能&#xff0c;以確保文章盡可能準確。 Still, we occasionally miss factual inaccuracies, non-functioning code exa…

如何對接oracle 建立pdb

Oracle數據庫的結構是一個數據庫實例下有許多用戶&#xff0c;每一個用戶有自己的表空間&#xff0c;即每一個用戶相當于MySQL中的一個數據庫。不久前下了oracle 12c的數據庫&#xff0c;安裝之后建user時才知道oracle12c 有一個很大的變動就是引入了pdb可插入數據庫&#xff0…

二、數據庫設計與操作

一、 數據庫設計仿QQ數據庫一共包括5張數據表&#xff0c;每張數據表結構如下&#xff1a;1、 tb_User&#xff08;用戶信息表&#xff09;這張表主要用來存儲用戶的好友關系與信息字段名數據類型是否Null值默認值綁定描述IDint否用戶賬號PwdVarchar(50)否用戶密碼Frie…

hdu 過山車_從機械工程師到軟件開發人員–我的編碼過山車

hdu 過山車There arent many people out there who grew up dreaming of writing code. I definitely didnt. I wanted to design cars. But somehow I ended up building software.很少有人夢見編寫代碼。 我絕對沒有。 我想設計汽車。 但是我最終以某種方式開發了軟件。 I u…

mysql 兩列互換

mysql 如果想互換兩列的值&#xff0c;直接寫 update 表 set col1col2&#xff0c;col2col1 這樣的后果就是兩列都是 col2 的值 注意這和sql server 是不同的&#xff0c; 如果想實現上述功能&#xff0c;添加一個自增列作為標識&#xff08;必須的&#xff09;&#xff0c; u…

劍指 Offer 36. 二叉搜索樹與雙向鏈表

輸入一棵二叉搜索樹&#xff0c;將該二叉搜索樹轉換成一個排序的循環雙向鏈表。要求不能創建任何新的節點&#xff0c;只能調整樹中節點指針的指向。 為了讓您更好地理解問題&#xff0c;以下面的二叉搜索樹為例&#xff1a; 我們希望將這個二叉搜索樹轉化為雙向循環鏈表。鏈表…

游戲引擎開發和物理引擎_視頻游戲開發的最佳游戲引擎

游戲引擎開發和物理引擎In this article, well look at some of the most popular game engines for video game development. Youll get a brief overview of each engine so you can choose which to use for your project.在本文中&#xff0c;我們將介紹一些用于視頻游戲開…

TPS和QPS的區別和理解

TPS和QPS的區別和理解 原創 2016年04月26日 17:11:3114010QPS&#xff1a;Queries Per Second意思是“每秒查詢率”&#xff0c;是一臺服務器每秒能夠相應的查詢次數&#xff0c;是對一個特定的查詢服務器在規定時間內所處理流量多少的衡量標準。 TPS&#xff1a;是Transaction…

1893. 檢查是否區域內所有整數都被覆蓋

theme: healer-readable 給你一個二維整數數組 ranges 和兩個整數 left 和 right 。每個 ranges[i] [starti, endi] 表示一個從 starti 到 endi 的 閉區間 。 如果閉區間 [left, right] 內每個整數都被 ranges 中 至少一個 區間覆蓋&#xff0c;那么請你返回 true &#xff…

004-docker常用命令[二]-容器操作ps,top,attach,export

2.3、容器操作 2.3.1、docker ps docker ps : 列出容器 語法 docker ps [OPTIONS] OPTIONS說明&#xff1a; -a :顯示所有的容器&#xff0c;包括未運行的。 -f :根據條件過濾顯示的內容。 --format :指定返回值的模板文件。 -l :顯示最近創建的容器。 -n :列出最近創建的n…

【類】變量復用,函數復用

變量復用 變量復用&#xff0c;適用于以下場景&#xff1a;1&#xff0c;整個項目公用的部分&#xff08;比如errors&#xff09;&#xff1b;2&#xff0c;一組類要通信&#xff0c;或者同一個類的兩個函數之間要通信&#xff0c;通信數據可以用類來定義和約束&#xff1b; 場…

python練習_如何使用Logzero在Python中練習記錄

python練習Logzero is a Python package created by Chris Hager that simplifies logging with Python 2 and 3. Logzero makes it easier as a print statement to show information and debugging details.Logzero是Chris Hager創建的Python程序包&#xff0c;它簡化了Pytho…