昨天介紹了 Canvas 的誕生與崛起,瞭解了 Canvas 的重要性後,終於要開始實作了!
正文開始前先簡介,Canvas API 是 HTML5 Web API 中的重要功能,為開發者提供了強大的 2D 繪圖工具,能用於動畫、互動遊戲、數據可視化(像是前端熟悉的 EChart)。
😀 我剛開始學習前端時,有上幾堂 Canvas 課程,短短幾堂課只覺得好麻煩XD,有很多細節跟數學計算,UI/UX 更是挑戰。後來做專案時幸好有成熟的 Library 讓開發方便很多,近年來有 AI 幫忙計算更是方便~ Canvas 其實可以做很多有趣的事,本來想在這一篇介紹基本用法以及進階用法,但篇幅太長,只好把進階用法挪到明天,基本用法比較無趣,但基礎不可略過,就請先忍忍XD
Canvas 的第一步是建立 <canvas>
元素,並取得 2D 繪圖上下文(context)。這個 context 提供了所有繪圖方法。
width
和 height
屬性必須直接寫在 <canvas>
標籤上,否則用 CSS 設定會導致畫面模糊(尤其在高 DPI 螢幕)。
請參考附圖及程式碼
<canvas id="tutorial" width="200" height="200"></canvas>
var canvas = document.getElementById("tutorial");
// 取得 2D 繪圖 context
var ctx = canvas.getContext("2d");
直接繪製:fillRect
會立即畫到畫布上,常用於資料視覺化、遊戲地圖格子。
路徑繪製:採用先「建立路徑」、再「渲染」。用 beginPath / moveTo / lineTo / arc…
建立路徑 → 最後用 fill()
或 stroke()
把路徑畫到畫布上。
// 繪製實心矩形(x=50, y=50, 寬=100, 高=100)
ctx.fillRect(50, 50, 100, 100);
// 清除(x=50, y=50, 25×25)區域
ctx.clearRect(50, 50, 25, 25);
// 描邊矩形(x=25, y=50, 50×150)
ctx.strokeRect(25, 50, 50, 150);
// 開始新路徑
ctx.beginPath();
// 起點(75,50)
ctx.moveTo(75, 50);
// lineTo:將當前路徑的最後一個點,與指定座標以直線相連,不會直接渲染內容
ctx.lineTo(100, 75); // 連到(100,75)
ctx.lineTo(100, 25); // 再連到(100,25)
// 要將路徑繪製到畫布上,可以使用 fill() 或 stroke()
// 自動回到起點
ctx.closePath();
// 以目前 fillStyle 填滿三角形
ctx.fill();
基本圖形示意圖
Canvas 支援多種顏色、線條樣式與漸層,讓圖形更豐富。
// 設定圖形的顏色
ctx.fillStyle = "rgb(200 0 0)";
// 設定圖形邊框的顏色
ctx.strokeStyle = "#09f";
// 設定線的寬度
ctx.lineWidth = 15;
// 設定線末端的樣式
ctx.lineCap = "round";
Canvas 可以直接在畫布上繪製文字,適合標註、分數顯示、資料標籤等。
ctx.font = "40px serif";
// (x=0, y=100) 填滿文字
ctx.fillText("Hello world", 0, 100);
// (x=0, y=50) 描邊文字
ctx.strokeText("Hello world", 0, 50);
設定文字示意圖
Canvas 除了繪製基本圖形,也能將圖片渲染到畫布上,這是製作遊戲、圖片編輯器、資料視覺化等應用的基礎。
跨域圖片(CORS)問題:如果圖片來源不是同一個網域,且未設置 crossOrigin
,或圖片伺服器未允許 CORS,則後續使用 getImageData
等 API 會報錯(SecurityError)。
後面會有一天專門來介紹瀏覽器針對 Canvas 的安全設計,敬請期待!
drawImage
支援多種參數,可以用來縮放、裁切圖片。
const img = new Image();
img.crossOrigin = "anonymous";
img.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/300px-PNG_transparency_demonstration_1.png";
img.onload = () => {
ctx.drawImage(img, 0, 10); // 將整張圖片貼到畫布 (x=0, y=10)
};
介紹完基礎用法,肯定要做個有趣的範例,才不會看到睡著~ 歡迎玩玩看 🥳
用 Canvas 做一張「極簡相片卡」:背景提供兩種純動畫(Stars/Snow),可上傳一張相片自動置中,一鍵匯出 PNG。星空置於相片後方;飄雪分為後景與前景兩層,帶出自然景深。
👉 歡迎追蹤這個系列,我會從 Canvas 開始,一步步帶你認識更多 Web API 🎯