Mit der HTML-in-Canvas API können Sie interaktive, barrierefreie DOM-Unterbäume direkt in 2D-, WebGL- oder WebGPU-Canvas-Kontexte rendern.
In diesem Leitfaden werden technische Konzepte für HTML-in-Canvas beschrieben, die für alle Canvas-Kontexte gelten:
- Canvas für das Rendern von HTML vorbereiten
- Teilbaum
drawableverstehen - Das Ereignis
paint - Geometrie eines Elements aktualisieren
- Barrierefreiheit von HTML-in-Canvas
- Fallback-Strategien verwenden
Canvas für das Rendern von HTML vorbereiten
Wenn Sie HTML-Elemente in einem <canvas> rendern möchten, konfigurieren Sie die folgenden beiden Attribute:
content="drawable"für<canvas>festlegen:Dadurch wird das Canvas-Element so konfiguriert, dass seine untergeordneten DOM-Knoten angeordnet werden, anstatt sie nur als versteckte Inhalte zu behandeln.drawablefür Zielelemente festlegen:Dadurch wird ein Element als unabhängige Paint-Root markiert, die für das Canvas-Rendering infrage kommt.
<canvas id="mainCanvas" width="600" height="400" content="drawable">
<div id="parentElement" class="card" drawable>
<h2>Container Title</h2>
<p>Descriptive text inside the parent element.</p>
<!-- Nested drawable: excluded from parentElement and drawn independently -->
<button id="childElement" class="btn" drawable>Action Button</button>
</div>
</canvas>
Drawable-Unterstruktur
Wenn Sie HTML-Code für das Rendering in einem Canvas vorbereiten, müssen Sie entscheiden, welche Elemente unabhängig voneinander gezeichnet werden sollen. Jedes drawable-Element stellt eine unabhängige Paint-Wurzel und den zugehörigen darstellbaren Unterbaum dar.
Eine darstellbare Unterstruktur besteht aus einem Element mit dem Attribut drawable und allen seinen Nachfolgern, ausgenommen verschachtelte Nachfolger, die ebenfalls drawable enthalten, zum Beispiel:
<canvas content="drawable">
<!-- Subtree A (Renders parent container and text) -->
<div id="parentElement" drawable>
<h2>Parent Card Heading</h2>
<p>Card body text content.</p>
<!-- Subtree B (Excluded from Subtree A and drawn separately) -->
<button id="nestedChildElement" drawable>
Clickable Button
</button>
</div>
</canvas>
| Element | Grenze zeichnen | Verhalten |
|---|---|---|
#parentElement (Teilbaum A) |
Hintergrundbereich, Überschrift und Absatz | Wird beim Aufrufen von drawElementImage(parentElement, ...) gerendert |
#nestedChildElement (Teilbaum B) |
Buttonoberfläche und -text | Aus dem #parentElement-Unterbaum ausgeschlossen; in einem separaten drawElementImage(nestedChildElement, ...)-Aufruf gerendert |
drawable-Schaltfläche ist in einer drawable-Karte verschachtelt und beide werden durch einen eigenen drawElementImage()-Aufruf gezeichnet.Durch das Verschachteln von zeichenbaren Elementen können Sie semantische HTML-Beziehungen beibehalten und gleichzeitig untergeordnete Elemente unabhängig voneinander auf der Canvas-Szene überlagern, positionieren oder animieren.
Das Ereignis paint
Die HTML-in-Canvas API führt das Ereignis paint ein. Der Browser löst automatisch ein paint-Ereignis für das <canvas> aus, wenn sich das Layout, der Text oder die CSS-Stile für einen der untergeordneten drawable-Elemente ändern.
canvas.addEventListener("paint", (event) => {
// Clear the viewport
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Redraw elements individually
ctx.drawElementImage(parentElement, 20, 20);
ctx.drawElementImage(childElement, 40, 90);
});
Das Ereignis paint sendet eine Instanz von CanvasPaintEvent, die das Standard-DOM Event erweitert und eine changedElements-Eigenschaft hat, die nur die drawable-Nachfolger enthält, die sich seit dem letzten Rendern visuell geändert haben (z. B. Stiländerungen, Layoutverschiebungen, Textbearbeitungen oder Änderungen des Fokusstatus).
canvas.addEventListener("paint", (event) => {
// Array of changed elements
for (const el of event.changedElements) {
console.log(`Element #${el.id} visually changed and needs repainting`);
}
});
Lebenszyklus eines Frames
Canvas-Zeichenbefehle, die innerhalb des paint-Ereignisses ausgeführt werden, werden im aktuellen Rendering-Update angezeigt. DOM-Änderungen, die innerhalb des paint-Ereignisses vorgenommen werden, werden jedoch erst im nachfolgenden Frame angezeigt:
canvas.addEventListener("paint", () => {
// Renders in the CURRENT rendering update:
ctx.drawElementImage(parentElement, 20, 20);
// Modifying DOM styles inside paint schedules a new layout cycle;
// changes will appear in the NEXT frame:
parentElement.style.backgroundColor = "#e0f2fe";
});
Verschachtelte Canvases
Wenn Ihre Seite verschachtelte <canvas content="drawable">-Elemente enthält, sendet der Browser paint-Ereignisse in umgekehrter DOM-Baumreihenfolge (Nachkommen werden vor Vorfahren ausgelöst). So wird sichergestellt, dass untergeordnete Canvas-Elemente gerendert werden, bevor sie von übergeordneten Canvas-Elementen zusammengesetzt werden.
Angenommen, im folgenden Beispiel muss sich das innere nestedElement-Element visuell ändern (z. B. ändert sich die CSS-Hintergrundfarbe, wenn der Nutzer den Mauszeiger darauf hält). Zuerst wird das Ereignis paint auf dem Canvas nestedCanvas ausgelöst. Der Listener löscht den untergeordneten Zwischenspeicher und ruft ctx.drawElementImage(nestedElement, ...) auf, um den aktualisierten Status zu rendern. Anschließend wird das Ereignis paint auf parentCanvas ausgelöst. Der Listener zeichnet wrapperElement (mit dem bereits aktualisierten nestedCanvas-Canvas) in die Szene.
<!-- Outer parent canvas -->
<canvas id="parentCanvas" width="800" height="600" content="drawable">
<!-- Wrapper container for nested content -->
<div id="wrapperElement" drawable>
<!-- Nested child canvas -->
<canvas id="nestedCanvas" width="300" height="200" content="drawable">
<div id="nestedElement" class="badge" drawable>
Inner Child Content
</div>
</canvas>
</div>
</canvas>
<script>
const parentCanvas = document.getElementById("parentCanvas");
const parentCtx = parentCanvas.getContext("2d");
const nestedCanvas = document.getElementById("nestedCanvas");
const nestedCtx = nestedCanvas.getContext("2d");
const nestedElement = document.getElementById("nestedElement");
const wrapperElement = document.getElementById("wrapperElement");
// ============================================================================
// 1. Child Canvas Listener (Fires FIRST)
// ============================================================================
nestedCanvas.addEventListener("paint", (event) => {
// Clear and redraw the child canvas with the updated inner element
nestedCtx.clearRect(0, 0, nestedCanvas.width, nestedCanvas.height);
nestedCtx.drawElementImage(nestedElement, 10, 10);
console.log("1. Child nested canvas rendered fresh pixels.");
});
// ============================================================================
// 2. Parent Canvas Listener (Fires SECOND)
// ============================================================================
parentCanvas.addEventListener("paint", (event) => {
// Clear and redraw the parent canvas scene
parentCtx.clearRect(0, 0, parentCanvas.width, parentCanvas.height);
// Draws the wrapper container (including the freshly painted nestedCanvas)
parentCtx.drawElementImage(wrapperElement, 50, 50);
console.log("2. Parent canvas composited the complete scene.");
});
</script>
<canvas content="drawable">-Elemente verschachtelt sind, werden Paint-Ereignisse in umgekehrter Baumreihenfolge ausgelöst: Die verschachtelte Canvas wird zuerst gezeichnet, damit die übergeordnete Canvas ihre aktuellen Pixel zeichnen kann.Ereignis „paint“ auslösen
Rufen Sie requestPaint() auf, um ein einzelnes paint-Ereignis für den nächsten Frame zu planen, auch wenn sich kein DOM-Text oder keine DOM-Stile geändert haben. Dies kann beispielsweise zum Rendern interaktiver Szenen mit beweglichen Elementen verwendet werden:
let animatedX = 0;
canvas.addEventListener("paint", () => {
animatedX += 1.5; // Move the element horizontally
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawElementImage(staticElement, 20, 20);
ctx.drawElementImage(movingElement, animatedX, 200);
// Request canvas paint on each rendering update for smooth animation
canvas.requestPaint();
});
canvas.requestPaint();
Geometrie eines Elements aktualisieren
Wenn Sie ein HTML-Element in ein Canvas zeichnen, wird durch den Zeichencode festgelegt, wo das Element angezeigt wird und wie groß es ist. Im Gegensatz zu regulären HTML-Inhalten können die Position und Größe des Elements auf dem Bildschirm, also seine Geometrie, nicht allein anhand des berechneten Stils bestimmt werden. Der Browser benötigt die Geometrie eines Elements für Folgendes:
- Eingabeereignisse wie Klicks, Berührungen und Zeigerbewegungen an das richtige Element senden. Dies wird als Trefferprüfung bezeichnet.
- Genaue Ergebnisse aus Layoutabfragen wie
getBoundingClientRect()zurückgeben. - Die Grenzen des Elements werden an Hilfstechnologien wie Lupen gemeldet.
In 2D aktualisiert drawElementImage() die Geometrie standardmäßig automatisch. Die Argumente, die Sie an die Funktion übergeben, reichen zusammen mit dem berechneten Stil des Elements und der aktuellen Transformation des Kontexts aus, um zu bestimmen, wo das Element angezeigt wird.
In WebGL- und WebGPU-Kontexten kann der Browser die Geometrie nicht bestimmen. Ein HTML-Element wird in eine Textur kopiert und Ihr Shader-Programm kann diese Textur dann beliebig auf die Szene abbilden. Wenn Sie dem Browser mitteilen möchten, wo das Element angezeigt wird, übergeben Sie eine Transformation an updateElementGeometry().
updateElementGeometry() nicht mehr aufruft, weiß der Browser nicht mehr, wo sich die HTML-Elemente auf der 3D-Karte befinden. Die Karte dreht sich weiter, aber Klicks landen immer noch dort, wo sie vorher waren.Wenn Sie die Geometrie aktualisieren möchten, übergeben Sie eine räumliche Transformation an die Methode. Hier erfahren Sie, wie Sie eine Transformation für verschiedene Kontexte erstellen:
- Geometrie in 2D synchronisieren
- Geometrie in WebGL synchronisieren
- Geometrie in WebGPU synchronisieren
Stapelreihenfolge für Trefferprüfung verwalten
Standardmäßig wird ein Element jedes Mal, wenn seine Geometrie aktualisiert wird, vom Browser an die Spitze des Interaktionsstapels verschoben (zuletzt gezeichnet = oberstes Klickziel). Sie können dieses Verhalten mit preserveHitTestOrder steuern:
// Updates the backdrop without stealing clicks from foreground elements
canvas.updateElementGeometry(backgroundElement, {
canvasTransform: customTransform,
preserveHitTestOrder: true
});
| Option | Verhalten | Anwendungsfall |
|---|---|---|
preserveHitTestOrder: false (Standard) |
Verschiebt das Element an den Anfang des Trefferprüfungsstapels. | Vordergrundelemente, die zuerst angeklickt werden sollen. |
preserveHitTestOrder: true |
Das Element bleibt auf seiner aktuellen Stapelpriorität. | Hintergrundelemente, die nach den Vordergrundelementen aktualisiert werden müssen. |
Geometrie zurücksetzen
Wenn Sie ein Element entfernen möchten, ohne es aus dem DOM zu entfernen, rufen Sie canvas.clearElementGeometry() auf. Dadurch wird die Canvas-Transformation des Elements zurückgesetzt und es wird im Accessibility Tree als „offscreen“ markiert:
// Remove from canvas hit-testing and mark as offscreen
canvas.clearElementGeometry(childElement);
Größen und Einheiten
Wenn Sie HTML in ein Canvas zeichnen, arbeitet der Browser gleichzeitig in drei Koordinatensystemen: CSS-Pixel, Gerätepixel und Canvas-Rasterpixel.
CSS-Pixel werden zum Messen und Positionieren von Inhalten im Layout verwendet. Der Browser skaliert sie dann um devicePixelRatio, um die Seite in physische Gerätepixel zu rastern. Da CSS-Pixel eine logische Einheit sind, werden Positionen und Größen oft als Bruchteile eines Gerätepixels angegeben (z. B. 10,5 CSS-Pixel × DPR von 1,5 = 15,75 Gerätepixel). Ein Bildschirm kann nur ganze Pixel einfärben, daher muss der Browser alles auflösen, was dazwischen liegt. Das geschieht auf zwei Arten:
- Andocken: Boxgrenzen, Rahmen und Ebenenversätze werden auf das nächste ganze Gerätepixel gerundet, damit sie scharf bleiben.
- Anti-Aliasing: Bei Textglyphen, Kurven und transformierten Kanten wird die teilweise Abdeckung mit benachbarten Pixeln gemischt, damit sie weiterhin glatt und an der richtigen Stelle aussehen.
Ein <canvas> hat ein eigenes Pixelraster, das durch die Attribute width und height festgelegt wird und von CSS-Pixeln und Gerätepixeln getrennt ist. Zur Darstellung wird die Canvas-Bitmap vom Browser auf das physische Pixelraster neu abgetastet. Dabei werden benachbarte Canvas-Pixel gemischt, um jedes Gerätepixel zu füllen. Informationen dazu, wie der Browser zwischen CSS-, Canvas- und Gerätepixeln zuordnet, finden Sie unter Pixelgenaues Rendering mit devicePixelContentBox.
Alle drawable-HTML-Elemente werden in CSS-Pixeln dargestellt. Da in ein Canvas gezeichnete Inhalte zwei Konvertierungen durchlaufen können – von CSS-Pixeln in das Canvas-Raster und dann vom Canvas-Raster in physische Pixel –, wird bei jedem Schritt, der nicht genau übereinstimmt, eine weitere Überblendung hinzugefügt. Das Ergebnis kann unscharf aussehen. Um dies zu vermeiden, sollten Sie das Canvas-Raster an das physische Pixelraster anpassen. Dies dient zwei Zwecken:
- Konsistentes Rendering: Wenn der Canvas 1:1 auf physische Pixel abgebildet wird, führt die Umwandlung von CSS-Pixeln in Canvas-Pixel zum selben Ergebnis wie die Umwandlung von CSS-Pixeln in physische Pixel für reguläres HTML durch den Browser.
- Kein zusätzliches Blending: Wenn das Canvas 1:1 auf physische Pixel abgebildet wird, wird durch die Konvertierung in Gerätepixel keine Unschärfe hinzugefügt.
Die folgende Abbildung zeigt eine Pixelkonvertierung, die zu unscharfen Inhalten führt. Die drei Raster stimmen nicht überein: Das Canvas-Element ist 360 × 180 CSS-Pixel groß und die Canvas-Größe beträgt 300 × 150 Canvas-Rasterpixel. Bei einem Pixel-Verhältnis des Geräts von 1, 5 deckt der Canvas 540 × 270 Gerätepixel ab. Ein CSS-Pixel umfasst 1,5 Gerätepixel und ein Canvas-Pixel umfasst 1,2 CSS-Pixel oder 1,8 Gerätepixel (Bereich 1). Wenn der Kreis gezeichnet wird, werden seine Position und sein Radius in Canvas-Pixeln und nicht in CSS-Pixeln angegeben. Der Browser zeichnet ihn also in die 300 × 150-Canvas-Bitmap und glättet die Kanten (Bereich 2). Um den Canvas anzuzeigen, dehnt der Browser diese Bitmap dann über 540 × 270 Gerätepixel, sodass der Browser interpolieren muss: Jedes Gerätepixel nimmt eine gewichtete Mischung der nächstgelegenen Canvas-Pixel auf, die bereits die geglättete Kante enthalten. Der Rand wird ein zweites Mal gemischt und erstreckt sich über mehrere Gerätepixel, sodass der Kreis unscharf aussieht (Bereich 3). Das könnte vermieden werden, wenn das Canvas-Raster 1:1 mit den Gerätepixeln übereinstimmen würde. Der Browser würde dann die Kante nur einmal direkt im Geräteraster glätten und die Bitmap ohne Resampling anzeigen, sodass die Kante scharf bleibt (Bild 4):
Für eine scharfe Darstellung muss das Canvas-Raster mit der Anzahl der Gerätepixel übereinstimmen, die das Canvas abdeckt: 540 × 270 im vorherigen Beispiel.
Größe des Canvas-Rasters mit einem ResizeObserver anpassen
Die richtige Rastergröße hängt vom Gerät ab und kann sich ändern, wenn sich das Layout ändert, der Nutzer die Seite zoomt oder das Fenster auf ein anderes Display verschiebt. Anstatt die Rastergröße fest zu codieren, lassen Sie sich vom Browser mitteilen, wie groß sie sein soll.
Damit das Canvas-Raster mit dem Canvas auf dem Bildschirm synchron bleibt, sollten Sie es immer mit ResizeObserver dimensionieren und das Canvas-Raster auf devicePixelContentBoxSize anpassen:
const observer = new ResizeObserver(([entry]) => {
const dpc = entry.devicePixelContentBoxSize;
canvas.width = dpc ? dpc[0].inlineSize : Math.round(entry.contentRect.width * window.devicePixelRatio);
canvas.height = dpc ? dpc[0].blockSize : Math.round(entry.contentRect.height * window.devicePixelRatio);
});
const supportsDevicePixelContentBox =
typeof ResizeObserverEntry !== 'undefined' &&
'devicePixelContentBoxSize' in ResizeObserverEntry.prototype;
const options = supportsDevicePixelContentBox ? { box: 'device-pixel-content-box' } : {};
observer.observe(canvas, options);
CSS-Pixel in Canvas-Rasterkoordinaten umwandeln
Ein paint-Handler kombiniert häufig DOM-Messungen mit Zeichenbefehlen, z. B. um ein Element basierend auf seiner Größe zu positionieren. Die beiden verwenden unterschiedliche Einheiten:
- Canvas-Pixel beschreiben das Canvas-Raster, dessen Größe durch
canvas.widthundcanvas.heightdefiniert wird. Beispiele: die Parameterdx,dy,dwidthunddheightder ZeichenmethodendrawElementImage()oder andere Canvas API-Parameter wiefillRect()undtranslate(). - CSS-Pixel beschreiben die Seite. DOM-Messungen wie
offsetWidthundclientWidthsowie Zeigerereigniskoordinaten wieoffsetXwerden in CSS-Pixeln angegeben.
Hier finden Sie eine Übersicht über die Einheiten, die von verschiedenen API-Parametern verwendet werden:
| Wert | Einheiten |
|---|---|
canvas.width und canvas.height |
Pixel des Canvas-Rasters |
2D-Zeichnungsparameter, einschließlich dx, dy, dwidth und dheight von drawElementImage() |
Pixel des Canvas-Rasters |
width und height von canvas.getElementImageDefaultSize() zurückgegeben |
Pixel des Canvas-Rasters |
Quellrechtecke: sx, sy, swidth und sheight von drawElementImage() und texElementSubImage2D(); sourceX, sourceY, sourceWidth und sourceHeight von drawElementImageToTexture() |
CSS-Pixel |
Texturgrößen: width und height Optionen von texElementSubImage2D(); size von drawElementImageToTexture() |
Texturpixel. Standardmäßig die Größe des Elements in Pixeln des Zeichenflächenrasters, aufgerundet |
Elementgeometrie: getElementTransform() und die Optionen canvasTransform und canvasClip von updateElementGeometry() |
CSS-Pixel |
DOM-Messungen wie offsetWidth, clientWidth, getBoundingClientRect(), Koordinaten von Zeigerereignissen und contentBoxSize eines ResizeObserver-Eintrags |
CSS-Pixel |
devicePixelContentBoxSize eines ResizeObserver-Eintrags |
Gerätepixel |
Wenn Sie die falschen Einheiten verwenden, entspricht die Größe des HTML-Inhalts, der in den Canvas gezeichnet wird, möglicherweise nicht Ihren Erwartungen. Sie müssen den CSS-Pixelwert in Canvas-Rasterpixel umwandeln, wenn Sie HTML in Canvas zeichnen. Berechnen Sie dazu das Verhältnis zwischen der Rastergröße und der CSS-Größe des Canvas: canvas.width / cssContentWidth horizontal und canvas.height / cssContentHeight vertikal. Der ResizeObserver ist ein praktischer Ort, um das Verhältnis wie folgt zu berechnen:
// The number of canvas grid pixels per CSS pixel
let scaleX = 1;
let scaleY = 1;
const observer = new ResizeObserver(([entry]) => {
const dpc = entry.devicePixelContentBoxSize;
const cssContentWidth = entry.contentRect.width;
const cssContentHeight = entry.contentRect.height;
// Best practice: make the canvas grid match the physical pixel grid
if (dpc) {
canvas.width = dpc[0].inlineSize;
canvas.height = dpc[0].blockSize;
} else {
canvas.width = Math.round(cssContentWidth * window.devicePixelRatio);
canvas.height = Math.round(cssContentHeight * window.devicePixelRatio);
}
scaleX = canvas.width / cssContentWidth;
scaleY = canvas.height / cssContentHeight;
});
const supportsDevicePixelContentBox =
typeof ResizeObserverEntry !== 'undefined' &&
'devicePixelContentBoxSize' in ResizeObserverEntry.prototype;
const options = supportsDevicePixelContentBox ? { box: 'device-pixel-content-box' } : {};
observer.observe(canvas, options);
Multiplizieren Sie dann die CSS-Pixelwerte mit scaleX und scaleY, bevor Sie sie an die Zeichenmethode übergeben. So zentrieren Sie beispielsweise ein zeichnungsfähiges Element im Canvas:
const ctx = canvas.getContext('2d');
const card = document.getElementById('card');
canvas.onpaint = () => {
ctx.reset();
// offsetWidth and offsetHeight are in CSS pixels.
// Convert them to canvas grid coordinates.
const width = card.offsetWidth * scaleX;
const height = card.offsetHeight * scaleY;
const x = (canvas.width - width) / 2;
const y = (canvas.height - height) / 2;
// drawElementImage() takes canvas grid coordinates.
ctx.drawElementImage(card, x, y);
};
Da drawElementImage() den Rahmen des Elements zeichnet, verwenden Sie box-sizing: border-box, um Padding und Rahmen in die width und height der Karte einzubeziehen, damit die Karte in der von Ihnen festgelegten Größe gezeichnet wird:
#card {
/* Make width and height include padding and border */
box-sizing: border-box;
width: 200px;
padding: 16px;
}
Barrierefreiheit von HTML-in-Canvas
Im Allgemeinen wird der HTML-Inhalt eines <canvas content="drawable"> für Bedienungshilfen auf die gleiche Weise wie reguläres DOM bereitgestellt. Das bedeutet, dass er in der Baumstruktur für Bedienungshilfen dargestellt wird, sofern er nicht explizit mit Attributen wie aria-hidden="true" oder inert ausgeblendet wird. Es gibt jedoch eine wichtige Ausnahme: ein drawable-Element, dessen gerenderte Geometrie noch nicht festgelegt oder aktualisiert wurde.
Ein drawable-Element in einem <canvas content="drawable"> hat keine gerenderte Geometrie, wenn:
- Sie wurde noch nicht mit
drawElementImage()gerendert, wodurch die Geometrie standardmäßig automatisch aktualisiert wird. - Die Geometrie wurde nicht explizit mit
updateElementGeometry()aktualisiert.
Wenn ein drawable-Element keine gerenderte Geometrie hat, werden dieses drawable-Element und seine drawable-Unterstruktur ohne Geometrieinformationen an die Baumstruktur für Bedienungshilfen gemeldet. Das ist beispielsweise hilfreich, um Screenreadern den Zugriff auf den semantischen Inhalt zu ermöglichen, während visuelle Bedienungshilfen (wie Lupen) angewiesen werden, die nicht gezeichneten Elemente herauszufiltern.
Im folgenden Beispiel wird die Semantik einer Abbildung, eines Bildes und einer Bildunterschrift beibehalten, während das Bild und die Abbildung separat gezeichnet werden:
<canvas id="canvas" width="400" height="300" content="drawable">
<figure id="figure">
<img drawable id="image" src="..." alt="image alt text" />
<figcaption drawable id="caption">A caption</figcaption>
</figure>
</canvas>
<script>
const ctx = canvas.getContext('2d');
canvas.onpaint = () => {
ctx.reset();
// Note: Because `preserveElementGeometry` defaults to false, the
// `drawElementImage` call automatically updates geometry, ensuring
// the image and caption have geometry information for accessibility.
ctx.drawElementImage(image, 0, 0);
ctx.drawElementImage(caption, 0, 200);
};
</script>
Fallback-Strategien
Die HTML-in-Canvas API wurde in Chrome 157 eingeführt und wird möglicherweise nicht in allen Browsern unterstützt. Damit Ihre Lösung für alle Nutzer reibungslos funktioniert, sollten Sie prüfen, ob der Browser die API unterstützt, und bei Bedarf auf eine alternative Lösung zurückgreifen:
export function supportsHtmlInCanvas() {
if (typeof document === 'undefined') return false;
const canvas = document.createElement('canvas');
canvas.setAttribute('content', 'drawable');
return canvas.content === 'drawable';
}
Wenn die API nicht unterstützt wird, können Sie je nach Ihren Implementierungszielen eine der folgenden Alternativen auswählen:
- Eine alternative UI
- Schwebende HTML-Overlays
- Die Bibliothek three-html-render
- html2canvas
- dom-to-image
Nächste Schritte
- HTML in einem 2D-Kontext rendern
- HTML in einem WebGL-Canvas rendern
- HTML in einem WebGPU-Canvas rendern
- Informationen zu Fallback-Strategien
- Melden Sie ein Problem auf GitHub, um uns Feedback zu geben.
- Sehen Sie sich die HTML-in-Canvas-Demosammlung der Community an.