Swift — 玩玩 動畫(CABasicAnimation)
6 min readJun 8, 2018
之前我們有實作一些有關遮罩 Mask 的效果,這次我們將它套用到 CABasicAnimation 實作一些好玩且常用到的動畫效果。
聚光燈效果(Random Circle Mask)
雖然我不知道該取什麼名字,可是內容大致上是想要有個 Mask 在我們的圖片上隨機移動,然後移動到的地方才會顯示遮罩後的圖片。
因此我們會需要先畫出一個圓形的 Layer 來當我們的 Mask:
let mask = CALayer()mask.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
mask.backgroundColor = UIColor.black.cgColor
mask.cornerRadius = 100
mask.position = view.centermyImage.layer.mask = mask
之後我們會需要讓它產生隨機的 x、y 座標,而且移動範圍必須在手機範圍內,所以我們這麼設置:
@objc func animationMask() {// 設置 x,y 座標位移範圍
let xPosition = CGFloat(arc4random() % UInt32(view.frame.maxX))
let yPosition = CGFloat(arc4random() % UInt32(view.frame.maxY))let animation = CABasicAnimation(keyPath: "position")
animation.toValue = CGPoint(x: xPosition, y: yPosition)
animation.duration = 10// 這邊 duration 設置為 10 的原因,就只是想單純讓它能更複雜的位移,可能還沒結束這個 function 又被調用一次,在畫面呈現可能就會有彎曲移動的感覺。mask.add(animation, forKey: nil)}
之後我們需要設置一個 Timer 來調用這個方法,並且也更新裡面的座標的數據,並且把 repeats 設置為 true:
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(animationMask), userInfo: nil, repeats: true)
翻牌效果(Flip Card Mask)
這個效果大致上是想要做出一個類似翻牌的效果,只是忘了後面那張不會翻轉…,所以你們可以想像有一張透明的 Mask 在翻轉( 應該沒錯吧… ),這邊我們一樣需要建立一個 Layer 來做為 mask:
// 這邊把 frame 設置為整個畫面,為了讓整個畫面有翻轉效果
mask.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)mask.backgroundColor = UIColor.black.cgColormyImage.layer.mask = mask
這邊我一樣把動畫效果獨立出來,定義在一個方法內,因為這一次我們以 y 軸為中心旋轉效果,所以我們 key Path 為 transform.rotation.y :
func animationMask() {let animation = CABasicAnimation(keyPath: "transform.rotation.y")
animation.toValue = Double.pi * 2
animation.duration = 3
animation.repeatCount = Float.infinitymask.add(animation, forKey: nil)}
縮放效果 (Transform Mask)
這個效果我想預設就想要一個類似一個小洞逐漸變大的效果,所以這個效果其實很容易實現,我們一樣建立一個 mask 來作為遮罩:
mask.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
mask.position = myImage.center
mask.cornerRadius = 100
mask.masksToBounds = true
mask.backgroundColor = UIColor.black.cgColor這邊因為是要由小變大的洞,所以我把 mask 切成圓形。
接下來重點依然是我們的動畫部分( mask 只是輔助? ),這邊我們選擇變形的縮放效果,所以 keyPath 為 transform.scale:
func animationMask() {let animation = CABasicAnimation(keyPath: "transform.scale")// 這邊我想要他一開始是小到看不見的圓
animation.fromValue = [0.01,0.01]// 之後再把它放到最大
animation.toValue = [5,5]animation.duration = 5
animation.autoreverses = true
animation.repeatCount = Float.infinitymask.add(animation, forKey: nil)}
最後附上小小 Demo 的 Github 連結: