HTML in 2D-Canvas rendern

Mit der HTML-in-Canvas API können Sie interaktive, barrierefreie DOM-Unterbäume direkt in einem 2D-Canvas-Kontext rendern. Weitere Informationen zur API und ihren Vorteilen finden Sie in der Übersicht zu HTML-in-Canvas.

In diesem Leitfaden wird gezeigt, wie Sie HTML in einem 2D-Canvas rendern. Zum Rendern von HTML in einem 2D-Canvas sind die folgenden Schritte erforderlich:

  1. Arbeitsfläche vorbereiten Legen Sie die richtigen Attribute deklarativ fest, damit der Browser weiß, dass er HTML in einem Canvas rendern soll. Diese Einrichtung ist für 2D-, WebGL- und WebGPU-Kontexte identisch. Informationen zum Einrichten des Canvas und zum Deklarieren von HTML-Elementen, die unabhängig voneinander gezeichnet werden sollen
  2. Zeichnen Sie das Elementbild in den Canvas.
  3. [Optional] Synchronisieren Sie das DOM und die Pixel.

HTML-Elemente in 2D-Canvas zeichnen

Sobald der Canvas bereit ist und Elemente als drawable markiert sind, rendern Sie sie mit der Methode drawElementImage() im 2D-Kontext.

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() unterstützt Formen mit 3, 5, 7 und 9 Argumenten und akzeptiert einen optionalen options-Parameter:

// 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);
Formular für Überlastung Parameter Layouteffekt
Standardgröße (element, dx, dy) Das gesamte Element in seiner Standardgröße, wobei sich die obere linke Ecke bei (dx, dy) befindet.
Feld „Benutzerdefiniertes Ziel“ (element, dx, dy, dwidth, dheight) Skaliert das vollständige Elementbild in einen dw × dh-Darstellungsbereich auf der Leinwand.
Zugeschnitten, Standardgröße (element, sx, sy, swidth, sheight, dx, dy) Nur der Bereich swidth × sheight, der bei (sx, sy) beginnt und in der Standardgröße dieses Bereichs gezeichnet wird (derselbe Maßstab wie das Formular in Standardgröße).
Quell-Slice zum Ziel (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) Schneidet das Quellelement ab (sx, sy) mit den Abmessungen swidth × sheight zu und ordnet es dann dem Ziel (dx, dy, dwidth, dheight) zu.

DOM und Pixel synchronisieren

Da das <canvas>-Rendering imperativ ist, während DOM-Layout und CSS-Styling reaktiv sind, benötigt der Browser einen Mechanismus, um die gerenderten Canvas-Pixel, interaktiven Trefferprüfungsbereiche und Barrierefreiheitsbäume synchron zu halten. Bevor Sie erfahren, wie Sie das DOM und die Pixel synchronisieren, sollten Sie sich mit dem paint-Ereignis vertraut machen, das ausgelöst wird, wenn DOM-Elemente aktualisiert und neu gezeichnet werden müssen.

In 2D-Canvas-Kontexten synchronisiert der Browser automatisch die Layoutkoordinaten, die Grenzen für die Barrierefreiheit im Internet und die Trefferprüfung für Zeiger des Elements mit den gezeichneten Canvas-Koordinaten.

Elementgeometrie manuell aktualisieren

In komplexeren Szenarien können Sie die automatische Geometriesynchronisierung deaktivieren und räumliche Transformationen manuell steuern. Übergeben Sie { preserveElementGeometry: true } an drawElementImage(), um zu verhindern, dass der Browser die vorhandenen Trefferprüfungskoordinaten des Elements automatisch überschreibt:

// 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 });
In 2D wird diese Geometrie von drawElementImage() automatisch aktualisiert. In dieser Demo wird gezeigt, wie die Geometrie nicht mehr synchron ist, wenn { preserveElementGeometry: true } festgelegt ist.

Nächste Schritte