JS地下城[7F] - Canvas畫布

李炳寬
李炳寬
Nov 1 · 10 min read

- 前言 -

一路勇闖地下城到了第七層,因為自認文筆不好又詞窮,本來沒有計劃寫部落格的,但好死不死第七層遇到了我心中最軟的一塊 Canva…

初期進入前端領域時都著重在網頁切版與 JavaScript,認為自己應該不太會應用到 Canvas,所以一直沒有把它排進我的學習清單中,當然之後網站看多了,就有發現 Canvas 的應用其實非常豐富,幸好這次也有機會來好好學習一下了。


- 重點技術 -

  1. HTML5 Canvas 運用
  2. JavaScript / jQuery 程式設計

- BOSS 攻略-

所以,如何開始 ?

因為真的沒碰過,實在不知道從何開始,只知道 HTML 裡有 <canvas> 的標籤,但標籤裡要放些甚麼 ?

看了看 MDN ,原來需要取得 <canvas> 的渲染環境,用getContext() 輸入參數 2d 來取得 2D 的繪圖環境,這樣後面才能使用相關的繪圖函式。

到這裡卻發現畫布只有小小一塊,這樣怎麼夠畫呢?雖然可以用 CSS 來調整 Canvas 的大小,但官方建議使用 <canvas>widthheight 來設定,不然在繪圖上會有比例的問題。

這樣就能根據視窗大小來設定 Canvas 的屬性了。

畫布有了,然後呢?

現在準備好一張全新的空白畫布了,但該如何在上面畫圖呢 ?先來看看該怎麼畫出直線吧 !
現在已經可以使用相關的繪圖函式了,畫直線的話需要三個基本的方法。

做完這三個步驟後卻發現畫布上甚麼也沒有,因為剛剛只做到了告知的動作,並還沒叫電腦實際畫出來。

我只有鉛筆嗎?

成功畫出第一筆後卻發現只有一條細細醜醜的黑線,畫筆的顏色粗細該怎麼調整呢?

這樣我們就有隨心所欲可調整的畫筆了 !

互動的開始

畫筆、畫布都有了,但總不能叫使用者自己打程式來畫圖吧?而且現在還只能畫直線…

為了讓使用者可以利用滑鼠來繪圖,必須要把上面的畫直線方法來跟滑鼠事件連動,而各種的筆畫線條實際上是用長度只有 1pixel 的直線連起來的。

簡單來說我們就是利用滑鼠移動的事件來不斷取得新座標,並且把座標丟進 moveTo()lineTo() 之中,而滑鼠按下和放開只是啟動和關閉的作用。

進階的功能

有了基本的繪圖功能,來思考該如何達到「復原」和「重做」吧!

看了看文件,原本發現 Path2D Objectsave(), restore() 好像蠻符合我們要的概念的。

Path2D Object 是利用 MyPath = new Path2D() 來建立一個路徑物件,可以事先存取路徑再利用 ctx.stroke(MyPath) 畫出來,但這個物件只能存取路徑卻無法存取畫筆顏色和樣式。

save(), restore() 可以存取畫布狀態並重新呼叫來畫出,但一次只能存取一個狀態到 stack 中,看來也不適用。

只好看看大家怎麼做的,原來要利用toDataURL() 來「存入」和「讀取」。
toDataURL() 可以幫我們把畫布狀態編碼為 base64 的字串,這樣我們就可以方便存取啦!

先來定義兩個變數 step 用來紀錄步數 history 用來紀錄每一步的筆畫。每畫一筆步數就 +1,並且把base64 存進 history 中。

但為何中間要有一個判斷式呢?

現在每一筆都被記錄下來了,那該怎麼把紀錄給呼叫回來呢?

這樣復原就完成了,而重做的概念剛好就是相反的囉。而其實裡面也藏了清除畫布的方法 ctx.clearRect(0,0,canvasWidth,canvasHeight),這樣 ClearAll就可以直接拔出來用了。

保存美好

經過復原重做,應該對保存有些靈感了吧? 沒錯,又是toDataURL()

在按下保存後,把畫布狀態利用toDataURL() 編碼並設定在連結中,這樣按下去後就可以下載囉~

這樣我們的繪圖板就完成啦!剩下顏色選擇和筆畫粗細的調整,相信對能到達第七層的勇者來說,肯定是一塊小蛋糕的!讓我們朝下一關邁進吧!!


- 番外篇 -

相信許多勇者在思考額外功能的時候都是朝著新增顏色的方向前進,而我也不例。

利用陣列來管理顏色,只要使用者新增顏色,就會更新陣列資料,並且利用forEach() 來生成 DOM :

而我主要想要分享的是判斷式中我呼叫的一個名為 isDark 的 function,這個函式是做什麼用的呢?

大家知道顏色有深有淺,但我的勾勾卻是黑色的,如果在深色上是看不清楚的,那我該如何知道使用者選的顏色是深是淺呢?

因為陣列中的資料都是#FFFFFF 帶有井字號的16進位色碼,我們把字串拆開並且轉為10進位的數字,這樣我們就輕易的拿到顏色的 RGB 啦~~

最後用一個神秘的算式就能知道這個顏色是深是淺,而我們就能給他對應的白勾勾與黑勾勾了!


Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade