運用 CAGradientLayer、 CABasicAnimation做字母效果
利用 CAGradientLayer做字母漸層、CABasicAnimation設定動畫
上一篇文章
製作檔案
本次繪製用到以下功能:
- 利用UIBezierPath繪製路徑
- 利用CAShapeLayer產生形狀
- 利用 CAGradientLayer & mask 讓 CAShapeLayer 繪製的形狀變漸層
- 使用 CABasicAnimation 設定動畫
利用 CAGradientLayer & mask 讓 CAShapeLayer 繪製的形狀變漸層
再來就是幫小小兵的名字KEVIN加漸層了!想呈現字母內顏色漸層 & 字母邊框漸層兩種效果,取決於CAShapeLayer的fillColor屬性有無顏色
eLayer.fillColor = UIColor.clear.cgColor →無顏色
首先在生成CAGradientLaye後,挑選漸層效果的顏色。我從下面網站選了三個顏色,按一下顏色組合下方的分享按鈕可以複製每個顏色的RGB數值,很方便!
漸層放三個顏色,gradientLayer.locations
的array就要放三個值,各代表漸層顏色的分布比例,數值範圍為0–1。我設定[0.09, 0.15, 0.2]
代表左圖第一藍色到中間藍色的漸層從0開始、0.09結束; 中間藍色到黃色的漸層從0.15開始、0.2結束。
要注意locations
的array中的數值要越來越大,並且有幾個顏色就要有幾個數值。
let gradientLayer = CAGradientLayer()let nameGradientColor = [
CGColor(red: 10/255, green: 25/255, blue: 49/255, alpha: 1),
CGColor(red: 24/255, green: 90/255, blue: 219/255, alpha: 1),
CGColor(red: 255/255, green: 201/255, blue: 71/255, alpha: 1)]gradientLayer.colors = nameGradientColorgradientLayer.locations = [0.09, 0.15, 0.2]gradientLayer.frame = CGRect(x: 0, y: 0, width: 500, height: 500)view.layer.addSublayer(gradientLayer)gradientLayer.mask = eLayer
另外因為我事後才想到要幫字母加漸層效果,所以我先畫了字母的路徑和形狀後,才把eLayer 設成 gradientLayer 的 mask,造成字母E消失!為什麼會這樣??OMG
因為我在繪製字母E時使用了view的座標去設定路徑位置 (此時view還是eLayer的superView),但之後因為要將eLayer 設成 gradientLayer 的 mask (想像成gradientLayer變成eLayer的superView),導致gradientLayer上的字母E 路徑走的是view的座標系統,換句話說,字母E的路徑應該要gradientLayer的左上角(0,0)開始繪製才對!哎,所以字母無法顯現,更不用說還要求他漸層了!
view.layer.addSublayer(gradientLayer)gradientLayer.mask = eLayer
其實正確的製作順序是先有漸層Layer,然後在Layer上畫路徑才對啊——————
但木已成舟,既然現在沒辦法硬逼 eLayer 的 (0,0) 對應到 gradientLayer 的左上角 (0,0),不重畫的方法是,將gradientLayer的(x,y)座標設(0,0)
,讓他對齊view的左上角 (0,0)後,把frame尺寸設大一點如 width: 500, height: 500
,讓字母mask的路徑部分顯現出來。
let ePath = UIBezierPath()//不小心依照view為基準畫路徑的座標ePath.move(to: CGPoint(x: 249, y: 57))
ePath.addLine(to: CGPoint(x: 228, y: 57))
ePath.addLine(to: CGPoint(x: 228, y: 81))
ePath.addLine(to: CGPoint(x: 249, y: 81))
ePath.move(to: CGPoint(x: 230, y: 69))
ePath.addLine(to: CGPoint(x: 247, y: 69))//顯示E字母的CAShapeLayerlet eLayer = CAShapeLayer()
eLayer.path = ePath.cgPath
eLayer.strokeColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1).cgColor
eLayer.lineWidth = 8
eLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(eLayer)let gradientLayer = CAGradientLayer()let nameGradientColor = [
CGColor(red: 10/255, green: 25/255, blue: 49/255, alpha: 1),
CGColor(red: 24/255, green: 90/255, blue: 219/255, alpha: 1),
CGColor(red: 255/255, green: 201/255, blue: 71/255, alpha: 1)]gradientLayer.colors = nameGradientColorgradientLayer.locations = [0.09, 0.15, 0.2]gradientLayer.frame = CGRect(x: 0, y: 0, width: 500, height: 500)view.layer.addSublayer(gradientLayer)gradientLayer.mask = eLayer
使用 CABasicAnimation 設定動畫
先說明以下動畫沒有加上viewDidLoad,所以不會在畫面一啟動就開始跑動畫。要特別壓option+command+p去跑預覽。
CABasicAnimation可以實現位移、透明度、顏色、拉伸等動畫效果。這些動畫效果會由傳入的keyPath參數決定。我們用KEVIN的名字來測試,用前四個字母分別測試不同的動畫效果。
animation.duration
設定動畫持續時間,以秒為單位。以下例子都沒有動到秒數
字母 K
transform.scale.x
會拉伸Layer,將字母K的X座標由2到1拉伸
toValue的1是K原先設定的座標位置。kLayer從畫右拉伸移動到原設定位置。
let animation = CABasicAnimation(keyPath: “transform.scale.x”)animation.fromValue = 2animation.toValue = 1animation.duration = 3kLayer.add(animation, forKey: nil)
稍微調整數值試試效果
雖然沒有調整速度,但因為距離變遠,所以速度也變快了
animation.fromValue = 3animation.toValue = 0animation.duration = 3
字母 E
strokeEnd
代表顯示從 CABasicAnimation 路徑的起點畫線到終點的動畫效果。fromValue = 0是路徑起點,toValue = 1是路徑終點。畫面從開頭的空白到按照UIBezierPath的路徑順序,從起點到終點的跑出動畫。
let animation = CABasicAnimation(keyPath: “strokeEnd”)animation.fromValue = 0animation.toValue = 1animation.duration = 3eLayer.add(animation, forKey: nil)
稍微調整數值試試效果
把fromValue和toValue的值倒過來,畫面從開頭的E開始一筆一劃的消失
animation.fromValue = 1animation.toValue = 0animation.duration = 3
字母 V
opacity
會讓一個 layer 從 0 到 1 的淡入,反之則淡出
let animation = CABasicAnimation(keyPath: “opacity”)animation.fromValue = 0animation.toValue = 1animation.duration = 3vLayer.add(animation, forKey: nil)
字母 I
position
可以控制一個layer要從某座標移動到某座標,是設定讓layer回到原本位置。從開頭I在[0, 40]的位置,移動到iLayer原本的位置[0, 0]
因為iLayer貼在漸層layer上,所以移動時出乎意料做出了變色效果~
let animation = CABasicAnimation(keyPath: “position”)animation.fromValue = [0, 40]animation.toValue = [0, 0]animation.duration = 1iLayer.add(animation, forKey: nil)
動畫成品
最後附上漸層&動畫效果的程式碼
漸層方向、位置參考
繪製的形狀加上漸層效果
把線條變成動畫參考