InquirerBatac inaugurates first automated weather station in Ilocos NortePunchUK tests five-day breast cancer radiotherapyCNN TürkBorsa güne düşüşle başladı (30.10.2026)Daily MaverickLOCAL ELECTIONS 2026: MK support down as Zuma disappears from stump — new big pollESPN17 teams that can win 30 gamesThe Jerusalem PostIsraeli Arabs, Palestinians view path to coalition through political clout - analysisBollywood HungamaSara Ali Khan faces fatwa over Kedarnath Temple visit: ReportsUOLSignos: confira seu horóscopo desta sexta (30)GhaflaPastor Kanyari Leaks Private WhatsApp Chats With Daughter Sky To Prove Financial SupportZDF heuteAktuelle Pressemitteilungen des ZDFThe South AfricanWarning of major delays at Cape Town International AirportХабрЯ не планировал становиться open-source разработчиком, а теперь я развиваю проект с 1000+ звёзд на GitHub
The Daily Newsstand · Free, Always
Friday, October 30, 2026

[Перевод] HTML-in-Canvas в Chrome 157: интерактивный DOM в 2D, WebGL и WebGPU

Translate

Эта статья перевод оригинальной статьи «HTML-in-Canvas in Chrome 157: Interactive DOM inside 2D, WebGL, and WebGPU».

Также я веду телеграм канал «Frontend по‑флотски», где рассказываю про интересные вещи из мира разработки интерфейсов и AI.

Вступление

После успешного origin trial API HTML-in-Canvas официально вышел в стабильной версии Chrome 157. Он объединяет интерактивность и доступность DOM с производительностью и попиксельным управлением <canvas>. Так возможности браузера можно использовать вместе с графикой canvas, ускоренной на GPU.

Выбор между canvas и DOM

Раньше при создании веб-приложений со сложной графикой приходилось выбирать между стандартными HTML-элементами и непосредственной работой с контекстами canvas.

Технология

Сильные стороны

Ограничения

<canvas>

Низкоуровневое управление пикселями с доступом к GPU для конвейеров 2D- и 3D-графики, собственных шейдеров и воркеров для внеэкранного рендеринга. Высокая производительность в тяжёлых интерфейсах с большим объёмом данных.

Нет встроенных возможностей веб-платформы: выделения, копирования и вставки текста, действий по правому клику и переноса строк. Непрозрачная для браузера сетка пикселей по умолчанию не поддерживает скринридеры, поиск по странице, автоматический перевод и автозаполнение. Для них нужна отдельная реализация.

HTML

Семантический интерфейс со встроенными элементами форм, адаптивной типографикой и CSS-стилями. Интеграция со скринридерами, поиском по странице и DevTools.

Ограниченные возможности управления производительностью сложных интерфейсов. Визуальные эффекты ограничены стандартными CSS и SVG, без прямого управления пикселями или шейдеров.

До HTML-in-Canvas

До появления этого API для интерфейсов, активно использующих canvas, было два подхода. У каждого были свои недостатки.

  1. Отрисовка текста непосредственно в пикселях canvas с помощью fillText(). Приложение императивно рисовало текст и элементы управления как наборы пикселей. Это создавало несколько проблем:

    • Скринридеры и вспомогательные инструменты не могут прочитать пиксели canvas. Для доступности приходилось вручную создавать и синхронизировать невидимый резервный DOM.

    • Пользователь не мог искать текст через поиск по странице (Ctrl/Cmd+F), привычным образом копировать и вставлять его, вызывать контекстные меню, пользоваться переводом и проверкой правописания в браузере.

    • Для интернационализации приходилось включать в сборку большие JavaScript-движки компоновки текста.

  2. HTML-элементы поверх canvas. Например, библиотеки размещали стандартные HTML-элементы над холстом, вычисляя ограничивающие прямоугольники и матричные преобразования в JavaScript. Здесь возникали другие проблемы:

    • Задержки синхронизации и визуальные разрывы. При прокрутке, масштабировании или движении камеры в 3D DOM-элементы могли смещаться или дрожать относительно пикселей canvas из-за разницы во времени подготовки кадров.

    • Ограничения обрезки и порядка наложения. HTML-слои всегда располагались поверх всего буфера canvas. Поместить HTML внутрь 3D-сцены, например за трёхмерный объект, внутрь стеклянного материала или в отражение зеркала, без сложных обходных решений с преобразованием iframe в изображение было нельзя.

    • Дополнительная нагрузка. Чтобы HTML-слои оставались на своих местах относительно canvas, на каждом кадре нужно пересчитывать преобразование каждого слоя в JavaScript и записывать его в style.transform. Перед отрисовкой браузер разбирает каждую строку и пересчитывает стиль элемента, поэтому каждый новый слой увеличивает работу основного потока. В 2D-контексте drawElementImage() обновляет положение элемента автоматически. В WebGL и WebGPU вычисленное преобразование передаётся в updateElementGeometry() как матрица. В обоих случаях браузеру не приходится разбирать CSS и пересчитывать стили.

Что даёт HTML-in-Canvas

HTML-in-Canvas устраняет необходимость в этих компромиссах. HTML внутри элемента <canvas> остаётся интерактивным, а интеграции с браузером работают автоматически.

HTML-содержимое внутри <canvas> сохраняет те же возможности, что и снаружи:

  • Компоновка и форматирование текста, включая многострочный и двунаправленный текст с CSS-стилями.

  • Элементы форм с широкими возможностями оформления через CSS и шейдеры.

  • Выделение, копирование и вставка текста, а также правый клик. Пользователи могут выделять текст внутри 3D-сцен и вызывать контекстные меню.

  • Доступность: HTML-содержимое canvas попадает в дерево доступности для скринридеров.

  • Функции браузера, включая перевод, автозаполнение и поиск по странице, работают без дополнительной настройки. Можно переводить и искать текст внутри текстур WebGL и WebGPU.

  • Расширения браузера тоже работают с этим содержимым. Например, расширение для замены текста автоматически обновляет текст на трёхмерных мешах.

  • В Chrome DevTools можно просматривать и менять CSS-стили элементов интерфейса внутри canvas.

  • Поисковые роботы и AI-агенты могут индексировать DOM-содержимое, отрисованное в 2D- и 3D-сценах.

  • Готовую композицию canvas с живыми DOM-элементами можно экспортировать в изображение (toDataURL(), toBlob()) или видеопоток (captureStream()).

Сравнение возможностей браузера при отрисовке текста непосредственно в canvas и через HTML-in-Canvas. В области HTML-in-Canvas текст можно выделять и переводить, а автозаполнение и другие функции браузера работают без дополнительной настройки. В области обычного canvas содержимое отрисовано методом fillText и не интерактивно.

Основные сценарии использования

API подходит для следующих задач:

  • Крупные приложения на canvas могут отрисовывать компоненты интерфейса прямо в рабочих областях холста, улучшая доступность и уменьшая размер сборки.

  • В 3D-сценах, играх и иммерсивных приложениях WebXR можно размещать интерактивные DOM-элементы прямо внутри сцены: например, внутриигровые терминалы или трёхмерные книги, которые можно читать.

  • Инструменты для создания и редактирования медиа могут сочетать HTML-типографику с шейдерными эффектами и экспортировать составные сцены непосредственно в изображения или видеопотоки.

  • Для выразительных интерфейсов можно обрабатывать HTML-содержимое как пиксели и создавать визуальные эффекты с помощью шейдеров.

Как начать работу с HTML-in-Canvas

Подробности есть в технической документации HTML-in-Canvas.

Для отрисовки HTML в canvas выполните следующие шаги.

1. Подготовьте canvas

Декларативно задайте атрибуты, которые сообщают браузеру, что HTML нужно отрисовывать в canvas. Эта настройка одинакова для контекстов 2D, WebGL и WebGPU. В документации описаны подготовка canvas и объявление 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>

2. Нарисуйте изображение элемента в canvas

Конкретная реализация зависит от контекста: 2D, WebGL или WebGPU.

const ctx = canvas.getContext("2d");
// Draw HTML element into canvas in 2D
ctx.drawElementImage(myElement, myElementX, myElementY);

3. При необходимости синхронизируйте 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 });

Поддержка библиотек и экосистемы

HTML-in-Canvas поддерживают основные библиотеки для WebGL и трёхмерной графики.

Перечисленные инструменты являются сторонними проектами сообщества. Google и команда Chrome не разрабатывают, не сопровождают и официально не поддерживают их.

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 поддерживает потоковую передачу HTML-текстур через setSource().

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-слои поверх canvas или одну из готовых библиотек, например three-html-render, html2canvas или dom-to-image.

Эти библиотеки являются сторонними проектами сообщества. Google и команда Chrome не разрабатывают, не сопровождают и официально не поддерживают их.

Что дальше

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.