Skip to content
Docs
Open Promoeyes
html

html

HTML primitives — REAL HTML + CSS as a promo stage, one trial per scene.

Read the rig's notes
`html` is the <ui> twin: a texture stage that takes ordinary markup and a
stylesheet — pug children ARE the DOM (div.hero, h1(text=…), ul/li, table,
input, img(src="image:…")) and a `style(text="…")` child is the CSS. It
renders through the WICG html-in-canvas API (drawElementImage on a
<canvas layoutsubtree>, Chromium behind --enable-features=CanvasDrawElement)
and falls back to an SVG foreignObject snapshot everywhere else — the two
tiers are pixel-identical for the same markup (packages/engine/layers/html/).
`html3d` is the <ui3d> twin: every TOP-LEVEL markup child becomes its own
world plane, placed from its live CSS layout box and animatable with the
same delta tracks a ui3d child takes.

Time is deterministic: the root carries `--t` (scene seconds) and `--p`
(0..1), and every CSS @keyframes animation is pinned to the frame's time
(paused + negative delay), so scrub / capture / export all agree.
Sizing: width/height is the stage in mm like <ui> (bare tag = 1920×1080
wall); `coords_width` lays the DOM out at that many CSS px and scales it
onto the stage — the way to put a 390px phone page on a 71mm glass.
Assets stay NAMED: img(src="image:cards-img2.jpg"), url("font:…").

PIXEL-SPACE SECTION (01–07) — full-frame billboards, camera 960 540 1320.
  01. hello      — gradient text, flex hero, a --p progress bar
  02. typography — paragraphs, lists, drop cap, balance, blockquote, mark
  03. grid       — a CSS-grid dashboard: auto-fit tiles, grid areas, shadows
  04. keyframes  — @keyframes choreography seeked deterministically
  05. table      — a pricing <table>, <code>, <kbd>, <abbr>
  06. code       — <pre><code> with span highlighting + counter line numbers
  07. forms      — native <input>/<select>/<progress>/<meter>/<button>
WORLD-SPACE SECTION (08–10) — mm, lit like a product shot.
  08. device     — iphone + laptop, each screen an html stage (coords_width)
  09. panels     — three glass <html> panes (no fill) yawed over spheres
  10. exploded   — html3d: a dashboard's children separate into Z layers

Capture: `nx run tools:capture:browser -- --project promos/primitives/html/html.promo`
(the webgl-node capture has no DOM — html stages render empty there).
Preview: /packages/runtime/index.html?project=promos/primitives/html/html.promo
Topic
uis
Scenes
10
Kind
reference rig
//
    HTML primitives — REAL HTML + CSS as a promo stage, one trial per scene.

    `html` is the <ui> twin: a texture stage that takes ordinary markup and a
    stylesheet — pug children ARE the DOM (div.hero, h1(text=…), ul/li, table,
    input, img(src="image:…")) and a `style(text="…")` child is the CSS. It
    renders through the WICG html-in-canvas API (drawElementImage on a
    <canvas layoutsubtree>, Chromium behind --enable-features=CanvasDrawElement)
    and falls back to an SVG foreignObject snapshot everywhere else — the two
    tiers are pixel-identical for the same markup (packages/engine/layers/html/).
    `html3d` is the <ui3d> twin: every TOP-LEVEL markup child becomes its own
    world plane, placed from its live CSS layout box and animatable with the
    same delta tracks a ui3d child takes.

    Time is deterministic: the root carries `--t` (scene seconds) and `--p`
    (0..1), and every CSS @keyframes animation is pinned to the frame's time
    (paused + negative delay), so scrub / capture / export all agree.
    Sizing: width/height is the stage in mm like <ui> (bare tag = 1920×1080
    wall); `coords_width` lays the DOM out at that many CSS px and scales it
    onto the stage — the way to put a 390px phone page on a 71mm glass.
    Assets stay NAMED: img(src="image:cards-img2.jpg"), url("font:…").

    PIXEL-SPACE SECTION (01–07) — full-frame billboards, camera 960 540 1320.
      01. hello      — gradient text, flex hero, a --p progress bar
      02. typography — paragraphs, lists, drop cap, balance, blockquote, mark
      03. grid       — a CSS-grid dashboard: auto-fit tiles, grid areas, shadows
      04. keyframes  — @keyframes choreography seeked deterministically
      05. table      — a pricing <table>, <code>, <kbd>, <abbr>
      06. code       — <pre><code> with span highlighting + counter line numbers
      07. forms      — native <input>/<select>/<progress>/<meter>/<button>
    WORLD-SPACE SECTION (08–10) — mm, lit like a product shot.
      08. device     — iphone + laptop, each screen an html stage (coords_width)
      09. panels     — three glass <html> panes (no fill) yawed over spheres
      10. exploded   — html3d: a dashboard's children separate into Z layers

    Capture: `nx run tools:capture:browser -- --project promos/primitives/html/html.promo`
    (the webgl-node capture has no DOM — html stages render empty there).
    Preview: /packages/runtime/index.html?project=promos/primitives/html/html.promo
promo#html
  // =======================================================================
  // SCENE 01 · HELLO — a flex hero, gradient text, --p drives the bar
  // =======================================================================
  scene#s01-hello(duration=6 transition=match-move transition-duration=0.8)
    camera(type=perspective fov=48 near=0.1 far=8000 position="960 540 1320" look_at="960 540 0")
      position
        0 960 540 1360
        6 easeInOutCubic 960 540 1300
    background(top=#081120 bottom=#04060c)
    postprocessing
      step(name=render)
      step(name=unreal_bloom strength=0.18 radius=0.4 threshold=0.85)
    haze#s01-haze-a(match=haze-a position="1320 760 -650" opacity=0.17 color=#0f6fd6 size="3100 2360" pulse=0 decay=0)
      position
        0 0 0 0
        6 easeInOutCubic -80 40 0
    haze#s01-haze-b(match=haze-b position="420 300 -680" opacity=0.11 color=#5e2a9d size="2500 1960" pulse=0 decay=0)
      position
        0 0 0 0
        6 easeInOutCubic 80 -40 0
    haze#s01-dot-a(match=dot-a position="180 880 120" opacity=0.5 color=#9be9ff size="76 76" pulse=0 decay=0)
    haze#s01-dot-b(match=dot-b position="1780 620 60" opacity=0.42 color=#e7fbff size="52 52" pulse=0 decay=0)
    text#s01-label(text="01 · hello — real DOM on a WebGL plane" kind=layer size=110 worldHeight=34 color=#8ea3c8 weight=600 align=center position="960 1032 150")
    html#s01-page(width=1920 height=1080 x=960 y=540)
      opacity
        0 0
        0.7 easeOutCubic 1
      style