手癢實驗 · 前端新玩具

手癢實驗:Chrome 157 的 HTML-in-Canvas,把真的 HTML 畫進畫布

手癢實驗只支援 Chrome 157+難度:會一點 HTML/JS附可玩 demo

這篇不是 Grok Bot 教學,是手癢實驗室的另一個分類:看到新東西就先拿來玩一下。這次的主角是 Chrome 新推出的 HTML-in-Canvas。下面有一塊可以直接動手玩的 demo,用 Chrome 157 以上開最有感覺。


這是什麼?

以前 canvas 是一張「純像素」的畫紙:你畫什麼就是什麼,畫上去的字只是一堆點,選不起來、搜不到、螢幕閱讀器看不到。HTML-in-Canvas 讓你把一般的網頁元素丟進畫布裡,由瀏覽器負責把它畫好,你只要決定它畫在哪、要不要加效果。

最神奇的地方是:畫完之後,瀏覽器會自動把這個元素的「點擊範圍」對齊到你畫的位置。所以你把一個輸入框畫歪了,點那個歪掉的輸入框還是能打字。


為什麼重要:Canvas 和 DOM 的兩難

好處壞處
Canvas像素級控制、GPU 加速、2D/3D、自訂 shader 特效字選不起來、不能複製、不能 Ctrl+F、不能翻譯、螢幕閱讀器讀不到、自動填入沒用
HTML(DOM)表單、排版、無障礙、翻譯、搜尋,瀏覽器全包特效只能靠 CSS/SVG,不能直接改像素、不能套 shader
HTML-in-CanvasHTML 照樣能互動,又能當像素來加特效、放進 3D、匯出成圖片或影片目前只有 Chrome 157+;寫法比一般 HTML 多幾步

以前硬要兩邊都要,常見做法是「在 canvas 上面疊一層 HTML」,再用 JavaScript 每一格算位置對齊。結果是捲動或轉鏡頭時會抖、會跑位,疊越多越卡。HTML-in-Canvas 就是要解決這個問題。


動手玩:畫進畫布的名片卡

偵測中…
效果

手癢實驗室 · 畫布名片卡

我是被畫成像素的 HTML

拖曳選我、右鍵複製我,或按 Ctrl+F 搜「像素」看看。

哈囉,手癢的人!凡事想試試 🧪

支援的話可以試試:① 在輸入框打字,卡片即時更新;② 切到「波浪」還是能點進輸入框;③ 按「匯出 PNG」把整張畫布存成圖片。


怎麼寫:三步就能畫

1. 準備畫布

<canvas id="canvas" content="drawable">
  <div id="card" drawable>
    <h2>這是真的 HTML</h2>
    <input placeholder="可以打字">
  </div>
</canvas>

每個要畫的元素都要加 drawable,直接放在 canvas 底下的也要。

2. 在 paint 事件裡畫

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const card = document.getElementById('card');

canvas.onpaint = () => {
  ctx.reset();
  ctx.drawElementImage(card, 20, 20); // 座標是「畫布格點」單位
};

只要卡片內容有變(打字、改樣式、focus),瀏覽器會自動觸發 paint,你在裡面重畫就好。2D 模式下,瀏覽器也會自動把點擊範圍和螢幕閱讀器的位置對齊到你畫的地方。

3. 要動起來:requestPaint()

function loop() {
  canvas.requestPaint();       // 下一格強制觸發一次 paint
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);

想旋轉、縮放,直接用平常的 ctx.translate()、ctx.rotate() 就好,點擊範圍會跟著轉。想匯出就用 canvas 原本的 toBlob()、toDataURL(),錄影用 captureStream()。

3D 的話(WebGL/WebGPU),瀏覽器不知道你把元素貼到哪個面上,要自己算一個 DOMMatrix 交給 canvas.updateElementGeometry(el, { canvasTransform })。Three.js(THREE.HTMLTexture,實驗性)、Babylon.js(HtmlTexture)、PixiJS(v8.19.0 的 HTMLSource)都已經有包好的寫法。


支援度、功能偵測和備案

function supportsHtmlInCanvas() {
  const c = document.createElement('canvas');
  c.setAttribute('content', 'drawable');
  return c.content === 'drawable';
}

if (!supportsHtmlInCanvas()) {
  // 把卡片搬出 canvas,當一般 HTML 顯示,並提示使用者
  fallbackBox.append(card);
  canvas.hidden = true;
}

為什麼要搬出來?因為不支援的瀏覽器會把 canvas 裡的東西當成「備用內容」藏起來,整塊會變成一片空白。本頁的 demo 就是這樣做:用 Safari 或 Firefox 打開,會看到提示和一般 HTML 版本的卡片,不會壞掉。

如果你的需求是「把網頁存成圖片」,不支援的瀏覽器還有 html2canvas、dom-to-image 這類老方法可以當備案(都是社群套件,不是官方)。


誰該用?誰不用?

值得試的:

先不用的:


常見問題(FAQ)

Q1:我開 demo 只看到提示,沒有特效?
代表你的瀏覽器還不支援。用電腦版 Chrome 157 以上開(網址列輸入 chrome://version 可以看版本)。

Q2:畫進 canvas 的字,Google 搜得到嗎?
官方說法是爬蟲和 AI 代理可以讀到畫進 2D/3D 場景的 DOM 內容,因為它本來就是 HTML。不過一般文章頁還是直接用 HTML 最穩。

Q3:可以把別的網站嵌進來畫嗎?
不行。官方文件寫明不支援把跨網域(cross-origin)的內容放進畫布。

Q4:手機能用嗎?
官方公告沒有特別說明行動版,建議先用電腦版 Chrome 玩。iPhone 上的瀏覽器都是 Safari 核心,目前不支援,會看到一般 HTML 版本。


下一步

想用 AI 幫你寫這類實驗?先回第一篇:怎麼安裝 Grok Bot。
想開信箱、一次建好多個 Bot?看第二篇:信箱與多 Bot。
想讓 Bot 幫你追 X 上的新技術消息?看第三篇:Grok Bot 連接 X。
追蹤手癢實驗室 https://www.threads.com/@bluevelo1666

來源(本篇為改寫實測筆記,非轉載):Chrome for Developers:Chrome 157 的 HTML-in-Canvas、2D 技術文件、匯出指南、WICG/html-in-canvas。


非官方聲明: 本站為個人非官方教學,內容依作者實測日期撰寫,API 與瀏覽器支援度可能隨時變動,請以官方文件為準。
最後實測:2026-10-30|© 手癢實驗室 lab.taipeisi.com