iT邦幫忙

2025 iThome 鐵人賽

DAY 4
3
Modern Web

從 Canvas 到各式各樣的 Web API 之旅系列 第 4

Day 4 - Canvas API 進階用法篇

  • 分享至 

  • xImage
  •  

😀 進入 Canvas 進階!本篇不再只是「畫出東西」,而是學會操作畫布狀態圖形之間的關係
你將會:用座標變換把圖像轉場、用混色疊出設計感、用像素級處理做特效、使用者與圖像互動,最後把成果匯出圖片


進階用法

1. 座標變換:translate / rotate / scale / setTransform

可以把圖片先平移到中心,再做旋轉、放大,可用來做卡牌翻轉或 UI 動畫。

// 移動畫布座標。將原點平移到 (110, 30)
ctx.translate(110, 30);

// 旋轉畫布座標。以目前原點為中心,順時針旋轉 30°
ctx.rotate((30 * Math.PI) / 180);

// 縮放畫布。將繪圖寬度縮小為 30%,高度縮小為 80%
ctx.scale(0.3, 0.8);

// 覆蓋設定畫布縮放、旋轉、移動 ctx.setTransform(水平缩放, 水平旋轉, 垂直旋轉, 垂直缩放, 水平移動, 垂直移動)
ctx.setTransform(1, 0, 0, 1, 0, 0);

https://ithelp.ithome.com.tw/upload/images/20250917/20177984qdWaE4iIKH.png

2. 複合與混色:globalCompositeOperation

設定 新繪製圖形 與 畫布上已存在圖形 在重疊時的混合方式。
工作原理與 Photoshop / Figma 的圖層混合模式 類似,可以實現多種疊色、剪裁、透明等效果。

// 設定繪圖的合成模式為 multiply,顏色相乘,常用於製作陰影或加深效果
ctx.globalCompositeOperation = "multiply";

ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);

ctx.fillStyle = "red";
ctx.fillRect(50, 50, 100, 100);

https://ithelp.ithome.com.tw/upload/images/20250917/20177984OVfAggYrel.png

3. 像素級操作:getImageData/putImageData

逐像素調整可做馬賽克、邊緣偵測等自訂影像特效。

// 取得畫布上 (10, 20) 起點、寬 80、高 230 區域的像素資料
const imageData = ctx.getImageData(10, 20, 80, 230);

// 將這份像素資料貼到畫布上的 (20, 0) 位置
ctx.putImageData(imageData, 20, 0);

https://ithelp.ithome.com.tw/upload/images/20250917/20177984mKzcqWBJvo.png

4. 事件互動與命中測試(Hit Testing)

Canvas 本身只有一個 <canvas> 元素,它不像 DOM 裡的 <div>、<button> 那樣能直接綁定事件給每個子元素。
所以當使用者點擊 Canvas 時,你只能得到「在 Canvas 上的座標」,之後要靠程式自己去判斷點擊的位置是不是在某個圖形上。

const rect = { x: 50, y: 50, width: 100, height: 80, color: "blue" };

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = rect.color;
    ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
}
draw();

canvas.addEventListener("click", (e) => {
    const rectBounds = canvas.getBoundingClientRect();
    const mouseX = e.clientX - rectBounds.left;
    const mouseY = e.clientY - rectBounds.top;

    // 命中測試:判斷滑鼠是否在方形內
    if (
        mouseX >= rect.x &&
        mouseX <= rect.x + rect.width &&
        mouseY >= rect.y &&
        mouseY <= rect.y + rect.height
    ) {
        rect.color = rect.color === "blue" ? "red" : "blue"; // 點中就換色
        draw();
    }
});

5. 匯出與持久化:toDataURL、toBlob

Canvas 可以將畫布內容匯出成圖片,方便下載、分享或上傳伺服器。
常用兩種方法:

  1. 產生 Base64 圖片字串(toDataURL) 
    適合用於即時預覽、小圖分享、或直接嵌入 HTML。
    缺點:大圖會產生很長的字串,效能較差。
const dataURL = canvas.toDataURL("image/png"); // 預設 "image/png"
const img = document.createElement("img");
img.src = dataURL;
document.body.appendChild(img); // 將圖片添加到頁面上
  1. 產生 Blob 物件(toBlob)
    適合大圖下載、檔案上傳、或需要進一步處理二進位資料時。
canvas.toBlob((blob) => {
    const blobUrl = URL.createObjectURL(blob);
    const img = document.createElement("img");
    img.src = blobUrl;
    document.body.appendChild(img); // 將圖片添加到頁面上

    img.onload = () => {
        URL.revokeObjectURL(blobUrl); // 釋放記憶體
    };
}, "image/png"); // 預設 "image/png"

範例 Demo

介紹完進階用法,肯定要做個有趣的範例,才能有所體會~ 歡迎玩玩看 🥳

用 Canvas 做一張「濾鏡與圖形編輯器」:背景為多彩漸層,圖形可拖曳、旋轉、縮放,並可套用濾鏡與圖形混色,最後匯出 PNG 圖檔。


👉 歡迎追蹤這個系列,我會從 Canvas 開始,一步步帶你認識更多 Web API 🎯


上一篇
Day 3 - Canvas API 基本用法篇
下一篇
Day 5 - 已經有 DOM + CSS,為何需要 Canvas!?
系列文
從 Canvas 到各式各樣的 Web API 之旅8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言