To nye web-teknologier imponerer meg stort

Det går stadig lengre tid mellom hver gang jeg blir skikkelig imponert over ny webteknologi. Men Pretext og «HTML in Canvas» imponerer!

Nå som AI-verktøy tilsynelatende lar «hvem som helst» lage nesten hva som helst i løpet av en kveld, merker jeg at terskelen for å bli imponert har blitt høyere.

De siste ukene har det likevel dukket opp et par nye teknologier som har ført til en bølge av ganske oppsiktsvekkende demoer.

To av de mest interessante teknologiene er Pretext og HTML in Canvas.

Pretext – lynkjapp måling av tekst

Cheng Lou, tidligere medlem av React-kjerneteamet i Meta og nå utvikler i Midjourney, står bak biblioteket Pretext.

Kort fortalt lar det deg måle nøyaktig hvor mye plass tekst vil ta på skjermen – før den rendres i DOM-en.

Dette er kjappere enn dagens metode: Frem til nå har man vanligvis pleid å legge teksten inn i DOM-en og sjekke hvor mye plass den tar ved å bruke metoder som getBoundingClientRect eller offsetHeight. Dette utløser en layout reflow – en treg og kostbar operasjon.

Pretext hopper over dette ved å bruke nettleserens canvas-API til å gjøre alle font-målinger på forhånd og deretter regne ut hvor mye plass hvert eneste ord bruker, samt linjebryting, linjehøyde, osv. Deretter plasserer du ut teksten selv, enten på et canvas eller i DOM-en – da med «absolute positioning» av alle elementer.

Da Cheng Lou delte prosjektet på X, tok det helt av. Tråden har fått titalls millioner visninger, og utviklere kastet seg raskt på med egne eksperimenter og demoer. Noe av det er genuint nytt – ting jeg i hvert fall ikke har sett på web før.

Du finner en masse imponerende demoer på Pretexts offisielle nettside her: https://pretextjs.dev/pretext-demo

Wes Bos i Podcasten Syntax tror Pretext kan være bare én av flere byggeklosser i et større prosjekt – og at Midjourney kanskje planlegger for eksempel en «Figma-killer»:

Nytt forslag: HTML in Canvas

Støvet etter Pretext hadde knapt lagt seg før det dukket opp enda en «snakkis» i sosiale medier: HTML in Canvas.

Dette er et forslag fra WICG (Web Incubator Community Group) som foreløpig bare er tilgjengelig i Chrome Canary – og bak et flagg (chrome://flags/#canvas-draw-element). Altså veldig eksperimentelt.

Som det fremgår av navnet lar HTML in Canvas deg rendre ekte, interaktive HTML-elementer direkte på et <canvas>, for eksempel slik:

<canvas id="canvas" style="width: 400px; height: 200px;" layoutsubtree>
  <div>
    <h1>Tittel</h1>
    <p>Her kommer litt tekst</p>
  </div>
</canvas>

Legg merke til layoutsubtree-attributten på canvas-elementet. Det betyr kort fortalt at alt mellom den første div-en i koden over blir en del av en layout som kan tegnes ut til canvasen. HTML-elementene oppfører seg som om de er synlige, men er ikke synlige før de eksplisitt tegnes ut på canvasen.

For å tegne ut (rendre) HTML-elementene bruker du metoden drawElementImage(). Det er også WebGL/WebGPU-støtte, da bruker du i stedet for drawElementImage metodene WebGLRenderingContext.texElementImage2D og copyElementImageToTexture.

Den tredje byggeklossen i HTML in Canvas er paint-eventet. Dette er et event som fyrer når rendringen av HTML-elementene på canvaset endres, slik at du vet når du må tegne opp canvaset på nytt. Her er et eksempel fra utvikleren selv på hvordan du viser et skjema på et canvas:

<canvas id="canvas" style="width: 400px; height: 200px;" layoutsubtree>
  <form id="form_element">
    <label for="name">name:</label>
    <input id="name">
  </form>
</canvas>

<script>
  const ctx = document.getElementById('canvas').getContext('2d');

  canvas.onpaint = () => {
    ctx.reset();
    const transform = ctx.drawElementImage(form_element, 100, 0);
    form_element.style.transform = transform.toString();
  };

  // Size the canvas grid to match 
  // the device scale factor to prevent blurriness.
  const observer = new ResizeObserver(([entry]) => {
    canvas.width = entry.devicePixelContentBoxSize[0].inlineSize;
    canvas.height = entry.devicePixelContentBoxSize[0].blockSize;
  });
  observer.observe(canvas, {box: 'device-pixel-content-box'});
</script>

Hva kan du bruke det til?

Det som gjør dette spesielt, er at det fortsatt er ekte HTML. Du kan markere elementene, inspisere dem, bruke input-felter og knapper, legge på klasser og style dem med CSS, og så videre.

Det at det er vanlige HTML-elementer som beholder egenskapene til disse betyr også at det er enklere å rendre kompleks tekst-layout på et canvas uten at det går utover for eksempel tilgjengelighet.

Mange av demoene som har blitt publisert er kanskje imponerende, men ikke så nyttige. Jeg ser likevel for meg at teknikken kan brukes til mye spennende, som for eksempel til å rendre rike 2D-grensesnitt (for eksempel menyer) på overflater inne i 3D-scener i spill, eller til å lage nettsider som skiller seg ut med avanserte visuelle effekter.

For moro skyld lagde jeg en liten demo. Siden du trenger Chrome Canary og jeg ikke vet om du har det, embedder jeg den som en video:

0:00
/0:11

Inspiserer vi canvaset ser vi at det er vanlige HTML-elementer inne i canvaset.

Har du Chrome Canary med HTML in Canvas aktivert, kan du åpne denne lenken for å se demoen «live». Kildekoden finner du på min Github

Det ligger også en masse demoer ute på nettet, blant annet har noen laget en samleside her: https://html-in-canvas.dev/demos/

Mozilla advarer

Før du nå går berserk og bygger om alle de produksjonskritiske web-prosjektene dine til å bruke HTML in Canvas: Dette er som nevnt bare et forslag – og det er langt fra sikkert dette kommer til å bli en del av web-standarden. Eller at den kommer til å støttes av alle nettlesere.

Mozilla er blant de som stiller seg kritisk til hele forslaget, av mange årsaker som du kan lese mer om blant annet her.

Uansett: Jeg synes det er innmari gøy å se hvor mye spennende som skjer med web-teknologi nå! Og jeg kommer garantert til å leke meg med både Pretext og HTML in Canvas. På hobbyprosjektene mine, vel å merke!