{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "html-in-canvas-shader",
 "name": "Shader auf echtem DOM (HTML-in-Canvas)",
 "name_en": "HTML-in-Canvas / shaders on live DOM",
 "kurz": "Ein echtes HTML-Produkt-UI wird zur Shader-Textur: es kippt in Perspektive, liegt unter einer Glaslinse oder löst sich beim Ansichtswechsel auf und bleibt dabei bedienbar.",
 "kategorie": "3D & WebGL",
 "kategorie_slug": "3d-webgl",
 "kategorie_nr": 11,
 "bau_chat": "C5",
 "prioritaet": "C",
 "trendstatus": "aufsteigend",
 "belegstatus": "quellenbelegt",
 "website_belege": 0,
 "stimmung": [
  "präzise",
  "experimentell"
 ],
 "stimmung_roh": [
  "experimentell",
  "technisch"
 ],
 "technik": [
  "html-in-canvas",
  "webgl-shader",
  "webgpu",
  "canvas"
 ],
 "technik_gruppen": [
  "webgl",
  "canvas"
 ],
 "leistungskosten": "mittel",
 "steckbrief": {
  "beschreibung": "Ein canvas bekommt echte DOM-Kinder: Attribut content=\"drawable\" (vorher layoutsubtree). In 2D zeichnet drawElementImage() ein Element ins Canvas. In WebGL lädt texElementSubImage2D() das Element als Textur, der Speicher wird vorher mit texImage2D() angelegt. WebGPU nutzt drawElementImageToTexture(). Darauf laufen Shader wie Glaslinse, Wellen, Dissolve oder 3D-Neigung, und das UI bleibt bedienbar. In WebGL und WebGPU meldet canvas.updateElementGeometry() die Transformation, damit Klicks, Fokus und Barrierefreiheit an der sichtbaren Stelle liegen.",
  "warum_es_wirkt": "Es löst das Grundproblem von WebGL-Oberflächen: Der Effekt liegt auf echtem, zugänglichem und responsivem HTML statt auf einer Kopie oder einem Screenshot.",
  "wann_einsetzen": "Für Experimente und Lab-Seiten und als progressive Verbesserung in Chromium mit Origin-Trial-Token, etwa für ein Produkt-UI im Hero.",
  "wann_nicht": "Für produktionskritische Funktionen. Die API ist im Origin Trial und wurde mehrfach umbenannt.",
  "varianten": [
   "DOM-Textur auf geneigter 3D-Fläche",
   "Glaslinse über dem DOM",
   "Shader-Übergang zwischen zwei DOM-Zuständen"
  ],
  "umsetzung": "Per Feature-Erkennung prüfen, welche API-Generation da ist (texElementSubImage2D oder texElementImage2D), und verzweigen. Ohne Unterstützung bleibt normales DOM sichtbar. Wer den Effekt trotzdem zeigen will, nimmt einen Schnappschuss per SVG foreignObject mit eingebetteten Schriften und erneuert ihn nach jeder DOM-Änderung. Das ist teurer und hinkt bei Hover nach. Responsives Verhalten des UI dann über Container-Abfragen lösen, weil @media im Schnappschuss die Bildgröße sieht.",
  "mobil": "HTML-in-Canvas nur in Chromium für Android mit Origin Trial, sonst normales DOM. Effekte auf Tippen statt Hover legen.",
  "reduzierte_bewegung": "Effekte aus, das DOM bleibt normal und unverändert.",
  "barrierefreiheit": "Hauptvorteil: Das DOM bleibt zugänglich und per Tastatur bedienbar. Die Geometrie muss zur Darstellung passen, sonst liegen Klick und Fokus neben dem Bild. Das Canvas selbst bekommt aria-hidden."
 },
 "messwerte": {
  "easing": "",
  "dauer_ms": "",
  "stagger_ms": "",
  "distanz": "",
  "sonstiges": "Origin Trial bis Chrome 160",
  "herkunft": "beobachtet",
  "quelle": "https://developer.chrome.com/blog/html-in-canvas-ot-changes?hl=en"
 },
 "kurve": null,
 "gesehen_bei": [
  {
   "seite": "Chrome Developers – HTML-in-Canvas updates",
   "url": "https://developer.chrome.com/blog/html-in-canvas-ot-changes?hl=en",
   "auszeichnung": "",
   "beobachtung": "Origin Trial bis Chrome 160; API-Umbenennungen in 155; 2D hält Hit-Testing/Fokusringe automatisch synchron, in WebGL/WebGPU per updateElementGeometry.",
   "art": "artikel"
  },
  {
   "seite": "Codrops – Exploring the HTML-in-Canvas Proposal",
   "url": "https://tympanus.net/codrops/2026/05/13/exploring-the-html-in-canvas-proposal/",
   "auszeichnung": "",
   "beobachtung": "Laut Feed: Funktionsweise und Möglichkeiten mit Demos.",
   "art": "artikel"
  }
 ],
 "tutorials": [
  {
   "titel": "Exploring the HTML-in-Canvas Proposal",
   "url": "https://tympanus.net/codrops/2026/05/13/exploring-the-html-in-canvas-proposal/"
  },
  {
   "titel": "HTML-in-Canvas updates: Iterating toward a better Web API",
   "url": "https://developer.chrome.com/blog/html-in-canvas-ot-changes?hl=en"
  }
 ],
 "kombinierbar_mit": [
  "liquid-glass-refraktion",
  "shader-uebergang-dissolve",
  "webgl-bildverzerrung"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/3d-webgl/html-in-canvas-shader/",
  "meta": "https://cecodesign.de/lab/fundus/3d-webgl/html-in-canvas-shader/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/3d-webgl/html-in-canvas-shader/demo"
 },
 "herkunft": {
  "quelldateien": [
   "material3d.json",
   "patch-belege-2.json"
  ],
  "pruefnotizen": [
   "patch-belege-2.json: Kein Produktionsbeleg (Origin Trial); bleibt C."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Ein echtes HTML-Produkt-UI wird zur Shader-Textur: es kippt in Perspektive, liegt unter einer Glaslinse oder löst sich beim Ansichtswechsel auf und bleibt dabei bedienbar.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "kurve": "cubic-bezier(0.25, 0.46, 0.45, 0.94) (easeOutQuad, Rezept saas-produkt-praezise) für Aufrichten und Dissolve",
   "ui": "160 ms cubic-bezier(0.25, 0.46, 0.45, 0.94) für Hover, Schalter, Reiter",
   "kippen": "rotateX 12°, rotateY 16°, Zeiger ±4° (Lerp 0.08 je Bild bei 60 Bildern/s), perspective 1600 px; über dem UI richtet es sich in 600 ms auf",
   "kippen_licht": "Licht von oben links (-0.35, -0.6, 1), Helligkeit 1 + (n·l − l.z) × 1.4, Glanzstreifen 7 %, Schatten 55 % Deckkraft, versetzt (−18, 34) px",
   "glas": "Linse 240 × 112 px (Telefon 150 × 84), Pillenform, gerundete Kante 28 px, Brechung 26 px am Rand, Zoom 1.12, Dispersion 0.06, Folgen per Lerp 0.14, Schatten 32 % 10 px tiefer",
   "wechsel": "Rausch-Dissolve 600 ms, Ursprung am geklickten Reiter, Anteil Rauschen 0.3 (fbm 4 Oktaven), Kante 0.035 im Markenton #ff7847",
   "geometrie_sync": "gleiche Projektion als CSS-Transform am echten DOM: perspective(1600px) rotateX() rotateY(), damit Treffer und Fokus stimmen (Live-API: updateElementGeometry)",
   "ersatz": "ohne HTML-in-Canvas: Schnappschuss per SVG foreignObject mit eingebetteten Schriften, nach DOM-Änderung neu, gedrosselt auf 90 ms; Responsivität über Container-Abfragen, weil @media im Bild die Bildgröße sähe",
   "pixelratio": "max. 2, bei Software-Rendering 1",
   "vorfuehrung": "Runde 15 s: 5 s Kippen (gedachter Zeiger), 5 s Glas, 5 s Wechsel mit zwei Reiter-Klicks"
  },
  "ausloeser": "hover",
  "touch": "Kippen: Tippen auf das UI richtet es auf, Tippen daneben kippt es zurück. Glas: Tippen setzt die Linse an die Stelle. Wechsel: Reiter antippen. Unter 520 px Containerbreite zeigt die App ihr Telefon-Layout, kleinere Linse.",
  "reduziert": "Shader aus, das UI ist normales HTML ohne Neigung, Linse und Dissolve. Reiter wechseln hart. Ein Hinweis unter der Bühne sagt es.",
  "korrekturen": {
   "beschreibung": "Ein canvas bekommt echte DOM-Kinder: Attribut content=\"drawable\" (vorher layoutsubtree). In 2D zeichnet drawElementImage() ein Element ins Canvas. In WebGL lädt texElementSubImage2D() das Element als Textur, der Speicher wird vorher mit texImage2D() angelegt. WebGPU nutzt drawElementImageToTexture(). Darauf laufen Shader wie Glaslinse, Wellen, Dissolve oder 3D-Neigung, und das UI bleibt bedienbar. In WebGL und WebGPU meldet canvas.updateElementGeometry() die Transformation, damit Klicks, Fokus und Barrierefreiheit an der sichtbaren Stelle liegen.",
   "warum_es_wirkt": "Es löst das Grundproblem von WebGL-Oberflächen: Der Effekt liegt auf echtem, zugänglichem und responsivem HTML statt auf einer Kopie oder einem Screenshot.",
   "wann_einsetzen": "Für Experimente und Lab-Seiten und als progressive Verbesserung in Chromium mit Origin-Trial-Token, etwa für ein Produkt-UI im Hero.",
   "wann_nicht": "Für produktionskritische Funktionen. Die API ist im Origin Trial und wurde mehrfach umbenannt.",
   "varianten": [
    "DOM-Textur auf geneigter 3D-Fläche",
    "Glaslinse über dem DOM",
    "Shader-Übergang zwischen zwei DOM-Zuständen"
   ],
   "umsetzung": "Per Feature-Erkennung prüfen, welche API-Generation da ist (texElementSubImage2D oder texElementImage2D), und verzweigen. Ohne Unterstützung bleibt normales DOM sichtbar. Wer den Effekt trotzdem zeigen will, nimmt einen Schnappschuss per SVG foreignObject mit eingebetteten Schriften und erneuert ihn nach jeder DOM-Änderung. Das ist teurer und hinkt bei Hover nach. Responsives Verhalten des UI dann über Container-Abfragen lösen, weil @media im Schnappschuss die Bildgröße sieht.",
   "mobil": "HTML-in-Canvas nur in Chromium für Android mit Origin Trial, sonst normales DOM. Effekte auf Tippen statt Hover legen.",
   "reduzierte_bewegung": "Effekte aus, das DOM bleibt normal und unverändert.",
   "barrierefreiheit": "Hauptvorteil: Das DOM bleibt zugänglich und per Tastatur bedienbar. Die Geometrie muss zur Darstellung passen, sonst liegen Klick und Fokus neben dem Bild. Das Canvas selbst bekommt aria-hidden."
  },
  "geprueft": "01.11.2026",
  "notiz": "Welt: Rezept saas-produkt-praezise, erfundenes Dispo-Tool „Kurbel“ aus Berlin-Kreuzberg für Lastenrad-Kurierdienste (Geist + Geist Mono, Graustufen nach Linear, ein Markenton Orange). Das Produkt-UI ist echtes HTML mit Reitern, Auswahl, Schalter und Umplanen-Knopf. Drei Varianten per Umschalter. Der Live-Weg (content=drawable/layoutsubtree, texElementSubImage2D/texElementImage2D, paint-Ereignis, updateElementGeometry) ist per Feature-Erkennung eingebaut, aber ohne Origin Trial nicht getestet; geprüft ist der Ersatz per foreignObject-Schnappschuss. Rohes WebGL ohne three. Referenzen: linear.app, n8n.io, krea.ai, clerk.com. AD-Review 01.11.2026: Note 4 Zugang 02.11.2026: Tastatur: Fokus im UI richtet die gekippte Ansicht sofort auf (echtes HTML mit Fokusring sichtbar), Fokus verlässt das UI → kippt zurück; „Details“-Knöpfe der Tourzeilen auch bei :focus-within sichtbar; Kontrastmodus-Rahmen für Knöpfe."
 }
}
