將 HTML 算繪至 2D 畫布

HTML-in-Canvas API 可讓您直接在 2D 畫布內容中,轉譯互動式且可存取的 DOM 子樹。請參閱 HTML-in-Canvas 總覽,進一步瞭解這個 API 及其優點。

本指南說明如何將 HTML 轉譯為 2D 畫布。如要在 2D 畫布中算繪 HTML,請按照下列步驟操作:

  1. 準備畫布。以宣告方式設定正確的屬性,讓瀏覽器知道應將 HTML 轉譯為畫布。這項設定在 2D、WebGL 和 WebGPU 環境中都相同。瞭解如何設定畫布,以及如何宣告要獨立繪製的 HTML 元素。
  2. 將元素圖片繪製到畫布中。
  3. [選用] 同步處理 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 });
在 2D 模式下,drawElementImage() 會自動更新這個幾何圖形。這段示範影片說明設定 { preserveElementGeometry: true } 時,幾何圖形如何失去同步。

後續步驟