HTML-in-Canvas API 可讓您直接在 2D 畫布內容中,轉譯互動式且可存取的 DOM 子樹。請參閱 HTML-in-Canvas 總覽,進一步瞭解這個 API 及其優點。
本指南說明如何將 HTML 轉譯為 2D 畫布。如要在 2D 畫布中算繪 HTML,請按照下列步驟操作:
- 準備畫布。以宣告方式設定正確的屬性,讓瀏覽器知道應將 HTML 轉譯為畫布。這項設定在 2D、WebGL 和 WebGPU 環境中都相同。瞭解如何設定畫布,以及如何宣告要獨立繪製的 HTML 元素。
- 將元素圖片繪製到畫布中。
- [選用] 同步處理 DOM 和像素。
將 HTML 元素繪製到 2D 畫布
畫布準備就緒,且元素標示為 drawable 後,請使用 drawElementImage() 方法將元素算繪至 2D 情境。
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const childElement1 = document.getElementById("childElement1");
const childElement2 = document.getElementById("childElement2");
canvas.onpaint = () => {
ctx.reset();
// 1. Draw the primary element at coordinate (20, 20)
ctx.drawElementImage(childElement1, 20, 20);
// 2. Draw the secondary nested button at a custom offset
ctx.drawElementImage(childElement2, 40, 90);
}
drawElementImage() 支援 3 引數、5 引數、7 引數和 9 引數形式,並接受選用的 options 參數:
// 1. Basic position: (element, dx, dy, options?)
ctx.drawElementImage(targetElement, 100, 150);
// 2. Scaled / resized: (element, dx, dy, dWidth, dHeight, options?)
ctx.drawElementImage(targetElement, 100, 150, 180, 60);
// 3. Cropped, default size: (element, sx, sy, swidth, sheight, dx, dy, options?)
ctx.drawElementImage(targetElement, 0, 0, 90, 30, 100, 150);
// 4. Cropped and resized: (element, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, options?)
ctx.drawElementImage(targetElement, 0, 0, 90, 30, 100, 150, 180, 60);
| 超載表單 | 參數 | 版面配置效果 |
|---|---|---|
| 預設大小 | (element, dx, dy) |
整個元素採用預設大小,左上角位於 (dx, dy)。 |
| 自訂目的地方塊 | (element, dx, dy, dwidth, dheight) |
將完整元素圖片縮放至畫布上的 dw × dh 檢視區塊。 |
| 裁切,預設大小 | (element, sx, sy, swidth, sheight, dx, dy) |
只有從 (sx, sy) 開始的 swidth × sheight 區域,以該區域的預設大小繪製 (與預設大小表單相同的比例)。 |
| 來源切片到目的地 | (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) |
從 (sx, sy) 開始裁剪來源元素,尺寸為 swidth × sheight,然後對應至目的地 (dx, dy, dwidth, dheight)。 |
同步處理 DOM 和像素
由於 <canvas> 轉譯是必要的,而 DOM 版面配置和 CSS 樣式則是反應式的,因此瀏覽器需要一種機制,讓轉譯的畫布像素、互動式點擊測試區域和無障礙樹狀結構保持同步。在瞭解如何同步處理 DOM 和像素之前,請務必瞭解 DOM 元素更新並需要重新繪製時觸發的 paint 事件。
在 2D 畫布情境中,瀏覽器會自動同步處理元素的版面配置座標、無障礙邊界,以及指標點擊測試與繪製的畫布座標。
手動更新元素幾何圖形
在進階情境中,您可以選擇不自動同步處理幾何圖形,並手動控制空間轉換。將 { preserveElementGeometry: true } 傳遞至 drawElementImage(),防止瀏覽器自動覆寫元素的現有點擊測試座標:
// 1. Draw the element without altering its existing hit-test bounds
ctx.drawElementImage(targetElement, elementX, 200, { preserveElementGeometry: true });
// 2. Construct a custom transform matrix as needed,
// assuming scaleX/scaleY = canvas grid pixels per CSS pixel,
// from your resize observer (see "Units and sizing").
const currentTransform = new DOMMatrix();
currentTransform.a = 1.5; // scale X
currentTransform.e = x / scaleX; // translate X: grid px → CSS px
currentTransform.f = y / scaleY; // translate Y: grid px → CSS px
// 3. Explicitly apply the custom transform
canvas.updateElementGeometry(targetElement, { canvasTransform: currentTransform });
drawElementImage() 會自動更新這個幾何圖形。這段示範影片說明設定 { preserveElementGeometry: true } 時,幾何圖形如何失去同步。後續步驟
- 瞭解 HTML-in-Canvas 的核心技術概念。
- 瞭解如何在 WebGL Canvas 中算繪 HTML。
- 瞭解如何在 WebGPU Canvas 中算繪 HTML。
- 瞭解備用策略。
- 歡迎在 GitHub 回報問題,分享您的意見。
- 請參閱社群提供的 HTML-in-Canvas 示範集合。