用 UIBezierPath 畫出低配版五條悟

Una
彼得潘的 Swift iOS / Flutter App 開發教室
6 min readJul 20, 2023

原本覺得這個作業好像很好玩,沒想到花費好多時間,中途好幾次都想放棄,但頭都洗下去了,只好先寫出一個不太精緻的頭,就決定先暫停。

對比照,沒有比較沒有傷害

這次處理最久的就是眼鏡的漸層

是先使用了漸層的layer,然後將畫出來的鏡片變成mask達到效果,但是不知道為什麼,漸層的圖層x及y軸不是0,0就沒辦法成功顯示,如之後有得到解答再補充上來

func addLeftGlasses() -> CAGradientLayer {
// 建立一個 UIBezierPath 來繪製眼鏡的左邊框形狀
let path = UIBezierPath()
path.move(to: CGPoint(x: 126, y: 295))
path.addQuadCurve(to: CGPoint(x: 148, y: 275), controlPoint: CGPoint(x: 124, y: 282))
path.addQuadCurve(to: CGPoint(x: 183, y: 285), controlPoint: CGPoint(x: 175, y: 269))
path.addQuadCurve(to: CGPoint(x: 159, y: 309), controlPoint: CGPoint(x: 188, y: 300))
path.addQuadCurve(to: CGPoint(x: 126, y: 296), controlPoint: CGPoint(x: 132, y: 313))
path.close()

// 建立一個 CAShapeLayer 來使用前面建立的 Bezier Path,並用於裁剪漸層圖層
let leftGlassesLayer = CAShapeLayer()

// 建立一個 CAGradientLayer 用於建立漸層效果
let gradientLayer = CAGradientLayer()

// 設定漸層圖層的尺寸為 (width: 800, height: 315)
gradientLayer.frame = CGRect(x: 0, y: 0, width: 800, height: 315)

// 將 Bezier Path 設定為裁剪漸層的遮罩
leftGlassesLayer.path = path.cgPath

// 設定漸層的顏色陣列,用於定義漸層的顏色變化
gradientLayer.colors = [
UIColor(cgColor: CGColor(red: 82/255, green: 107/255, blue: 152/255, alpha: 1)).cgColor,
UIColor(cgColor: CGColor(red: 10/255, green: 37/255, blue: 61/255, alpha: 1)).cgColor,
UIColor(cgColor: CGColor(red: 82/255, green: 107/255, blue: 152/255, alpha: 1)).cgColor,
UIColor(cgColor: CGColor(red: 10/255, green: 37/255, blue: 61/255, alpha: 1)).cgColor
]

// 設定漸層的位置,這決定了每個漸層色彩的分佈位置
gradientLayer.locations = [0, 0.5, 0.9, 1]

// 將裁剪圖層設定為漸層圖層的遮罩,以便僅在左邊框的形狀上顯示漸層效果
gradientLayer.mask = leftGlassesLayer

// 回傳建立完成的漸層圖層
return gradientLayer
}

左邊的眼睫毛因為懶得再畫一次,所以也練習用CGAffineTransform處理

func addLeftEyelashes() -> CAShapeLayer {
// 右眼睫毛的path
// ...


// 創建 CAShapeLayer 來展示這個形狀
let leftEyelashes = CAShapeLayer()
// 將 UIBezierPath 轉換為 CGPath,並設定為 CAShapeLayer 的 path
leftEyelashes.path = path.cgPath
// 設定 CAShapeLayer 的 bounds 和 position 來決定圖層的位置和尺寸
let boundingBox = path.cgPath.boundingBox
leftEyelashes.bounds = boundingBox
leftEyelashes.position = CGPoint(x: boundingBox.midX, y: boundingBox.midY)
// 使用 CGAffineTransform 來進行旋轉和翻轉變換,讓左眼睫毛翻轉並旋轉成適合的位置
let transform = CGAffineTransform(scaleX: -1, y: 1).translatedBy(x: 85, y: 20).rotated(by: -50)
leftEyelashes.setAffineTransform(transform)
// 設定填充色、邊框色和邊框寬度來控制圖形的外觀
leftEyelashes.fillColor = UIColor(red: 169/255, green: 185/255, blue: 213/255, alpha: 1).cgColor
leftEyelashes.strokeColor = CGColor(srgbRed: 35/255, green: 35/255, blue: 32/255, alpha: 1)
leftEyelashes.lineWidth = 1

// 回傳 CAShapeLayer 以供使用
return leftEyelashes
}

附上github

--

--