iT邦幫忙

3

JS30 Day 8 - Fun with HTML5 Canvas 學習筆記

今天主要利用 <canvas> 這個 HTML 元素來做出我們要的功能,我們可以利用程式腳本在這個元素上繪圖(通常是用 JS)、合成圖片或動畫效果。

而我們今天所要的功能為在畫布按下鼠標並拖曳可以畫出色彩,並會線條改變粗細,放開或離開畫布就停止。

首先,獲取canvas元素。


    <canvas id="draw" width="800" height="800"></canvas>
    let canvas = document.querySelector('#draw');
 

HTMLCanvasElement.getContext():

由於一開始canvas為空白,需先存取渲染環境,在上面繪圖,然後才會顯現影像
getContext():此方法可以取得渲染環境及其繪圖函數(function),參數有'2d',
'webgl'(3d)等等。此處用2d


      let ctx = canvas.getContext('2d');
      

設置canvas下的樣式及狀態


      // 設置畫畫狀態
      let drawing = false;
      // 用來判斷線條變粗變細
      let direction = -1;
      // 設置初始座標
      let x = 0,y = 0;
      // 線條寬度(預設為1)
      let lineWidth = 50;
      ctx.lineWidth = lineWidth;

      // 端點樣式:有 'square'(方)、'round' (圓)、(預設為butt(切平))
      ctx.lineCap = 'round';
      // 交叉點樣式:有'bevel'(斜角)'roun'(圓)、(預設為butt(尖角))
      ctx.lineJoin = 'round';
      

hsl():css函數,使用色相飽和度、亮度模型(HSL)定義顏色。

顏色屬性HSL Colors,此屬性可透過色相環上的角度來取得不同顏色
hsl(hue, saturation(飽和度), lightness(亮度));

CanvasRenderingContext2D.strokeStyle圖形邊線的顏色和樣式。 預設 #000 (黑色).
CanvasRenderingContext2D.fillStyle 圖形內部的顏色和樣式。預設 #000 (黑色).


      // 設置顏色初始值(角度)
      let colorDeg = 0;
      ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
      

最後我們加上滑鼠事件來進行處理

mousedown:當滑鼠按下表示開始畫畫,並記錄初始位置


      canvas.addEventListener('mousedown', (e) => {
        drawing = true;
        // 紀錄當前滑鼠點擊的位置
        [x, y] = [e.offsetX, e.offsetY];
      });
      

mousemove:當滑鼠移動(連續觸發)開始畫圖

CanvasRenderingContext2D.beginPath():此方法可創建一個新的路徑(表示開始畫)。

CanvasRenderingContext2D.moveTo():將一個新路徑的起始點移動到(x,y)坐標(剛剛滑鼠點擊紀錄的位置)

CanvasRenderingContext2D.lineTo():使用直線連接路徑最後的點到x,y坐標(當前最後點的位置)。

CanvasRenderingContext2D.stroke():根據當前的畫線樣式,渲染出當前或已經存在的路徑的方法。

canvas.addEventListener('mousemove', (e) => {
        if (!drawing) {
          return
        }
        // console.log('draw');
        // 開始畫
        ctx.beginPath();
        // 每當移動(+1度)就改變色環角度
        colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;

        // 如果減到小於1或+到大於50,就切換方向(變粗或變細)
        if (lineWidth < 1 || lineWidth > 50) {
          direction *= -1;
        }
        // 每當移動就改變粗細
        lineWidth += direction;
        ctx.lineWidth = lineWidth;
        
        ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
        
        // 新路徑的起始點
        ctx.moveTo(x, y);
        // 使用直線連接路徑(當前的點到起始點)
        ctx.lineTo(e.offsetX, e.offsetY);
        
        // 更新紀錄當前滑鼠點擊的位置
        [x, y] = [e.offsetX, e.offsetY];
        
        // 如果不加上storke,就只是連起來,但沒畫出來,一定要加上storke來渲染
        ctx.stroke();
      });

mouseup、mouseleave:當滑鼠放開或離開就停止。

   canvas.addEventListener('mouseup', () => {
    drawing = false;
  });
  // 不使用mouseout,因為會連續觸發
  canvas.addEventListener('mouseleave', () => {
    drawing = false;
  });
  
  

最後結果如下

https://ithelp.ithome.com.tw/upload/images/20200525/20126182mQy4t8L6F3.png


尚未有邦友留言

立即登入留言