本文作者:HelloGitHub-kalifun
Zdog 項目地址:https://github.com/metafizzy/zdog
在上一篇文章我們介紹了 Zdog 如何使用,接下來這篇文章我將帶領各位利用 Zdog 畫出一個 GitHub 章魚貓(和官方的還是有些差別的)。
一、分析
通過上面的動畫,我們可以對 GitHub 章魚貓進行分析,給我們最直觀的就是 7 部分。頭部、臉、眼睛、鼻子、嘴巴、鬍鬚、耳朵。
頭部:由一個規則的實體圓角矩形組成。臉:有兩個規則的實體圓角矩形組成。第一層是製作陰影,第二層是臉。眼睛:由三個橢圓形組成的眼睛,然後利用複製生成另一隻眼睛。鼻子:由一個橢圓形組成。嘴巴:由一個橢圓形變成一個半圓形則是嘴巴啦。鬍鬚:由兩條曲線進行複製完成。耳朵:由帶圓形底座的方形圓柱組成。通過上面分析我們需要使用的 API:
Zdog.Anchor:將多個形狀或項目合併成一個項目來進行渲染等。Zdog.Group:控制渲染順序,繼承 Anchor,形狀將按照添加到組中的順序呈現。Zdog.RoundedRect:圓角矩形,使用 cornerRadius 設置圓角半徑。Zdog.Cone:帶圓形底座的方形圓柱。Zdog.Shape:自定義形狀的形狀類。Shape 的形狀由其路徑定義。Zdog.TAU:以弧度為單位的完整旋轉。Math.PI * 2 == TAU,但比 PI 更加友好,因為 TAU 直接映射到完整旋轉。copy:針對相同的形狀進行複製。copyGraph:複製帶有子項的項目。二、步驟
Tips:解釋講解均在代碼中以注釋方式展示,請大家注意閱讀。
2.1 創建畫布
是時候開始表演了,首先需要創建畫布。代碼如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>GitHub 章魚貓</title> <style> .zdog-canvas{ display: block; margin: 0px auto; }</style></head><body><!--Zdog在<canvas>或<svg>元素上呈現。width和height屬性以設置大小。--><canvas width="1200" height="800" style="width: 600px;height: 400px"></canvas><!--引入js文件--><script src="https://unpkg.com/zdog@1/dist/zdog.dist.min.js"></script><script> // 1.將選定畫布,進行創作 let illo = new Zdog.Illustration({ element: ".zdog-canvas", dragRotate: true, }); //下面是準備的配色 // 瞳孔的顏色 const colorFeatures = "#AB5C53"; // 頭的顏色 const black = "#211F1F"; // 陰影的顏色 const colorShadow = "#C39B88"; // 皮膚的顏色 const colorSkin = "#E5C0AA"; // 眼睛最外圈的顏色 const white = "#FFF"; //---------------------------- //下面的所有代碼將都在這裡書寫 //---------------------------- illo.updateRenderGraph();</script></body></html>2.2 畫頭
按照我們之前分解的,先畫 GitHub 章魚貓的頭。代碼如下:
// 可以添加到Zdog場景的所有項目都充當錨點。const head = new Zdog.Anchor({ addTo: illo, translate: { // 向y軸移動 y: 15 },});// 具有分離渲染順序的項目。繼承Anchor。const domepiece = new Zdog.Group({ addTo: head});// 真正進行畫頭,是一個實體矩形const noggin = new Zdog.RoundedRect({ addTo: domepiece, // 設置高度和寬度 width: 160, height: 66, // 渲染形狀線並設置線寬。默認筆劃:1。 stroke: 230, // 使用cornerRadius設置圓角半徑 cornerRadius: 20, // 設置顏色 color: black, path: [ { x: -4.5 }, { x: 5.5 } ]});效果如下:
2.3 畫臉
面部的實現代碼如下:
// 我們需要畫下一組圖形,那就是臉。臉被定義為一組const face = new Zdog.Group({ addTo: head, // 將陰影部分進行位置的調節 translate: { // x軸我們不動,保持正中 x: 0, // y軸進行往下移動 y: 36, // 為了3D更加真實,我們需要將臉部往外突出一點。這樣才更加逼真 z: 20 },});// 下面我們開始進行陰影的繪畫,它是由一個實體矩形組成const skinShadow = new Zdog.RoundedRect({ addTo: face, // 設置高度和寬度 width: 100, height: 0, // 渲染形狀線並設置線寬。默認筆劃:1。 stroke: 180, //使用cornerRadius設置圓角半徑 cornerRadius: 40, // 設置顏色 color: colorShadow,});// 下面開始畫臉的部分const skin = new Zdog.RoundedRect({ addTo: face, // 高寬和上面需要一直,為了產生陰影的效果,我們只需要將我們的畫筆的寬度小一點並就可以看到想要的效果。 width: 100, height: 0, // 比之前的陰影部分減小一點 stroke: 170, // 圓角半徑和陰影部分是一致的 cornerRadius: 40, // 設置顏色 color: colorSkin, // 為了和陰影的下半部分重疊,需要將其往下移動 translate: { y: 4.5 }});效果如下:
2.4 畫眼睛
眼睛部分因為是相同的,所以我們會用到 copy 方法,代碼如下:
// 眼睛最外部分為純白色const iris = new Zdog.Ellipse({ addTo: eye, // 渲染內部形狀區域 fill: true, width: 40, height: 56, // 圓角半徑 stroke: 2, // 放大或縮小項目幾何體 scale: 1.5, color: white,});// 瞳孔部分const pupil = new Zdog.Ellipse({ addTo: eye, // 設置長寬 width: 37, height: 56, stroke: 0, fill: true, color: colorFeatures, // 由於它的位置需要更靠近右邊 translate: { x: 3, y: 5, z: 0 },});// 然後是瞳孔裡的小白點const anotherpupil = new Zdog.Ellipse({ addTo: pupil, // 設置寬度 width: 10, height: 10, color: white, fill: true, stroke: 0, // 設置位置 translate: { x: -7, y: -12, z: 3 }});// 這裡將剛繪畫好的左眼複製出來const eyeright = eyeleft.copyGraph({ // 並調整好眼睛的位置 translate: { x: 76, y: 6, z: 80 }, rotate: { y: TAU / -14 }});效果如下:
2.5 畫鼻子
代碼如下:
// 畫鼻子部分,相對很簡單,因為就是一個圓形const nose = new Zdog.Ellipse({ addTo: face, // 設置寬度 width: 6, height: 6, fill: true, stroke: 10, // 設置顏色 color: colorFeatures, // 調整位置 translate: { x: 0, y: 32, z: 74 },});效果如下:
2.6 畫嘴巴
代碼如下:
//接下來是畫嘴巴部分const mouth = new Zdog.Ellipse({ addTo: face, // 設置圓的直徑 diameter: 30, // 將其設置為1/4的圓,我們取值為2,所以獲得半圓 quarters: 2, // 設置圓角半徑 stroke: 4, // 將半圓進行縮放,使其更加逼真 scale: { x: 0.8, y: 1 }, color: colorFeatures, // 將半圓進行旋轉,讓開口向上 rotate: { x: TAU / 2.3, z: TAU / -4 }, // 然後再對其調整合理的位置 translate: { x: 0, y: 46, z: 74 },});效果如下:
2.7 畫耳朵
// 畫耳朵// 帶圓形底座的方形圓柱// 繪畫左耳const ear = new Zdog.Cone({ addTo: head, // 設置圓的直徑 diameter: 120, // 設置長度 length: 90, stroke: false, color: black, // 調整位置 translate: { x: -120, y: -105 }, // 圓角朝向為正z軸,因此需要對其旋轉 rotate: { x: TAU/4, y: TAU/12 },});// 繪畫右耳,將左耳進行複製,移動,旋轉ear.copy({ translate: { x: 120, y: -105 }, rotate: { x: TAU/4, y: TAU/-12 },});效果如下:
2.8 最後一步畫鬍鬚
終於到了最後一步,它即將生靈活現起來。代碼如下:
// 開始進行畫鬍鬚// shape自定義形狀const whisker = new Zdog.Shape({ addTo: whiskers, path: [ // 起始點 { x: 100, y: 0 }, // 曲線的橢圓適合由前一個拐角和終點形成的矩形。 { arc: [ // 拐角 { x: 30, y: -10 }, // corner // 終點 { x: -30, y: 0 }, // end point ]} ], closed: false, // 鬍鬚的寬度 stroke: 4, color: black,});// 左側的另一條鬍鬚,只需要按照上面的設置進行下移即可whisker.copy ({ path: [ { x: 100, y: 0 }, { arc: [ { x: 30, y: -5 }, // corner { x: -30, y: 10 }, // end point ]} ], // 將鬍鬚往下移 translate: { y: 20 },});// 將左側的鬍鬚複製進行移動並旋轉const whiskersright = whiskersleft.copyGraph({ translate: { x: 290, y: 20 }, rotate: { y: TAU/2, },});完成效果如下:
三、總結
文中的代碼已開源到 GitHub 地址:https://github.com/HelloGitHub-Team/Article/blob/master/contents/JavaScript/Zdog_advance/index.html
當我們對代碼進行分析時,其實感覺並沒有想像中的複雜,我們需要精心去進行分析。把需要的形狀先構思好,然後再參考 zdog 文檔,有沒有快捷的方式獲得你想要的形狀。有了這個庫是不是對自己的畫畫能力又有了新的認識呢?這裡是 HelloGitHub 擴充你的武器庫從這裡開始!
閱讀完本文後 「靈魂小畫師」 是否從此誕生了呢?
「旋轉跳躍我閉著眼睛」
四、參考資料
Zdog 官方文檔[1]效果來源[2]參考資料
[1]Zdog官方文檔: https://zzz.dog/
[2]效果來源: https://www.17sucai.com/preview/1750622/2019-08-08/ztocat/index.html
『講解開源項目系列』——讓對開源項目感興趣的人不再畏懼、讓開源項目的發起者不再孤單。跟著我們的文章,你會發現編程的樂趣、使用和發現參與開源項目如此簡單。歡迎留言聯繫我們、加入我們,讓更多人愛上開源、貢獻開源~