发布时间:2026 年 10 月 26 日
在成功完成源试用后,Chrome 157 正式发布了 HTML-in-Canvas API 的稳定版本。HTML-in-Canvas API 弥合了 DOM 的交互式、无障碍世界与 <canvas> 的高性能、像素级控制之间的差距。此 API 兼具丰富的浏览器功能和 GPU 加速的画布图形,让您两全其美。
Canvas 与 DOM 的两难选择
以前,在创建对视觉效果要求较高的 Web 应用时,您必须在标准 HTML 元素和原始画布上下文之间做出选择。
| 技术 | 优势 | 限制 |
|---|---|---|
<canvas> |
通过 GPU 访问权限进行低级像素控制,以驱动 2D 和 3D 图形流水线、自定义着色器和离屏工作器。为繁重、数据密集的界面提供高性能渲染。 | 没有内置的 Web 平台功能,例如文本选择、复制和粘贴、右键点击操作以及文本换行。不透明像素网格默认不支持屏幕阅读器、页内查找、自动翻译或自动填充,需要采用后备实现。 |
HTML |
开箱即用的 Semantic UI,内置表单控件、自适应排版和 CSS 样式。与屏幕阅读器、页内查找和开发者工具深度集成。 | 控制复杂界面性能的能力有限。视觉效果仅限于标准 CSS 和 SVG,不涉及直接像素操作或着色器。 |
HTML-in-Canvas 推出之前
在此 API 推出之前,如果您构建了大量使用画布的界面,则必须在以下两种方法之间做出选择,每种方法都有其自身的缺点:
- 直接将文本渲染为画布像素 (
fillText()):应用以命令式方式将文本和界面控件绘制为原始像素。这种方法存在以下缺点:- 无障碍功能故障:屏幕阅读器和辅助工具无法读取画布像素,除非您手动构建并同步一个不可见的后备 DOM。
- 浏览器功能失效:用户无法使用“在页面中查找”功能(Ctrl/Cmd+F)进行搜索、无法自然地复制和粘贴文本、无法触发上下文菜单,也无法使用浏览器翻译和拼写检查功能。
- 复杂的排版引擎:支持国际化需要捆绑大型 JavaScript 布局引擎。
- 画布顶部的浮动 HTML 叠加层:例如,使用 JavaScript 计算边界框和矩阵转换,从而在画布上定位标准 HTML 元素的库。这种方法的缺点包括:
- 同步延迟和视觉撕裂:在 3D 模式下滚动、缩放或移动摄像头时,由于帧时间差异,叠加层 DOM 元素可能会相对于画布像素发生漂移或抖动。
- 剪裁和 Z 轴排序限制:HTML 叠加层始终位于整个画布缓冲区的顶部。如果不采用复杂的 iframe 到图片解决方法,就无法在 3D 场景内嵌入 HTML(例如,在 3D 对象后面、玻璃材质内或在镜子中反射)。
- 性能开销:为了使叠加层与画布保持一致,您必须在 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 开发者工具中检查和调整画布界面元素的 CSS 样式。
- 可编入索引性与 AI 智能体:网络爬虫和 AI 智能体可以为渲染到 2D 和 3D 场景中的 DOM 内容编入索引。
- 媒体编辑和导出:将包含实时 DOM 元素的完整画布合成直接导出为图片(
toDataURL()、toBlob())或视频流 (captureStream())。
fillText 方法直接渲染到画布中,并且不具有互动性。主要应用场景
HTML-in-Canvas 可在多个方面发挥作用:
- 大型 Canvas 应用:重量级 Web 应用可以直接在 Canvas 工作区中渲染界面组件,从而提高无障碍性并缩减软件包大小。
- 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 不可用,您可以回退到备用界面、浮动 HTML 叠加层或某个可用库(例如 three-html-render、html2canvas 或 dom-to-image)。
后续步骤
- 浏览完整的 Chrome for Developers HTML-in-Canvas 文档。
- 使用 Modern Web Guidance 升级编码辅助。
- 在 WICG GitHub 代码库中分享反馈。
- 查看社区提供的 HTML-in-Canvas 演示。