HTML-in-Canvas API позволяет отрисовывать интерактивные и доступные поддеревья DOM непосредственно в контексте 2D-холста. Чтобы узнать больше об API и его преимуществах, прочитайте обзор HTML-in-Canvas.
В этом руководстве показано, как отобразить HTML на двухмерном холсте. Чтобы отрисовать HTML на 2D-холсте, выполните следующие действия:
- Подготовьте холст. Задайте нужные атрибуты, чтобы браузер знал, что HTML-код нужно отрисовать в элементе canvas. Эта настройка одинакова для контекстов 2D, WebGL и WebGPU. Узнайте, как настроить холст и как объявить элементы HTML, которые будут отрисовываться независимо.
- Нарисуйте изображение элемента на холсте.
- При необходимости синхронизируйте DOM и пиксели.
Рисование элементов HTML на холсте 2D
Когда холст будет готов, а элементы помечены как drawable, отрисуйте их в контексте 2D с помощью метода drawElementImage().
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) |
Только область swidth × sheight, начиная с (sx, sy), отрисованная в размере по умолчанию (в том же масштабе, что и форма по умолчанию). |
| Исходный фрагмент для назначения | (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) |
Обрезает исходный элемент, начиная с (sx, sy) с размерами swidth × sheight, а затем сопоставляет его с целевым элементом (dx, dy, dwidth, dheight). |
Синхронизация DOM и пикселей
Поскольку отрисовка <canvas> является императивной, а макет DOM и стили CSS – реактивными, браузеру нужен механизм, который будет синхронизировать отрисованные пиксели холста, интерактивные области проверки нажатия и деревья специальных возможностей. Прежде чем перейти к синхронизации DOM и пикселей, ознакомьтесь с событием paint, которое активируется, когда элементы DOM обновляются и их нужно перерисовать.
В контекстах 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 });
drawElementImage() обновляет эту геометрию автоматически. В этой демонстрации показано, как нарушается синхронизация геометрии, когда задано свойство { preserveElementGeometry: true }.Дальнейшие действия
- Изучите основные технические концепции HTML-in-Canvas.
- Узнайте, как отрисовывать HTML на холсте WebGL.
- Подробнее о том, как отрисовывать HTML на холсте WebGPU…
- Подробнее о резервных стратегиях…
- Чтобы поделиться отзывом, создайте проблему на GitHub.
- Посмотрите коллекцию демонстраций HTML-in-Canvas от сообщества.