一. CA類之間的關係
如圖,
二. CAMediaTiming協議
該協議中, 提供了以下屬性:
beginTime 用來設置動畫延時,若想延遲1秒,就設置爲CACurrentMediaTime()+1,其中CACurrentMediaTime()爲圖層當前時間。
duration 動畫的持續時間。
speed 動畫速率,決定動畫時間的倍率。當speed爲2時,動畫時間爲設置的duration的1/2。
timeOffset 動畫時間偏移量。比如設置動畫時長爲3秒,當設置timeOffset爲1.5時,當前動畫會從中間位置開始,並在到達指定位置時,走完之前跳過的前半段動畫。
repeatCount 動畫的重複次數。
repeatDuration 動畫的重複時間。
autoreverses 動畫由初始值到最終值後,是否反過來回到初始值的動畫, 默認爲NO。如果設置爲YES,就意味着動畫完成後會以動畫的形式回到初始值。
fillMode 決定當前對象在非動畫時間段的行爲.比如動畫開始之前,動畫結束之後。
⚠️:其實不只是CAAnimation遵循CAMediaTiming協議,熟悉底層結構的小夥伴們應該知道CALayer也遵循這個協議,所有在一定程度上我們可以通過控制layer本身的協議屬性來控制動畫節奏。
三. CAAnimation類
timingFunction 控制動畫節奏, 枚舉類型
delegate 指定CAAnimationDelegate的代理人,用於監聽動畫.
開始-(void)animationDidStart
結束-(void)animationDidStop(能監聽動畫的stop和remove)
removedOnCompletion 在動畫完成後是否移除動畫,默認爲YES.
注意:,如果想保持動畫執行後的狀態, 需要設置removedOnCompletion爲NO,並且設置fillMode爲kCAFillModeForwards。但如此操作並不會改變layer實際的值, 更加推薦”動畫結束後通過事務CATransaction關閉隱式動畫,並set操作layer的值”
詳情參考:https://www.jianshu.com/p/51483b560244
四.CAPropertyAnimation及其子類
1. 繼承於CAAnimation, 一般直接使用其子類來操作動畫,不使用本類.
類方法:
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
keyPath解析: CALayer的某個屬性名,並通過這個屬性的值進行修改,達到相應的動畫效果.
至於keyPath的值,可以參考http://www.cnblogs.com/pengyingh/articles/2379631.html
或者參考:
opacity 透明度
backgroundColor 背景顏色
cornerRadius 圓角
borderWidth 邊框寬度
contents 內容
…
rotation 旋轉
transform.rotation.x
transform.rotation.y
…
scale 縮放
transform.scale.x
transform.scale.y
transform.scale.z
…
translation 平移
transform.translation.x
transform.translation.y
transform.translation.z
…
position 位置
position.x
position.y
…
bounds 大小
bounds.size.width
bounds.origin.x
… … 以及CALayer子類對應的各個屬性(比如CAShapeLayer的path)
2.兩個子類包括CABasicAnimation(基礎動畫)和CAKeyframeAnimation(關鍵幀動畫), 下面接着講解.
2.1 對於CABasinAnimation, 僅有三個屬性:
fromValue, keyPath相應屬性的初始值
toValue, keyPath相應屬性的結束值
byValue, 在不設置toValue時,toValue = fromValue + byValue,也就是在當前的位置上增加多少
而CASpringAnimation ,繼承於CABasinAnimation, 是帶有初始速度以及阻尼指數等物理參數的屬性動畫。
我們可以把它看成在不絕對光滑的地面上,一個彈簧拴着別小球,那麼我們可以這麼理解他的屬性:
mass -> 小球質量,影響慣性。
stiffness -> 彈簧的勁度係數。
damping -> 阻尼係數,地面的摩擦力。
initialVelocity -> 初始速度,相當於給小球一個初始速度(可正可負,方向不同)
settlingDuration -> 結算時間,根據上述參數計算出的預計時間,相對於你設置的時間,這個時間比較準確。
2.2 對於CAKeyframeAnimation ,同樣通過keyPath對應屬性進行控制,但它可以通過values或者path進行多個階段的控制。
屬性如下:
path 關鍵幀路徑,優先級比values高,但是隻對CALayer的anchorPoint和position起作用。
values 關鍵幀組成的數組,動畫會依次顯示其中的每一幀,如果設置了path,那麼values將被忽略。
keyTimes 數組, 每一幀對應的時間,如果不設置,則各關鍵幀平分設定時間。
timingFunctions 數組 每一幀對應的動畫節奏。
tensionValues -> 動畫張力控制數組。
continuityValues -> 動畫連續性控制數組。
biasValues -> 動畫偏差率控制數組。
五. CATransition
是CAAnimation的子類,用於做轉場動畫,能夠爲層提供移出屏幕和移入屏幕的動畫效果.
屬性如下:
type -> 轉場動畫類型。
subtype -> 轉場動畫方向。
startProgress -> 動畫起點進度(整體的百分比)。
endProgress -> 動畫終點進度(整體的百分比)。
關於type的值:
六. CAAnimationGroup組合動畫
/* An array of CAAnimation objects. Each member of the array will run
* concurrently(同時地,併發地) in the time space of the parent animation using the normal rules. */
@property(nullable, copy) NSArray *animations;
七.仿射變換CGAffineTransform
數學原理參考https://www.cnblogs.com/yulang314/p/5128661.html
變化原理:源視圖上的點p(x,y)變化成目標視圖中p’(x’,y’)。對應關係爲:
注意:
CGAffineTransformIdentity, 獲取本身的轉換比例transform;
其次, 轉換後, 動畫會停留在最終狀態, 參數值發生了實質變換.
1.平移變換
我們如果想要達到平移的目的,只需要x’ = x + tx,y’ = y + ty(改變對應點的橫縱座標的位置即可)。那麼這樣算來,仿射變換的參數中,a = 1,b = 0, c = 0, d = 1。也就是說,我們確定了四個參數,那麼我們可以根據自己的需求給定tx,ty,這樣就完成了平移的設置。
所以, ios還提供了這個函數用於平移:
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
還有另外一個平移變換的構造:
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
兩者的區別當我們對一個視圖進行平移操作的時候,前者每次都會從初始位置開始平移(操作前回到原來的位置),後者是從給定參數(通常是上一次的狀態)的基礎上繼續平移。
2.縮放變換
縮放的操作,本質上是拉長或縮短了原來的點與點之間的距離,那麼也就是說我們只需要讓x’ = a * x, y’ = d *y(將一個點的橫座標和縱座標放大或者縮小若干倍)。根據平移的經驗,那麼這樣算來,仿射變換的參數中,b = 0, c = 0,tx = 0,ty = 0。也就是說,我們確定了四個參數,那麼我們可以根據自己的需求給定a,b,這樣就完成了縮放的設置,系統稱變換的係數爲sx,sy。
同樣它有兩種給定參數的方式:
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
前者依然是在視圖初始狀態的基礎上進行縮放(每次縮放前都先回到初始狀態),後者是在前一次操作後的基礎上進行縮放操作。
3.旋轉變換
在iOS中,視圖的旋轉是按照順時針進行一個角度(假定爲α)的改變,系統幫我們封裝了起來(角度參數爲angle),我們只需要設定一個角度就可以了。
所以系統通過的構造旋轉操作的參數是:
CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
同樣,前者是在初始化的基礎上操作旋轉(每次旋轉先回到初始狀態),而後者是在上一個參數(通常情況下是上一次的操作結果)的基礎上旋轉。
需要補充的動畫基礎
1.在每一個CALayer中,都有三個重要的層次樹,它們負責相互協調完成圖層的渲染展示效果。這三個層次樹分別是:
模型樹。通過layer.modelLayer獲取,當我們修改CALayer的可動畫屬性時,模型樹對應的屬性就會立刻被修改成對應的數值
呈現樹。通過layer. presentationLayer獲取,呈現樹保存着當前圖層狀態的顯示數據,即會隨着動畫的過程不斷更新圖層的狀態數據
渲染樹,iOS並沒有提供任何API來獲取這一個層次樹。顧名思義,它通過結合 modelLayer跟presentationLayer中設置的效果來將內容渲染到屏幕上
2.CAAnimation通過presentationLayer呈現的動畫, 並不會實質改變modelLayer(即我們所說的layer)的值,所以動畫完成後會自動回到初始狀態; 而通過UIView動畫, 改變的是實質數據(block裏面修改View值),所以動畫完成後, 會停留在最後狀態.