火車環島3671藍皮普快紀念品
第一次的SwiftUI練習題
中秋節過後去了一趟一個人的火車環島之旅,沒有買什麼紀念品,剛好最近iOS推出了SwiftUI,看到好多同學都在練習,就來畫3671藍皮普快列車吧!
遊記看這裡:
第一次的SwiftUI練習
成品:
火車繪製參考我自己拍的照片:
背景圖照片來源:Photo by freestocks.org on Unsplash
背景:
在 ZStack 裡加 Image作為背景,必須先呼叫 function resizable(),讓圖片變成可以縮放大小,使用 scaledToFit讓圖片維持原比例不變形,再用frame設定顯示大小。
//背景圖Image("sky").resizable().scaledToFit().frame(width: 900, height: 900)
火車:
火車的繪製就是一層疊一層的概念。
- 先畫車輪:生成 Path 時搭配參數 ellipseIn 繪製圓形。
//車輪Path(ellipseIn: CGRect(x: 350, y: 300, width: 100, height: 100))Path(ellipseIn: CGRect(x: 455, y: 270, width: 90, height: 90))Path(ellipseIn: CGRect(x: 552, y: 255, width: 70, height: 70))Path(ellipseIn: CGRect(x: 627, y: 239, width: 45, height: 45))}
2.再畫車廂:車廂的整體繪製使用addLine,再用closeSubpath()包起來,我會畫兩層,底層為底色(使用.fill),再疊一層框線(使用.stroke)。
//車廂身區塊Path{ (path) inpath.move(to: CGPoint(x: 604, y: 215))path.addLine(to: CGPoint(x:670 , y: 240))path.addLine(to: CGPoint(x: 675, y: 255))path.addLine(to: CGPoint(x: 607, y: 285))path.addLine(to: CGPoint(x: 607, y: 223))path.addLine(to: CGPoint(x: 604, y: 215))path.closeSubpath()}.fill(Color(red: 0/255, green: 51/255, blue:102/255))//車廂身輪廓Path{ (path) inpath.move(to: CGPoint(x: 604, y: 215))path.addLine(to: CGPoint(x:670 , y: 240))path.addLine(to: CGPoint(x: 675, y: 255))path.addLine(to: CGPoint(x: 607, y: 285))path.addLine(to: CGPoint(x: 607, y: 223))path.addLine(to: CGPoint(x: 604, y: 215))path.closeSubpath()}.stroke(Color(red: 0, green: 0, blue: 0), lineWidth: 2)
3.車窗:車頭的車窗還是使用addLine再用closeSubpath()包起來,第一節車廂的車窗很小格,乾脆就畫粗線條代表車廂。
車頭車窗:
//窗一Path{ (path) inpath.move(to: CGPoint(x: 220, y:183))path.addLine(to: CGPoint(x: 235, y:180))path.addLine(to: CGPoint(x: 235, y:203))path.addLine(to: CGPoint(x: 220, y:203))path.addLine(to: CGPoint(x: 220, y:183))path.closeSubpath()}.fill(Color(red: 94/255, green: 134/255, blue: 193/255))//窗二Path{ (path) inpath.move(to: CGPoint(x: 245, y:180))path.addLine(to: CGPoint(x: 270, y:177))path.addLine(to: CGPoint(x: 270, y:201))path.addLine(to: CGPoint(x: 245, y:202))path.addLine(to: CGPoint(x: 245, y:180))path.closeSubpath()}.fill(Color(red: 94/255, green: 134/255, blue: 193/255))
車廂車窗:
//第一節車廂車窗Path{ (path) inpath.move(to: CGPoint(x: 622, y: 240))path.addLine(to: CGPoint(x:622 , y:245))path.move(to: CGPoint(x: 632, y: 240))path.addLine(to: CGPoint(x:632 , y:245))path.move(to: CGPoint(x: 642, y: 240))path.addLine(to: CGPoint(x:642 , y:245))path.move(to: CGPoint(x: 652, y: 240))path.addLine(to: CGPoint(x:652 , y:245))path.move(to: CGPoint(x: 662, y: 241))path.addLine(to: CGPoint(x:662 , y:245))}.stroke(Color(red: 64/255, green: 64/255, blue: 64/255), lineWidth: 5 )//用lineWidth設定線條粗度為5
4.車身彩繪:車頭的白色弧形彩繪線條使用addQuadCurve去畫圓弧形狀,其他車身白色彩繪線依然使用addLine。
//車頭彩繪右Path{ (path) inpath.move(to: CGPoint(x: 200, y: 310))path.addQuadCurve(to: CGPoint(x: 265, y: 235 ), control: CGPoint(x:225 , y: 238))path.addLine(to: CGPoint(x: 265, y: 255))path.addQuadCurve(to: CGPoint(x: 200, y: 310 ), control: CGPoint(x:225 , y: 258))path.closeSubpath()}.fill(Color(red: 255, green: 255, blue: 255))//車頭彩繪左Path{ (path) inpath.move(to: CGPoint(x: 200, y: 310))path.addQuadCurve(to: CGPoint(x: 175 , y: 235 ), control: CGPoint(x:185 , y: 238))path.addLine(to: CGPoint(x: 175, y: 255))path.addQuadCurve(to: CGPoint(x: 200, y: 310 ), control: CGPoint(x:185 , y: 258))path.closeSubpath()}.fill(Color(red: 255, green: 255, blue: 255))//車頭彩繪左ㄧPath{ (path) inpath.move(to: CGPoint(x: 267, y: 235 ))path.addLine(to: CGPoint(x: 332, y: 235))path.addLine(to: CGPoint(x: 333, y: 255))path.addLine(to: CGPoint(x: 268, y: 255))path.addLine(to: CGPoint(x: 267, y: 235))path.closeSubpath()}.fill(Color(red: 255, green: 255, blue: 255))//車頭彩繪左二Path{ (path) inpath.move(to: CGPoint(x: 334, y: 235))path.addLine(to: CGPoint(x: 380, y: 235))path.addLine(to: CGPoint(x: 381, y: 255))path.addLine(to: CGPoint(x: 336, y: 255))path.addLine(to: CGPoint(x: 334, y: 235))path.closeSubpath()}.fill(Color(red: 255, green: 255, blue: 255))
5.車燈:為了讓車燈疊在最上層,車燈是最後才畫的,一樣搭配參數 ellipseIn 繪製圓形,再用.fill加入黃色代表車燈。
Group{Path(ellipseIn: CGRect(x: 179, y: 237, width: 10, height: 10)).fill(Color(red: 255/255, green: 255/255, blue: 0/255))Path(ellipseIn: CGRect(x: 238, y: 237, width: 10, height: 10)).fill(Color(red: 255/255, green: 255/255, blue: 0/255))Path(ellipseIn: CGRect(x: 266, y: 132, width: 15, height: 15)).fill(Color(red: 255/255, green: 255/255, blue: 0/255))Path(ellipseIn: CGRect(x: 266, y: 150, width: 15, height: 15)).fill(Color(red: 255/255, green: 255/255, blue: 0/255))}
畫出來的成品我還蠻滿意的,覺得很美:)
完整程式碼請見GitHub:
參考文章:
如果有值得大家參考的地方再麻煩大家幫我拍拍手喲,謝謝大家耐心閱讀🙇♀️