L'API HTML-in-Canvas consente di eseguire il rendering di sottoalberi DOM interattivi e accessibili direttamente in un contesto canvas 2D. Leggi la panoramica di HTML-in-Canvas per scoprire di più sull'API e sui suoi vantaggi.
Questa guida mostra come eseguire il rendering di HTML in un canvas 2D. Il rendering dell'HTML in un canvas 2D richiede i seguenti passaggi:
- Prepara la tela. Imposta in modo dichiarativo gli attributi corretti per far sapere al browser che deve eseguire il rendering del codice HTML in un canvas. Questa configurazione è identica nei contesti 2D, WebGL e WebGPU. Scopri come configurare il canvas e come dichiarare gli elementi HTML da disegnare in modo indipendente.
- Disegna l'immagine dell'elemento nel canvas.
- [Facoltativo] Sincronizza il DOM e i pixel.
Disegna elementi HTML in un canvas 2D
Una volta che il canvas è pronto e gli elementi sono contrassegnati come drawable, esegui il rendering nel contesto 2D utilizzando il metodo 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() supporta forme con 3, 5, 7 e 9 argomenti e accetta un parametro options facoltativo:
// 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);
| Modulo di sovraccarico | Parametri | Effetto layout |
|---|---|---|
| Dimensioni predefinite | (element, dx, dy) |
L'intero elemento alle dimensioni predefinite, con l'angolo in alto a sinistra in (dx, dy). |
| Riquadro Destinazione personalizzata | (element, dx, dy, dwidth, dheight) |
Scala l'immagine dell'intero elemento in un'area visibile dw × dh sul canvas. |
| Ritagliato, dimensioni predefinite | (element, sx, sy, swidth, sheight, dx, dy) |
Solo l'area swidth × sheight che inizia da (sx, sy), disegnata con le dimensioni predefinite dell'area (la stessa scala del modulo con dimensioni predefinite). |
| Sezione di origine nella destinazione | (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) |
Ritaglia l'elemento di origine a partire da (sx, sy) con dimensioni swidth × sheight, quindi lo mappa alla destinazione (dx, dy, dwidth, dheight). |
Sincronizza il DOM e i pixel
Poiché il rendering di <canvas> è imperativo, mentre il layout DOM e lo stile CSS sono reattivi, il browser ha bisogno di un meccanismo per mantenere sincronizzati i pixel del canvas visualizzati, le regioni di hit test interattive e gli alberi di accessibilità. Prima di imparare a sincronizzare il DOM e i pixel, assicurati di comprendere l'evento paint che viene attivato quando gli elementi DOM vengono aggiornati e devono essere ridisegnati.
Nei contesti canvas 2D, il browser sincronizza automaticamente le coordinate di layout dell'elemento, i limiti di accessibilità e l'hit test del puntatore con le coordinate del canvas disegnato.
Aggiorna manualmente la geometria degli elementi
In scenari avanzati, puoi disattivare la sincronizzazione automatica della geometria e controllare manualmente le trasformazioni spaziali. Passa { preserveElementGeometry: true } a drawElementImage() per impedire al browser di eseguire automaticamente l'override delle coordinate dell'hit test esistenti dell'elemento:
// 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() aggiorna automaticamente questa geometria. Questa demo mostra come la geometria non è sincronizzata quando è impostato { preserveElementGeometry: true }.Passaggi successivi
- Comprendere i concetti tecnici fondamentali alla base di HTML-in-Canvas.
- Scopri come eseguire il rendering del codice HTML in un canvas WebGL.
- Scopri come eseguire il rendering del codice HTML in un canvas WebGPU.
- Scopri di più sulle strategie di riserva.
- Invia una segnalazione su GitHub per condividere il tuo feedback.
- Dai un'occhiata alla raccolta di demo HTML-in-Canvas della community.