Contexte et motivation
Les développeurs web doivent souvent choisir entre le DOM, qui fournit une sémantique riche et une intégration native aux outils du navigateur, et le <canvas>, qui offre un accès bas‑niveau aux pixels pour des rendus 2D/3D performants. Cette dichotomie entraîne des surcoûts de bundle lorsqu’il faut reproduire des fonctionnalités du DOM (mise en forme du texte, contrôles de formulaire, accessibilité) dans un contexte canvas.
L’HTML‑in‑Canvas API, disponible en origin trial dans Chrome 148‑150, vise à éliminer ce compromis en autorisant le rendu direct d’éléments DOM à l’intérieur d’un canvas tout en conservant leur interactivité et leur visibilité pour les services du navigateur.
Fonctionnement de l'API HTML‑in‑Canvas
Le processus repose sur trois étapes : configuration du canvas, rendu de l’élément, puis mise à jour du transform CSS. La première étape consiste à ajouter l’attribut layoutsubtree au <canvas>. Cet attribut indique au moteur que le sous‑arbre DOM doit être considéré comme partie intégrante du rendu canvas et qu’il doit être exposé à l’arbre d’accessibilité.
<canvas id="canvas" style="width:200px;height:200px;" layoutsubtree>
<div id="form_element">
<label for="name">Name:</label> <input id="name" type="text">
</div>
</canvas>Pour éviter le flou, le script ajuste la taille du tampon du canvas en fonction du facteur d’échelle du dispositif via ResizeObserver. Le code suivant montre la logique de mise à l’échelle :
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);
});
observer.observe(canvas, {box: 'device-pixel-content-box'});Le rendu dépend du contexte graphique. En 2D, la méthode ctx.drawElementImage(element, x, y) copie le rendu DOM dans le tampon du canvas et renvoie une matrice de transformation à appliquer au CSS de l’élément. En WebGL, gl.texElementImage2D agit comme gl.texImage2D mais accepte un nœud DOM comme source. En WebGPU, la fonction queue.copyElementImageToTexture réalise l’équivalent.
// 2D rendering
const ctx = canvas.getContext('2d');
canvas.onpaint = () => {
ctx.reset();
const transform = ctx.drawElementImage(form_element, 0, 0);
// appliquer transform au style CSS
};
// WebGL rendering
canvas.onpaint = () => {
if (gl.texElementImage2D) {
gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, form_element);
}
};
// WebGPU rendering
canvas.onpaint = () => {
root.device.queue.copyElementImageToTexture(
form_element,
{texture: targetTexture}
);
};Cas d’usage et implications
L’API ouvre la voie à des applications où l’interface utilisateur doit coexister avec des scènes graphiques complexes. Les éditeurs de documents en ligne, les outils de design comme Figma, ou les jeux WebXR peuvent désormais placer des champs de texte, des menus ou des contrôles de formulaire directement dans le rendu 3D tout en conservant la sélection, le copier‑coller et la navigation au clavier. Les extensions de navigateur, les outils de traduction ou les modes sombre continuent de fonctionner sans adaptation supplémentaire.
Du point de vue du référencement, le texte rendu via l’API reste indexable par les moteurs de recherche et exploitable par les agents d’intelligence artificielle, car il demeure présent dans l’arbre d’accessibilité.
Limitations et perspectives
Le principal frein réside dans le statut d’essai : l’API n’est active que derrière le drapeau chrome://flags/#canvas-draw-element et nécessite une inscription au origin trial. De plus, le rendu dépend de la fréquence d’appel de l’événement onpaint; des scénarios à haute fréquence peuvent impacter les performances si le navigateur doit recalculer le transform à chaque frame. Enfin, la compatibilité reste limitée à Chrome 148‑150 ; les autres navigateurs ne supportent pas encore ces méthodes.
En résumé, l’HTML‑in‑Canvas API propose une solution technique concrète aux problèmes d’interopérabilité entre le DOM et le canvas, tout en exposant de nouvelles exigences de gestion de la synchronisation graphique.