顯式動畫Animation<轉>


當需要對非Root Layer進行動畫或者需要對動畫做更多自定義的行為的時候,就必須使用到顯式動畫了,顯式動畫的基類為CAAnimation,常用的是CABasicAnimation,CAKeyframeAnimation有時候還會使用到CAAnimationGroup,CATransition(注意不是CATransaction,Transition是過渡的意思). 

這里再強調關於動畫的兩個重要的點:一是中間狀態的插值計算(Interpolation),二是動畫節奏控制(Timing); 有時候插值計算也和Timing有一定關系. 如果狀態是一維空間的值(比如透明度),那么插值計算的結果必然再起點值和終點值之間,如果狀態是二維空間的值(比如position),那么一般情況下插值得到的點會落在起點和終點之間的線段上(當然也有可能連線是圓滑曲線).

1.CABasicAnimation

不管是CABasicAnimation還是CAKeyframeAnimation都是繼承於CAPropertyAnimation.CABasicAnimation有三個比較重要的屬性,fromValue,toValue,byValue,這三個屬性都是可選的,但不能同時多於兩個為非空.最終都是為了確定animation變化的起點和終點.Setting Interpolation Values詳細介紹了這個三個值的各種情況以及用途. 設置了動畫的起點和終點之后,中間的值都是通過插值方式計算出來的.插值計算的結果由timingFunction指定,默認timingFunction為nil,會使用liner的,也就是變化是均勻的.

2.Timing Function的作用

Timing Function的會被用於變化起點和終點之間的插值計算.形象點說是Timing Function決定了動畫運行的節奏(Pacing),比如是均勻變化(相同時間變化量相同),先快后慢,先慢后快還是先慢再快再慢.

時間函數是使用的一段函數來描述的,橫座標是時間t取值范圍是0.0-1.0,縱座標是變化量x(t)也是取值范圍也是0.0-1.0 假設有一個動畫,duration是8秒,變化值的起點是a終點是b(假設是透明度),那么在4秒處的值是多少呢? 可以通過計算為 a + x(4/8) * (b-a), 為什么這么計算呢?講實現的時間映射到單位值的時候4秒相對於總時間8秒就是0.5然后可以得到0.5的時候單位變化量是 x(0.5), x(0.5)/1 = 實際變化量/(b-a), 其中b-a為總變化量,所以實際變化量就是x(0.5) * (b-a) ,最后4秒時的值就是 a + x(0.5) * (b-a),所以計算的本質是映射.

Timing Function對應的類是CAMediaTimingFunction,它提供了兩種獲得時間函數的方式,一種是使用預定義的五種時間函數,一種是通過給點兩個控制點得到一個時間函數. 相關的方法為

+ (id)functionWithName:(NSString *)name;

+ (id)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

- (id)initWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;

五種預定義的時間函數名字的常量變量分別為 
kCAMediaTimingFunctionLinear, 
kCAMediaTimingFunctionEaseIn, 
kCAMediaTimingFunctionEaseOut, 
kCAMediaTimingFunctionEaseInEaseOut, 
kCAMediaTimingFunctionDefault. 
下圖展示了前面四種Timing Function的曲線圖,橫座標表示時間,縱座標表示變化量,這點需要搞清楚(並不是平面座標系中xy).
自定義的Timing Function的函數圖像就是一條三次貝塞爾曲線Cubic Bezier Curve,貝塞爾曲線的優點就是光滑,用在這里就使得變化顯得光滑.一條三次貝塞爾曲線可以由起點終點以及兩個控制點決定. 
上面的kCAMediaTimingFunctionDefault對應的函數曲線其實就是通過[(0.0,0.0), (0.25,0.1), (0.25,0.1), (1.0,1.0)]這四個點決定的三次貝塞爾曲線,頭尾為起點和終點,中間的兩個點是控制點. 

上圖中P0是起點,P3是終點,P1和P2是兩個控制點

如果時間變化曲線既不是直線也不是貝塞爾曲線,而是自定義的,又或者某個圖層運動的軌跡不是直線而是一個曲線,這些是基本動畫無法做到的,所以引入下面的內容,CAKeyframeAnimation,也即所謂的關鍵幀動畫.

3.CAKeyframeAnimation

任何動畫要表現出運動或者變化,至少需要兩個不同的關鍵狀態,而中間的狀態的變化可以通過插值計算完成,從而形成補間動畫,表示關鍵狀態的幀叫做關鍵幀.CABasicAnimation其實可以看作一種特殊的關鍵幀動畫,只有頭尾兩個關鍵幀.CAKeyframeAnimation則可以支持任意多個關鍵幀,關鍵幀有兩種方式來指定,使用path或者使用values,path是一個CGPathRef的值,且path只能對CALayer的 anchorPoint 和 position 屬性起作用,且設置了path之后values就不再起效了.而values則更加靈活. keyTimes這個可選參數可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的. 
還可以通過設置可選參數timingFunctions(CAKeyframeAnimation中timingFunction是無效的)為關鍵幀之間的過渡設置timingFunction,如果values有n個元素,那么timingFunctions則應該有n-1個.但很多時候並不需要timingFunctions,因為已經設置了夠多的關鍵幀了,比如沒1/60秒就設置了一個關鍵幀,那么幀率將達到60FPS,完全不需要相鄰兩幀的過渡效果(當然也有可能某兩幀 值相距較大,可以使用均勻變化或者增加幀率,比如每0.01秒設置一個關鍵幀).

在關鍵幀動畫中還有一個非常重要的參數,那便是calculationMode,計算模式.其主要針對的是每一幀的內容為一個座標點的情況,也就是對anchorPoint 和 position 進行的動畫.當在平面座標系中有多個離散的點的時候,可以是離散的,也可以直線相連后進行插值計算,也可以使用圓滑的曲線將他們相連后進行插值計算. calculationMode目前提供如下幾種模式 kCAAnimationLinear 
kCAAnimationDiscrete 
kCAAnimationPaced 
kCAAnimationCubic 
kCAAnimationCubicPaced

kCAAnimationLinear calculationMode的默認值,表示當關鍵幀為座標點的時候,關鍵幀之間直接直線相連進行插值計算; 
kCAAnimationDiscrete 離散的,就是不進行插值計算,所有關鍵幀直接逐個進行顯示; 
kCAAnimationPaced 使得動畫均勻進行,而不是按keyTimes設置的或者按關鍵幀平分時間,此時keyTimes和timingFunctions無效; 
kCAAnimationCubic 對關鍵幀為座標點的關鍵幀進行圓滑曲線相連后插值計算,對於曲線的形狀還可以通過tensionValues,continuityValues,biasValues來進行調整自定義,這里的數學原理是Kochanek–Bartels spline,這里的主要目的是使得運行的軌跡變得圓滑; 
kCAAnimationCubicPaced 看這個名字就知道和kCAAnimationCubic有一定聯系,其實就是在kCAAnimationCubic的基礎上使得動畫運行變得均勻,就是系統時間內運動的距離相同,此時keyTimes以及timingFunctions也是無效的.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM