在項目當中經常看到一些非常好看的動畫,于是乎自己也利用了一下業余時間把這塊東西整理
先看一個簡單的結構圖
animation.png
CAAnimation本身不能使用,需要使用他的子類。
- CAPropertyAnimation 屬性動畫 (本身也不能使用,要使用它的子類)
- CAAnimationGroup 組動畫
- CATransition 轉場動畫,系統就是使用在這個來做轉場動畫效果處理的
一、CAPropertyAnimation之CABaseAnimaiton
因為CAAnimaiton是對Layer
進行動畫,屬性動畫顧名思義就是對Layer
的屬性進行動畫。
在CABaseAnimation中常用的屬性介紹:
屬性介紹.png
具有動畫效果的KeyPath有
圖片.png
代碼如下:
class func baseAnimationWithKeyPath(_ path : String , fromValue : Any? , toValue : Any?, duration : CFTimeInterval, repeatCount : Float? , timingFunction : String?) -> CABasicAnimation{
let animate = CABasicAnimation(keyPath: path)
//起始值
animate.fromValue = fromValue;
//變成什么,或者說到哪個值
animate.toValue = toValue
//所改變屬性的起始改變量 比如旋轉360°,如果該值設置成為0.5 那么動畫就從180°開始
// animate.byValue =
//動畫結束是否停留在動畫結束的位置
// animate.isRemovedOnCompletion = false
//動畫時長
animate.duration = duration
//重復次數 Float.infinity 一直重復 OC:HUGE_VALF
animate.repeatCount = repeatCount ?? 0
//設置動畫在該時間內重復
// animate.repeatDuration = 5
//延時動畫開始時間,使用CACurrentMediaTime() + 秒(s)
// animate.beginTime = CACurrentMediaTime() + 2;
//設置動畫的速度變化
/*
kCAMediaTimingFunctionLinear: String 勻速
kCAMediaTimingFunctionEaseIn: String 先慢后快
kCAMediaTimingFunctionEaseOut: String 先快后慢
kCAMediaTimingFunctionEaseInEaseOut: String 兩頭慢,中間快
kCAMediaTimingFunctionDefault: String 默認效果和上面一個效果極為類似,不易區分
*/
animate.timingFunction = CAMediaTimingFunction(name: timingFunction ?? kCAMediaTimingFunctionEaseInEaseOut)
//動畫在開始和結束的時候的動作
/*
kCAFillModeForwards 保持在最后一幀,如果想保持在最后一幀,那么isRemovedOnCompletion應該設置為false
kCAFillModeBackwards 將會立即執行第一幀,無論是否設置了beginTime屬性
kCAFillModeBoth 該值是上面兩者的組合狀態
kCAFillModeRemoved 默認狀態,會恢復原狀
*/
animate.fillMode = kCAFillModeBoth
//動畫結束時,是否執行逆向動畫
// animate.autoreverses = true
return animate
}
實例圖:
aniChange.gif
aniPosition.gif
aniRotation.gif
aniScale.gif
aniSize.gif
二、CAPropertyAnimation之CAKeyframeAnimation
關鍵幀動畫屬性介紹
圖片.png
代碼
class func keyFrameAnimationWithKeyPath(_ keyPath : String , values : [Any]? , keyTimes : [NSNumber]? , path : CGPath? , duration : CFTimeInterval , cacluationMode : String , rotationMode : String?) -> CAKeyframeAnimation{
let keyFrame = CAKeyframeAnimation(keyPath: keyPath)
//由關鍵幀(關鍵值),通過關鍵幀對應的值執行動畫
keyFrame.values = values
//當設置了path之后,values就沒有效果了
keyFrame.path = path
//計算模式
/*
`discrete', 離散的,不進行插值運算
`linear', 線性插值
`paced', 節奏動畫,自動計算動畫的運動時間,是的動畫均勻運行,而不是根據keyTimes的值進行動畫,設置這個模式keyTimes和timingFunctions無效
`cubic' 對關鍵幀為坐標點的關鍵幀進行圓滑曲線相連后插值計算,需要設置timingFunctions。還可以通過tensionValues,continueityValues,biasValues來進行調整自定義
`cubicPaced' 結合了paced和cubic動畫效果
*/
keyFrame.calculationMode = cacluationMode
//旋轉模式
/*
`auto' = kCAAnimationRotateAuto 根據路徑自動旋轉
`autoReverse' = kCAAnimationRotateAutoReverse 根據路徑自動翻轉
*/
keyFrame.rotationMode = rotationMode
/*
用來區分動畫的分割時機。值區間為0.0 ~ 1.0 ,數組中的后一個值比前一個大或者相等,最好的是和Values或者Path控制的值對應
這個屬性只在 calculationMode = linear/discrete/cubic是被使用
*/
keyFrame.keyTimes = keyTimes
//動畫時長
keyFrame.duration = duration
return keyFrame
}
效果:
aniKeyFrame.gif
三、組動畫CAAnimationGroup
組動畫是就是添加多個動畫,同時產生動畫效果
這個的屬性比較簡單:
- open var animations: [CAAnimation]?
代碼
//創建動畫組
let layerGroup = CAAnimationGroup()
//添加動畫
layerGroup.animations = [shadowColorAni,shadowOffsetAni,shadowRadiusAni,shadowOpacityAni,positionYAni,boundsAni]
//重復次數
layerGroup.repeatCount = Float.infinity
//動畫時間
layerGroup.duration = 1.8
//翻轉
layerGroup.autoreverses = true
//把層添加進去
view.layer.insertSublayer(shapeLayer, at : 0)
//添加動畫
shapeLayer.add(layerGroup, forKey: "layerGroup")
效果:
aniGroup.gif
四、CATransition轉場動畫
屬性介紹
圖片.png
代碼
class func transitionAnimationWith(duration : CFTimeInterval, type : String , subtype : String? , startProgress : Float , endProgress : Float) -> CATransition{
let transitionAni = CATransition()
//轉場類型
transitionAni.type = type
/*
kCATransitionFromTop 從頂部轉場
kCATransitionFromBottom 從底部轉場
kCATransitionFromLeft 從左邊轉場
kCATransitionFromRight 從右邊轉場
*/
transitionAni.subtype = subtype ?? kCATransitionFromLeft
//動畫開始的進度
transitionAni.startProgress = startProgress
//動畫結束的進度
transitionAni.endProgress = endProgress
//動畫的時間
transitionAni.duration = duration
return transitionAni
}
效果
aniTransition.gif
五、IOS9之后的 Spring動畫
屬性:
圖片.png
代碼
class func springAnimationWithPath(_ path : String , mass : CGFloat , stiffness : CGFloat , damping : CGFloat , fromValue : Any? , toValue : Any) -> CASpringAnimation{
let springAni = CASpringAnimation(keyPath: path)
//質量:影響圖層運動時的彈簧慣性,質量越大,彈簧的拉伸和壓縮的幅度越大,動畫的速度變慢,且波動幅度變大
springAni.mass = mass
//剛度:越大動畫越快
springAni.stiffness = stiffness
//阻尼:越大停止越快
springAni.damping = damping
//初始速率
springAni.initialVelocity = 0
//初始值
springAni.fromValue = fromValue
//結束值
springAni.toValue = toValue
print("動畫停止預估時間" + "\(springAni.settlingDuration)")
springAni.duration = springAni.settlingDuration
return springAni
}
效果:
aniSpring.gif
六、綜合實例
動畫代碼全部都在Git上面
aniDrawline.gif
aniFire1.gif
aniFire2.gif
aniLogin.gif
aniWaveLine.gif
-
DEMO地址
-
如果覺得有用,用star砸死我吧
圖片.png