發布日期:2026 年 10 月 26 日
來源試用成功後,Chrome 157 正式推出 HTML-in-Canvas API 的穩定版本。HTML-in-Canvas API 彌補了 DOM 的互動式無障礙世界,與 <canvas> 的高效能像素級控制之間的差距。這個 API 結合了兩者的優點,既有豐富的瀏覽器功能,也有 GPU 加速的畫布圖形。
Canvas 與 DOM 的兩難
以往,建立視覺效果要求較高的網頁應用程式時,必須在標準 HTML 元素和原始畫布內容之間做出選擇。
| 科技 | 優勢 | 限制 |
|---|---|---|
<canvas> |
可透過 GPU 存取權進行低階像素控制,驅動 2D 和 3D 圖形管道、自訂著色器和螢幕外工作站。高效能轉譯,適合資料密集的繁重 UI。 | 沒有內建的網頁平台功能,例如文字選取、複製及貼上、按一下滑鼠右鍵動作和文字換行。不透明像素網格預設不支援螢幕閱讀器、網頁內搜尋、自動翻譯或自動填入功能,因此需要備用導入方式。 |
HTML |
內建表單控制項、回應式字體排版和 CSS 樣式,可直接使用 Semantic UI。與瀏覽器深度整合,支援螢幕閱讀器、網頁內搜尋和開發人員工具。 | 控制複雜 UI 效能的能力有限。視覺效果僅限標準 CSS 和 SVG,不得直接操作像素或使用著色器。 |
HTML-in-Canvas 推出前
在這個 API 推出前,如果您建構了大量使用畫布的 UI,就必須在兩種方法之間做出選擇,而這兩種方法各有缺點:
- 直接將文字算繪為畫布像素 (
fillText()):應用程式會以原始像素的形式,強制繪製文字和 UI 控制項。這種做法有以下缺點:- 無障礙功能故障:除非手動建構並同步處理隱藏的備用 DOM,否則螢幕閱讀器和輔助工具無法讀取畫布像素。
- 無法使用瀏覽器功能:使用者無法使用「在網頁中尋找」功能 (Ctrl/Cmd+F) 搜尋、自然地複製及貼上文字、觸發內容選單,或使用瀏覽器翻譯和拼字檢查功能。
- 複雜的字體排版引擎:如要支援國際化,必須綁定大型 JavaScript 版面配置引擎。
- 在畫布上浮動 HTML 疊加層:例如,使用程式庫,在 JavaScript 中計算定界框和矩陣轉換,將標準 HTML 元素置於畫布上。這種做法的缺點包括:
- 同步延遲和畫面撕裂:在 3D 模式下捲動、縮放或移動鏡頭時,疊加層 DOM 元素可能會因影格時間差異,而相對於畫布像素產生偏移或抖動。
- 裁剪和 Z 軸排序限制:HTML 疊加層一律位於整個畫布緩衝區的頂端。在 3D 場景中嵌入 HTML (例如在 3D 物件後方、玻璃材質內或鏡面反射中),需要複雜的 iframe 轉圖片解決方法。
- 效能負擔:為了讓疊加層與畫布對齊,您必須在 JavaScript 中重新計算每個疊加層的轉換,並在每個影格中寫入
style.transform。接著,瀏覽器會剖析每個字串,並重新計算元素樣式,然後才能算繪影格,因此主執行緒工作會隨著您新增的疊加層而增加。在 2D 情境中,drawElementImage()會為您更新元素的位置。在 WebGL 和 WebGPU 中,您會將計算出的轉換以矩陣形式傳遞至updateElementGeometry()。無論採用哪種方式,瀏覽器都不會剖析 CSS 或重新計算樣式。
HTML-in-Canvas 的主要優點
HTML-in-Canvas 則可消除這些缺點。將 HTML 放入 <canvas> 元素中,內容仍可互動,且所有瀏覽器整合功能都會自動運作。
在 <canvas> 內轉譯的 HTML 內容,與 <canvas> 外的 HTML 具有相同功能:
- 文字版面配置和格式:支援文字版面配置和格式,包括套用 CSS 樣式的多行或雙向文字。
- 表單控制項:提供豐富的表單控制項,以及多種 CSS 和著色器自訂選項。
- 選取、複製、貼上文字,以及按一下滑鼠右鍵:使用者可以醒目顯示 3D 場景中的文字,或觸發內容選單。
- 無障礙功能:在畫布中算繪的 HTML 內容會公開給螢幕閱讀器的無障礙樹狀結構。
- 整合瀏覽器功能:翻譯、自動填入和網頁內搜尋等瀏覽器功能可立即使用。使用者可以翻譯或搜尋 WebGL 和 WebGPU 紋理中的文字。
- 擴充功能整合:瀏覽器擴充功能會處理內容。舉例來說,文字替換擴充功能會自動更新 3D 網格上顯示的文字。
- 開發人員工具整合:直接在 Chrome 開發人員工具中,檢查及調整畫布 UI 元素的 CSS 樣式。
- 可索引性和 AI 代理:網路檢索器和 AI 代理可為轉譯成 2D 和 3D 場景的 DOM 內容建立索引。
- 媒體編輯和匯出:將包含即時 DOM 元素的完整畫布合成內容,直接匯出為圖片 (
toDataURL()、toBlob()) 或影片串流 (captureStream())。
fillText 方法直接算繪到畫布中,且不具互動性。主要用途
HTML-in-Canvas 可在多個領域發揮作用:
- 大型畫布應用程式:重量級網頁應用程式可直接在畫布工作區中轉譯 UI 元件,提升無障礙程度並縮減套件大小。
- 3D 場景和遊戲:沉浸式 WebXR 體驗和遊戲可將互動式 DOM 元素 (例如遊戲內終端機或可讀取的 3D 書籍) 直接置於場景中。
- 媒體編輯和匯出:結合豐富 HTML 字體排版和著色器效果的創意工具,可直接將複合場景匯出為圖片或影片串流。
- 表現力豐富的使用者介面:您可以將 HTML 內容當做原始像素進行操作,建構著色器驅動的視覺效果。
HTML-in-Canvas 快速入門導覽課程
如要在畫布中算繪 HTML,請按照下列步驟操作:
準備畫布。以宣告方式設定正確的屬性,讓瀏覽器知道應將 HTML 轉譯為畫布。這項設定在 2D、WebGL 和 WebGPU 環境中都相同。瞭解如何設定畫布,以及如何宣告要獨立繪製的 HTML 元素。
<!-- Prepare your canvas by setting the `content` attribute --> <canvas id="canvas" width="600" height="400" content="drawable"> <!-- Mark child as `drawable` to render to canvas --> <div id="myElement" drawable> <!-- Your HTML here --> </div> </canvas>將元素圖片繪製到畫布上。具體導入方式取決於您是在 2D、WebGL 還是 WebGPU 環境中算繪 HTML。
const ctx = canvas.getContext("2d"); // Draw HTML element into canvas in 2D ctx.drawElementImage(myElement, myElementX, myElementY);選用:同步處理 DOM 和像素。幾何圖形同步處理也取決於您使用的情境。在 2D 模式下,瀏覽器預設會自動處理,但在 3D 情境下,您需要建構轉換並傳遞至
updateElementGeometry方法。// In 3D, construct a transform as needed, for example: const transform = new DOMMatrix().translate(x, y); // Synchronize the element's DOM and pixels canvas.updateElementGeometry(myElement, { canvasTransform: transform });
框架和生態系統支援
主要的 WebGL 和 3D 圖形程式庫支援 HTML-in-Canvas:
Three.js:提供使用
THREE.HTMLTexture的實驗支援。const material = new THREE.MeshBasicMaterial(); material.map = new THREE.HTMLTexture(uiElement); const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material); scene.add(mesh);PlayCanvas:支援使用
setSource()串流 HTML 紋理。canvas.addEventListener('paint', () => { htmlTexture.setSource(htmlElement); }, { once: true });Babylon.js:透過
BABYLON.HtmlTexture提供內建繫結。const htmlTexture = new BABYLON.HtmlTexture("htmlTexture", uiElement, scene); material.diffuseTexture = htmlTexture;PixiJS:在
v8.19.0版本中內建支援HTMLSource。import { HTMLSource } from 'pixi.js/html-source'; const sprite = Sprite.from(new HTMLSource({ resource: form, autoUpdate: true })); app.stage.addChild(sprite);CanvasUI:專為 HTML-in-Canvas 設計的開放原始碼元件庫。
如要進一步瞭解實作細節,請參閱各架構的說明文件。
功能偵測和備用策略
為確保跨瀏覽器相容性,請先確認 API 支援情形,再執行程式碼:
export function supportsHtmlInCanvas() {
if (typeof document === "undefined") return false;
const canvas = document.createElement("canvas");
canvas.setAttribute("content", "drawable");
return canvas.content === "drawable";
}
如果無法使用 API,可以改用其他 UI、浮動 HTML 疊加層,或其中一個可用的程式庫 (例如 three-html-render、html2canvas 或 dom-to-image)。
後續步驟
- 查看完整的 Chrome 開發人員版 HTML-in-Canvas 說明文件。
- 使用 Modern Web Guidance 升級程式開發輔助。
- 在 WICG GitHub 存放區提供意見。
- 查看 HTML-in-Canvas 社群示範。