Canvas(1) - Basics

黃子洋
7 min readFeb 6, 2022

Introduction

這篇文章記錄著我在Youtube tutorial + MDN上學到的HTML5 Canvas知識,以下是幾個學習Canvas的重點

  • Create and resize the canvas
  • Draw elements
  • Animate elements
  • Interact with elements

這邊會先以學習Canvas API底下的CanvasRenderingContext2D底下的方法為主來繪製2D相關的東西

What is Canvas

Canvas代表畫布的意思,以我自己的解釋是某個可以讓你使用Canvas api底下的方法來繪製東西的區域,利用HTML tag可以讓我們定義此區域的長寬

<canvas id="my-house" width="300" height="300"></canvas>

Getting the CanvasRenderingContext2D instance

想要在canvas區域上進行2D繪畫,我們必須利用該實例底下提供的各種方法,以下的程式碼做了兩件事

  • 利用Javascript設定了canvas的長與寬
  • 利用getContext(‘2d’)獲取CanvasRenderingContext2D實例,之後可以取用底下API的方法來在canvas上繪製圖形
let canvas = document.querySelector('canvas')canvas.width = window.innerWidthcanvas.height = window.innerHeightconst c = canvas.getContext('2d')

Drawing Elements

Canvas提供了主要兩種方法來繪製圖形,方形和paths(點與點之間的連線)

Rect

  • fillRect(x, y, width, height)- x, y為方形左上角的點

path

要利用path來繪製圖形主要有三個步驟

  • create the path,通常用beginPath()來重新繪製新的path,利用moveTo()來決定新的起始點
  • use drawing commands to draw,在這邊Canvas提供了許多方法能讓我們使用畫出不只直線的線條,也可以利用其他方法畫出curve以及圓弧等等
  • stroke or fill the path to draw the shape,Canvas主要為圖形上色的方法為只畫邊線(stroke)或著填滿內層(fill)

更詳細的資訊可在官方的教學中查看

Clear image blur on mouse-move

在讀了一些Canvas的相關知識後,看了一個在Codepen上的範例,底下的範例來自網路上,主要是在Canvas上偵測使用者的滑鼠移動來移除Image blur,這樣的效果在之後可以應用在網頁上做一些刮刮樂諸如此類的東西,底下是連結。

https://codepen.io/hadabo/pen/NMadqJ

要達到此效果主要需要以下幾個Canvas知識

  1. Drawing element
  2. Styling element
  3. Canvas compositing

來分析一下Code吧

Html

Html這邊沒什麼好解釋的,就只有一個Canvas和一個Button而已

CSS

CSS這邊要記住的是在 id = demo 中有著一個background image而這個background image為一個清晰的圖片如下

from https://postimg.cc/mcyZNqPK

其他的也沒啥好說的,Button套用的CSS主要為position absolute代表著會脫離HTML的正常流,浮在最上層

Javascript

Get canvas instance and create an Html Image object (Line2 - 5)

首先先獲取Canvas2D的實例方便之後的繪製,並且創造一個Image Object,內容如下為一個blur的圖片

from https://postimg.cc/8FSPvDzh

Call the drawImage function to draw on canvas and handle events(Line10 - Line23)

監聽圖片的onLoad事件,並在圖片載入後才進行其他的事件監聽

globalCompositeOperation(合成效果)

通常如果在Canvas上畫上新的圖形時,一般的情況如果和舊圖形重疊,新的圖形會覆蓋上去,但是Canvas底下的API提供給我們彈性能改變這樣的行為

source-over

預設的行為,若新圖與舊圖重疊,新圖則會覆蓋上去

destination-out

若新圖與舊圖重疊,只保留新、舊圖形非重疊的舊圖形區域,其餘皆變為透明

有了上面的觀念後,我們可以看到目前Canvas上有著以下兩層圖片

  • clear image - (canvas’ backgroundImage, will not be affected by the destination-out affect)
  • blur image - (drawImage()繪製上去的)

在上述的Line 10,監聽著每個mousemove事件,並在事件觸發時執行erase function,該erase function會繪製一個圓形(arc),所以當使用者觸發了mouse-move事件後會在Canvas上再繪製一層圖片,導致再觸發mouse-move事件後在Canvas上有以下三層

  • clear image — (canvas’ backgroundImage, will not be affected by the destination-out affect)
  • blur image — (drawImage()繪製上去的)
  • the arc shape according to your current mouse position

依照目前的合成效果 destination-out 會保留新圖(mousemove event建立的arc)與舊圖(blur image)間不重疊的地方,而重疊的地方則會變成透明(顯露底下的clear image),所以藉由這種效果就能產生出類似把blur image刮開的效果

Reset

Reset button所監聽點擊事件所觸發的函式有了上述的觀念也很好理解,先把 globalCompositeOperation 給設置回原來的source-over,再利用drawImage方法把blur image繪製到Canvas上,接著再調整回 destination-out

Conclusion

Canvas在MDN上的教學其實還有非常多的東西,這邊也只講述到一點點,有興趣的可以自己去看。

其實還是有非常多的問題可以給我們去思考,如果要做一個刮刮樂的效果,有沒有辦法達到以下的特效

  • 監聽目前blur image被刮的百分比來做某些操作

目前已經有在網路上找到解答,日後研究一下程式碼可能再紀錄一下如何操作並且做一個小專案來示範。

延伸閱讀

  • 圖片載入處理

https://stackoverflow.com/questions/12354865/image-onload-event-and-browser-cache

--

--