原文: WPF中的動畫——(五)關鍵幀動畫 與 From/To/By 動畫類似,關鍵幀動畫以也可以以動畫形式顯示目标屬性值。 和From/To/By 動畫不同的是, From/To/By 動畫隻能控制在兩個狀态之間變化,而關鍵幀動畫則可以在多個狀态之間變化,例如,對于前面那個改變按鈕寬度的例子,如果我們要實作如下效果:
- 在2秒時将寬度從 0變為350
- 在7秒時将寬度變為50
- 在9秒的時候将其寬度變為200
雖然我們可以用三個From/To/By 動畫組合實作類似效果,但是這樣一來麻煩,二來要感覺動畫完成事件,不友善在XAML中使用。此時我們則可以使用關鍵幀動畫來快速實作這一過程。
var widthAnimation = new DoubleAnimationUsingKeyFrames();
var keyFrames = widthAnimation.KeyFrames;
keyFrames.Add(new
LinearDoubleKeyFrame(0, TimeSpan.FromSeconds(0)));
LinearDoubleKeyFrame(350, TimeSpan.FromSeconds(2)));
LinearDoubleKeyFrame(50, TimeSpan.FromSeconds(7)));
LinearDoubleKeyFrame(200, TimeSpan.FromSeconds(9)));
button.BeginAnimation(WidthProperty, widthAnimation);
可以看出,關鍵幀動畫将每一個狀态制定為一個關鍵幀,關鍵幀動畫時間線自動連接配接各個關鍵幀,并計算過渡狀态,完成動畫。是以,某種程度上,我們也可以把From/To/By 動畫看成是隻有兩個狀态的特殊關鍵幀動畫。
内置的關鍵幀動畫
與 From/To/By 動畫一樣,在名字空間System.Windows.Media.Animation 下也内置了大量關鍵幀動畫,它們的命名規則是:
<類型> AnimationUsingKeyFrames
例如這兒使用的DoubleAnimationUsingKeyFrames,其它類型請參看MSDN:
關鍵幀動畫概述,這裡就不列舉了。
插值算法
在關鍵幀動畫中,我們除了定義關鍵幀外,還需要定義兩個關鍵幀之間的插值算法,這樣系統才能根據關鍵幀和插值算法生成中間狀态。WPF系統内置四種插值算法:
- 線性: 兩個關鍵幀之間均勻變化
- 離散: 兩個關鍵幀之間突變(到達時間點的時候硬切換,沒有過渡效果)
- 樣條: 使用貝塞爾曲線實作更精确的加速和減速控制
- 緩動: 使用緩動函數曲線實作彈性變化
綜上來看,線性算法最常用,樣條算法能實作精準加速和減速控制。離散的這種硬切換的效果雖然看起來沒有什麼動畫效果,但用于連接配接關鍵幀還是比較常用的。另外在一些硬過渡的地方也是能用到的,例如實作閃爍效果。
這幾種算法的具體效果這裡就不做更多的介紹了,感興趣的朋友可以看看如下兩個連結中的描述和例子:
- http://msdn.microsoft.com/zh-cn/library/ms742524(v=vs.110).aspx
- http://msdn.microsoft.com/zh-cn/library/System.Windows.Media.Animation.LinearDoubleKeyFrame(v=vs.110).aspx
值得一提的是,并不是所有關鍵幀動畫都支援這幾種算法的,具體支援情況請參看MSDN:
。 當然,對于不支援的也是可以自己手動實作的。
關鍵幀(IKeyFrame)
前面已經介紹過,一個關鍵幀主要有時間點和插值算法兩部分組成,在WPF中,不同的關鍵幀動畫對應着同的關鍵幀對象,它們都繼承自IKeyFrame接口,其命名規則為:
<類型> KeyFrame
例如,DoubleAnimationUsingKeyFrames對應的是DoubleKeyFrame,但由于這個類并沒有制定插值算法,它隻是一個抽象基類,再加上插值算法後對應的關鍵幀類命名規範為:
<插值算法><類型> KeyFrame
例如,DoubleKeyFrame對應的幾種插值算法的關鍵幀為:LinearDoubleKeyFrame、DiscreteDoubleKeyFrame、SplineDoubleKeyFrame、EasingDoubleKeyFrame。這些關鍵幀對象使用的方式都比較類似,這裡就不多介紹了。
關鍵幀的時間點(KeyTime)
關鍵幀的時間點由IKeyFrame.KeyTime屬性指定。它是一個KeyTime類型,它有如下幾種取值類型:
- 時間點TimeSpan: 靠TimeSpan直接決定時間點,可以通過函數KeyTime.FromTimeSpan()建立,也可以直接用TimeSpan隐式轉換。
- 相對時間Percent: 指定的是百分比,通過時間線的Duration來聯合決定對應的時間點。通過函數KeyTime.FromPercent()建立。
- 特殊值Uniform: 時間線平均分布每個關鍵幀所需要的時間。通過函數KeyTime.Uniform建立。
- 特殊值Paced: 間線按固定的幀率配置設定所需時間,這種情況下,變化大的關鍵幀配置設定時間長,變化小的關鍵幀配置設定時間段。通過函數KeyTime.Paced建立。
用代碼建立的方式這兒就不舉例了,這裡就僅僅列舉一下如何在XAML中表示這幾種時間:
<LinearDoubleKeyFrame
Value="100" KeyTime="0:0:3" />
Value="100" KeyTime="30%" />
Value="100" KeyTime="Uniform" />
Value="100" KeyTime="Paced" />
參考資料: