iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
JavaScript

火箭通關JS30系列 第 8

JS30-08 - Fun with HTML5 Canvas

  • 分享至 

  • xImage
  •  

課程目的:

本次的內容是利用Html5的Canvas元素製作畫布,讓我們可以在網頁上的畫布區塊做簡單的塗鴉
作品實做

本次功能實作重點:

  • 元素選取與繪圖環境設定以及繪圖參數
  • 定義繪圖函式
  • 監聽繪圖事件
  • 設定繪圖函式
  • 點選按鈕清除畫布內容

元素選取與繪圖環境設定以及繪圖參數

      const canvas = document.querySelector("#draw");
      const btn = document.querySelector(".btn");
      const ctx = canvas.getContext("2d");
      ctx.strokeStyle = "#a1d2fa"; //線條的顏色
      ctx.lineJoin = "round"; //兩條線相交時的連接樣式為圓角
      ctx.lineCap = "round"; //決定線條末端的樣式為圓角
      ctx.lineWidth = 20; //設定線的寬度
      
      let isDrawing = false;
      let lestX = 0;
      let lestY = 0;
      let hue = 0;
      let increasing = true; //用於追蹤線條寬度

監聽繪圖事件

canvas.addEventListener("mousedown", (e) => {
        isDrawing = true;
        [lestX, lestY] = [e.offsetX, e.offsetY];
      });

canvas.addEventListener("mousemove", draw);

canvas.addEventListener("mouseup", () => (isDrawing = false)); //事件在使用者鬆開滑鼠按鍵時觸發。
canvas.addEventListener("mouseout", () => (isDrawing = false)); //事件在使用者的滑鼠指針移出畫布區域時觸發

isDrawing 作為類似開關的作用,當我們落筆開關會開起來(true),而放開滑鼠以及滑鼠範圍超出畫布時會關掉(true)

定義繪圖函式

 function draw(e) {
        if (!isDrawing) return;
        ctx.beginPath(); //開始新的路徑
        ctx.strokeStyle = `hsl(${hue},80% , 70%)`;
        ctx.moveTo(lestX, lestY);
        ctx.lineTo(e.offsetX, e.offsetY);
        ctx.stroke();
        [lestX, lestY] = [e.offsetX, e.offsetY];

        hue++;
        //避免數值超出360,重製回0
        if (hue >= 360) {
          hue = 0;
        }

        if (ctx.lineWidth >= 50 || ctx.lineWidth <= 10) {
           increasing = !increasing;
        }
        if (increasing) {
           ctx.lineWidth++;
         } else {
          ctx.lineWidth--;
         }
      }

if (!isDrawing) return 如果不是繪圖狀態則跳出函式
moveTo(lestX, lestY) 為滑鼠點擊時的座標,作為下筆的第一個點
lineTo() 將目前子路徑的最後一點與指定的 (e.offsetX, e.offsetY) 座標以直線段相連ctx.stroke()
ctx.stroke() 繪製目前或指定的路徑,而我們用來描繪目前移動的路徑

[lestX, lestY] = [e.offsetX, e.offsetY] 因為我們是當我們監聽到"mousemove”時,此函數會一直更新,於是必須時刻更新座標才可以使座標與描繪的點一致

ctx.lineWidth >= 50 || ctx.lineWidth <= 10) 當線條的寬度大於等於50或者小於等於10的時候,會使increasing 反轉 ,而increasing 做為調整線條寬度的開關,假設最初設定為true,線條寬度則會執行ctx.lineWidth++(增加)直到寬度超過50時,increasing 會反轉為true,便會開始執行ctx.lineWidth--(寬度減少)

點選按鈕清除畫布內容

 btn.addEventListener("click", () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
      });

這是我另外做的一個功能~當我按下網頁上的按鈕時可以將畫布清除為空白畫布的狀態
(x, y, width, height)清空給定矩形內的指定像素,x, y,各為畫布上的座標,width, height 則是用來設定清空區域的大小

導讀文件以及學習資源

JS30


上一篇
JS30-07 - Array Cardio Day 2
下一篇
JS30-09 - Dev Tools Domination
系列文
火箭通關JS3014
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言