HTML renderen in 2D-canvas

Met de HTML-in-Canvas API kun je interactieve, toegankelijke DOM-subtrees rechtstreeks renderen in een 2D-canvascontext. Lees het overzicht van HTML-in-Canvas voor meer informatie over de API en de voordelen ervan.

In deze handleiding wordt uitgelegd hoe u HTML rendert in een 2D-canvas. Voor de weergave van HTML in een 2D-canvas zijn de volgende stappen vereist:

  1. Bereid je canvas voor. Stel de juiste kenmerken declaratief in om de browser te laten weten dat deze HTML moet renderen in een canvas. Deze instelling is identiek voor 2D-, WebGL- en WebGPU-contexten. Meer informatie over hoe je je canvas instelt en hoe je HTML-elementen declareert die onafhankelijk moeten worden getekend.
  2. Teken de elementafbeelding op het canvas.
  3. [Optioneel] Synchroniseer het DOM en de pixels.

HTML-elementen tekenen in 2D-canvas

Zodra het canvas klaar is en elementen zijn gemarkeerd als drawable, render je ze in de 2D-context met de methode 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() ondersteunt formulieren met 3, 5, 7 en 9 argumenten en accepteert een optionele parameter 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);
Formulier voor overbelasting Parameters Indelingseffect
Standaardformaat (element, dx, dy) Het hele element in het standaardformaat, met de linkerbovenhoek op (dx, dy).
Vak voor aangepaste bestemming (element, dx, dy, dwidth, dheight) Schaalt de volledige elementafbeelding naar een kijkvenster van dw × dh op het canvas.
Bijgesneden, standaardformaat (element, sx, sy, swidth, sheight, dx, dy) Alleen het gebied swidth × sheight dat begint bij (sx, sy), getekend op de standaardgrootte van dat gebied (dezelfde schaal als het formulier met de standaardgrootte).
Bronslice naar bestemming (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) Snijdt het bronelement bij vanaf (sx, sy) met afmetingen swidth × sheight en wijst het daarna toe aan bestemming (dx, dy, dwidth, dheight).

Het DOM en de pixels synchroniseren

Omdat <canvas>-weergave noodzakelijk is terwijl de DOM-indeling en CSS-stijl reactief zijn, heeft de browser een mechanisme nodig om de weergegeven canvaspixels, interactieve hit-testregio's en toegankelijkheidsstructuren gesynchroniseerd te houden. Voordat u leert hoe u het DOM en de pixels synchroniseert, moet u de gebeurtenis paint begrijpen die wordt geactiveerd wanneer DOM-elementen worden geüpdatet en opnieuw moeten worden getekend.

In 2D-canvascontexten synchroniseert de browser automatisch de vormgevingscoördinaten, toegankelijkheidsgrenzen en hit-tests van de aanwijzer van het element met de getekende canvascoördinaten.

Elementgeometrie handmatig updaten

In geavanceerde scenario's kun je je afmelden voor automatische geometrische synchronisatie en ruimtelijke transformaties handmatig beheren. Geef { preserveElementGeometry: true } door aan drawElementImage() om te voorkomen dat de browser de bestaande hit-testcoördinaten van het element automatisch overschrijft:

// 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 updatet drawElementImage() deze geometrie automatisch. Deze demo toont hoe geometrie niet meer synchroon loopt als { preserveElementGeometry: true } is ingesteld.

Volgende stappen