畫筆的功能

大家都有玩過小畫家,我們可以使用小畫家的畫筆,輕鬆的畫出一些我們想要的圖案,相當的趣味也非常的方便

畫筆的功後續也演變為一些電子簽證的機制,最近剛好也碰到了一些類似的需求

決定在下方做個製作上的紀錄,下方提供了一個比較陽春的版本當作範例,也是為了方便理解他的製作方式


進入說明

HTML 架構如下所示:

<canvas id="canvas"></canvas>

宣告變數 與 事件監聽

宣告變數

// Canvas DOM 元素 
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

//起始點座標
let x1= 0
let y1= 0

// 終點座標
let x2= 0
let y2= 0

事件監聽

如果你剛剛有稍微玩了一下上面的 demo , 你不難發現這個範例所使用的事件監聽,分別是 按下滑鼠 mousedown 、 移動滑鼠 mousemove 與 放開滑鼠 mouseup

而在手機或是行動裝置上則是 按下滑鼠 ontouchstart 、 移動滑鼠 ontouchmove 與 放開滑鼠 touchend

// 宣告一個 hasTouchEvent 變數,來檢查是否有 touch 的事件存在
const hasTouchEvent = 'ontouchstart' in window ? true : false

// 透過上方的 hasTouchEvent 來決定要監聽的是 mouse 還是 touch 的事件
const downEvent = hasTouchEvent ? 'ontouchstart' : 'mousedown'
const moveEvent = hasTouchEvent ? 'ontouchmove' : 'mousemove'
const upEvent = hasTouchEvent ? 'touchend' : 'mouseup'

// 宣告 isMouseActive 為滑鼠點擊的狀態,因為我們需要滑鼠在 mousedown 的狀態時,才會監聽 mousemove 的狀態
let isMouseActive = false

藉由上方的事件參數,就可以達到我們想要的事件監聽了

canvas.addEventListener(downEvent, function(e){
  isMouseActive = true
})

canvas.addEventListener(moveEvent, function(e){
  if(mouseAvtive){
    return
  }
})

canvas.addEventListener(upEvent, function(e){
  isMouseActive = false
})

Canvas 畫筆 製作

有了上述的 參數 與 事件監聽 我們就可以開始製作畫筆的功能了,這邊我照著事件順序依依進行說明:

首先我們必須要在 mousedown 的當下,找到當前點擊的座標為起始座標,並設定一些畫出來線條的寬度

canvas.addEventListener(downEvent, function(e){
  isMouseActive = true  
  x1 = e.offsetX
  y1 = e.offsetY

  ctx.lineWidth = 5 // 線條寬度
  ctx.lineCap = 'round' // 線條兩端圓弧
  ctx.lineJoin = 'round' // 線條折角圓弧
})

event.offsetX、event.offsetY 滑鼠相對於事件源元素(srcElement)的 X, Y 坐標

接著在 mousemove 中,使用前面得到的起始座標當作起始點,並以 mousemove 中的得到座標當作目標

並且在繪製結束後,使用終點目標來更新其實座標 (使 mousemove 的事件繪圖是保持連貫的)

canvas.addEventListener(moveEvent, function(e){
      if(!isMouseActive){
        return
      }
      // 取得終點座標
      x2 = e.offsetX
      y2 = e.offsetY

      // 開始繪圖
      ctx.beginPath()
      ctx.moveTo(x1, y1)
      ctx.lineTo(x2, y2)
      ctx.stroke()

      // 更新起始點座標
      x1 = x2
      y1 = y2
})

這樣基本畫筆的功能就算是完成了,十分容易


完整的代碼如下:

// Canvas DOM 元素 
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

//起始點座標
let x1= 0
let y1= 0

// 終點座標
let x2= 0
let y2= 0

// 宣告一個 hasTouchEvent 變數,來檢查是否有 touch 的事件存在
const hasTouchEvent = 'ontouchstart' in window ? true : false

// 透過上方的 hasTouchEvent 來決定要監聽的是 mouse 還是 touch 的事件
const downEvent = hasTouchEvent ? 'ontouchstart' : 'mousedown'
const moveEvent = hasTouchEvent ? 'ontouchmove' : 'mousemove'
const upEvent = hasTouchEvent ? 'touchend' : 'mouseup'

// 宣告 isMouseActive 為滑鼠點擊的狀態,因為我們需要滑鼠在 mousedown 的狀態時,才會監聽 mousemove 的狀態
let isMouseActive = false

canvas.addEventListener(downEvent, function(e){
  isMouseActive = true
})

canvas.addEventListener(downEvent, function(e){
  isMouseActive = true  
  x1 = e.offsetX
  y1 = e.offsetY

  ctx.lineWidth = 5
  ctx.lineCap = 'round'
  ctx.lineJoin = 'round'
})

canvas.addEventListener(moveEvent, function(e){
      if(!isMouseActive){
        return
      }
      // 取得終點座標
      x2 = e.offsetX
      y2 = e.offsetY

      // 開始繪圖
      ctx.beginPath()
      ctx.moveTo(x1, y1)
      ctx.lineTo(x2, y2)
      ctx.stroke()

      // 更新起始點座標
      x1 = x2
      y1 = y2
})

canvas.addEventListener(upEvent, function(e){
  isMouseActive = false
})

Summary
[Canvas] 使用 JavaScript 實作 canvas 畫筆的功能
Article Name
[Canvas] 使用 JavaScript 實作 canvas 畫筆的功能
Description
大家都有玩過小畫家,我們可以使用小畫家的畫筆,輕鬆的畫出一些我們想要的圖案,相當的趣味也非常的方便畫筆的功後續也演變為一些電子簽證的機制,最近剛好也碰到了一些類似的需求決定在下方做個製作上的紀錄,下方提供了一個比較陽春的版本當作範例,也是為了方便理解他的製作方式
Author

Facebook 功能: