HTML renderen in een WebGPU-canvas biedt alle voordelen van HTML in een WebGL-canvas, zoals shader-effecten toepassen op de DOM of interactieve HTML integreren in 3D-scènes. WebGPU biedt wel aanzienlijke voordelen ten opzichte van WebGL.
In deze handleiding wordt uitgelegd hoe je HTML rendert in een WebGPU-canvas. Meer informatie over HTML-in-Canvas in het API-overzicht.
Voor de weergave van HTML in een WebGPU-canvas zijn de volgende stappen vereist:
- 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.
- Pas de HTML toe als textuur:
- Wijs GPU-textuuropslag vooraf toe.
- Upload de DOM-momentopname als een textuur.
- Synchroniseer het DOM en de pixels.
Een HTML-element tekenen als een WebGPU-textuur
In WebGPU worden HTML-elementen geüpload naar de GPU als 2D-texturen met drawElementImageToTexture().
Textuuropslag vooraf toewijzen
WebGPU vereist expliciete geheugentoewijzing. Voordat je DOM-pixels naar een textuur kopieert, moet je GPU VRAM reserveren met de methode device.createTexture():
const context = canvas.getContext("webgpu");
// Pre-allocate the texture size as needed
// For example: HTML element CSS size × devicePixelRatio
const size = canvas.getElementImageDefaultSize(myElement);
const myElementWidth = Math.ceil(size.width);
const myElementHeight = Math.ceil(size.height);
// Pre-allocate the GPUTexture backing (run once during setup)
const myTexture = device.createTexture({
size: {
width: myElementWidth,
height: myElementHeight,
depthOrArrayLayers: 1, // optional (defaults to 1)
},
format: "rgba8unorm",
usage:
GPUTextureUsage.TEXTURE_BINDING |
GPUTextureUsage.COPY_DST |
GPUTextureUsage.RENDER_ATTACHMENT,
});
Afbeelding van HTML-element tekenen
In WebGPU tekent de methode drawElementImageToTexture() de momentopname van het HTML-element. De methode gebruikt 2 woordenboekobjecten: source en destination.
source definieert het bron-DOM-element dat moet worden gerasterd en optionele subrechthoekige knipcoördinaten waarmee je alleen een deel van het element naar je textuur kunt kopiëren in plaats van de hele DOM-node:
| Property | Type | Beschrijving |
|---|---|---|
source vereist |
Element of ElementImage |
Het doel-DOM-element (of vooraf vastgelegde ElementImage-instantie) dat in de textuur moet worden getekend. |
sourceX optioneel (alle 4 of geen) |
float | De horizontale X-coördinaatverschuiving (in CSS-pixels) die de linkerbovenhoek van de subrechthoek van de bron definieert. |
sourceY optioneel (alle 4 of geen) |
float | De verticale Y-coördinaatverschuiving (in CSS-pixels) die de linkerbovenhoek van de subrechthoek van de bron definieert. |
sourceWidth optioneel (alle 4 of geen) |
float | De breedte (in CSS-pixels) van de bron-subrechthoek die moet worden bijgesneden en gerasterd. |
sourceHeight optioneel (alle 4 of geen) |
float | De hoogte (in css-pixels) van de bron-subrechthoek die moet worden bijgesneden en gerasterd. |
destination definieert de doel-GPU-textuur die de gerenderde DOM-momentopname krijgt, samen met optionele bestemmingsoffsets, mip-niveaus en kopieerdimensies om de pixels in een specifieke regio van de textuur te plaatsen:
| Property | Type | Beschrijving |
|---|---|---|
texture vereist |
GPUTexture |
De vooraf toegewezen WebGPU-bestemmingstextuur die de gerenderde DOM-pixelmomentopname krijgt. |
size optioneel |
GPUExtent3D |
De breedte en hoogte (in fysieke textuurpixels, bijvoorbeeld { width, height }) om het element te schalen en te rasteren binnen de bestemmingstextuur. |
origin optioneel |
GPUOrigin3D |
De 3D-bestemmingsverschuiving (x, y, z) binnen de textuur waar de gerasterde pixels worden geschreven. De standaardwaarde is [0, 0, 0]. |
mipLevel optioneel |
GPUIntegerCoordinate |
Het specifieke mipmap-niveau van de bestemmingstextuur waarnaar moet worden geschreven. De standaardwaarde is 0. |
aspect optioneel |
GPUTextureAspect |
Geeft aan naar welk textuuraspect moet worden gekopieerd ("all", "stencil-only" of "depth-only"). De standaardwaarde is "all". |
colorSpace optioneel |
PredefinedColorSpace |
De bestemmingskleurruimte (bijvoorbeeld "srgb", "display-p3") voor kleurconversie bij uploaden. De standaardwaarde is "srgb". |
premultipliedAlpha optioneel |
booleaans | Of alfa vooraf moet worden vermenigvuldigd in de kleurkanalen tijdens de upload. De standaardwaarde is false. |
Upload het element naar je textuur in de gebeurtenis paint door de methode drawElementImageToTexture() aan te roepen:
canvas.addEventListener("paint", (event) => {
const sourceDict = {
source: myElement,
// Optional sub-rectangle crop in CSS pixels
// (defaults to full element if omitted):
sourceX: 0,
sourceY: 0,
sourceWidth: myElement.offsetWidth,
sourceHeight: myElement.offsetHeight,
};
const destDict = {
texture: myTexture,
size: { width: myElementWidth, height: myElementHeight },
};
// Upload the latest DOM snapshot into the pre-allocated GPUTexture
device.queue.drawElementImageToTexture(sourceDict, destDict);
});
Geometrie synchroniseren
Als je DOM-hit-testing en focusringen voor toegankelijkheid wilt uitlijnen met de gerenderde canvasuitvoer, maak je een DOMMatrix-transformatie en pas je deze toe met de updateElementGeometry()-methode:
// Construct a transform as needed in CSS pixels
// relative to the canvas, for example:
// 1/8 of the canvas width from the left edge, vertically centered.
// scaleX, scaleY: canvas grid pixels per CSS pixel (from resize observer)
const canvasCssWidth = canvas.width / scaleX;
const canvasCssHeight = canvas.height / scaleY;
const elementCssHeight = canvas.getElementImageDefaultSize(myElement).height / scaleY;
const x = canvasCssWidth / 8;
const y = (canvasCssHeight - elementCssHeight) / 2;
const transform = new DOMMatrix().translate(x, y);
// Synchronize the element's DOM hit-testing and accessibility geometry
canvas.updateElementGeometry(myElement, { canvasTransform: transform });
Volgende stappen
- Inzicht krijgen in de technische kernconcepten achter HTML-in-Canvas.
- Meer informatie over hoe je HTML rendert in een 2D-context.
- Meer informatie over hoe je HTML rendert in een WebGL-canvas.
- Meer informatie over terugvalstrategieën.
- Dien een probleem in op GitHub om je feedback te delen.
- Ga naar de verzameling HTML-in-Canvas-demo's van de community.