😀 進入 Canvas 進階!本篇不再只是「畫出東西」,而是學會操作畫布狀態與圖形之間的關係。
你將會:用座標變換把圖像轉場、用混色疊出設計感、用像素級處理做特效、使用者與圖像互動,最後把成果匯出圖片。
可以把圖片先平移到中心,再做旋轉、放大,可用來做卡牌翻轉或 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);
設定 新繪製圖形 與 畫布上已存在圖形 在重疊時的混合方式。
工作原理與 Photoshop / Figma 的圖層混合模式 類似,可以實現多種疊色、剪裁、透明等效果。
// 設定繪圖的合成模式為 multiply,顏色相乘,常用於製作陰影或加深效果
ctx.globalCompositeOperation = "multiply";
ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);
ctx.fillStyle = "red";
ctx.fillRect(50, 50, 100, 100);
逐像素調整可做馬賽克、邊緣偵測等自訂影像特效。
// 取得畫布上 (10, 20) 起點、寬 80、高 230 區域的像素資料
const imageData = ctx.getImageData(10, 20, 80, 230);
// 將這份像素資料貼到畫布上的 (20, 0) 位置
ctx.putImageData(imageData, 20, 0);
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();
}
});
Canvas 可以將畫布內容匯出成圖片,方便下載、分享或上傳伺服器。
常用兩種方法:
const dataURL = canvas.toDataURL("image/png"); // 預設 "image/png"
const img = document.createElement("img");
img.src = dataURL;
document.body.appendChild(img); // 將圖片添加到頁面上
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"
介紹完進階用法,肯定要做個有趣的範例,才能有所體會~ 歡迎玩玩看 🥳
用 Canvas 做一張「濾鏡與圖形編輯器」:背景為多彩漸層,圖形可拖曳、旋轉、縮放,並可套用濾鏡與圖形混色,最後匯出 PNG 圖檔。
👉 歡迎追蹤這個系列,我會從 Canvas 開始,一步步帶你認識更多 Web API 🎯