Skip to content
Docs
Open Promoeyes
ui-fly

ui-fly

UI flying out of devices — ten ui3d overlay choreographies.

Read the rig's notes
`ui3d(overlay=screen …)` inside a device is the mesh twin of the flat `ui`
screen: every child mounts as a REAL plane anchored flush on the glass, in
the screen's own millimetres (an iphone glass is 71x154, so `x=5 y=32 w=61`
is a card 5mm in from the left edge). Because each child is a world plane,
its delta tracks LEAVE the screen: `position` "dx dy dz" in mm (+z toward
the camera, y down like the screen), `rotation.x` / `rotation.y` in degrees,
`scale`, `opacity` — so "0 0 0" is flush on the glass and dz=40 hovers 4cm
above it. The flat `ui` behind it stays on the glass — that is the app the
parts jump out of, and back into.

Overlay rules:
  · ALWAYS state width/height = the device's screen mm. Left off, the stage
    silently defaults to 1920x1080 and everything renders at quarter scale.
  · stack overlapping overlays with `lift` (0.5, 0.6, …) + `render_order`.
  · items are ABSOLUTE (x y w h) in screen mm — the overlay spans the whole
    display, so you pick the region with the card's own box.
  · an overlay item IS a node: it can be framed (bounds=union side=front).

  01. peel       iphone · notification cards peel off the glass one by one, hover, snap back
  02. assemble   iphone · the app flies IN from scattered origins (reverse of 01)
  03. lift       laptop · dashboard tiles rise to staggered depths, the chart swings out
  04. handoff    iphone -> laptop · a receipt card leaves the phone and lands on the desk screen
  05. fan        ipad · photo cards fan out of the tablet into a 3D arc
  06. widgets    imac · widgets pop out and hover with a slow drift
  07. modal      chrome · a dialog jumps toward the camera, the page stays behind
  08. bubbles    iphone · chat bubbles leave the phone and stack in the world beside it
  09. swarm      laptop · twelve tiles converge from twelve origins into the grid
  10. layers     iphone · the UI splits into z-layers, one card flies THROUGH the lens

AUTHORING NOTE — only the tags in the emitter's CONTENT_TAGS list group into
a parent's <children>; the rest (paragraph, headline, rich-text-block, …) is
emitted loose and appended AFTER its plain siblings at parse time. Each one
below therefore sits in its own
`card(w=hug h=hug fill=transparent shadow=false)`.

Capture: `nx run tools:capture:webgl -- --project promos/primitives/uis/ui/ui-fly.promo`
Preview: /packages/runtime/index.html?project=promos/primitives/uis/ui/ui-fly.promo
Topic
uis
Scenes
10
Kind
reference rig
//
    UI flying out of devices — ten ui3d overlay choreographies.

    `ui3d(overlay=screen …)` inside a device is the mesh twin of the flat `ui`
    screen: every child mounts as a REAL plane anchored flush on the glass, in
    the screen's own millimetres (an iphone glass is 71x154, so `x=5 y=32 w=61`
    is a card 5mm in from the left edge). Because each child is a world plane,
    its delta tracks LEAVE the screen: `position` "dx dy dz" in mm (+z toward
    the camera, y down like the screen), `rotation.x` / `rotation.y` in degrees,
    `scale`, `opacity` — so "0 0 0" is flush on the glass and dz=40 hovers 4cm
    above it. The flat `ui` behind it stays on the glass — that is the app the
    parts jump out of, and back into.

    Overlay rules:
      · ALWAYS state width/height = the device's screen mm. Left off, the stage
        silently defaults to 1920x1080 and everything renders at quarter scale.
      · stack overlapping overlays with `lift` (0.5, 0.6, …) + `render_order`.
      · items are ABSOLUTE (x y w h) in screen mm — the overlay spans the whole
        display, so you pick the region with the card's own box.
      · an overlay item IS a node: it can be framed (bounds=union side=front).

      01. peel       iphone · notification cards peel off the glass one by one, hover, snap back
      02. assemble   iphone · the app flies IN from scattered origins (reverse of 01)
      03. lift       laptop · dashboard tiles rise to staggered depths, the chart swings out
      04. handoff    iphone -> laptop · a receipt card leaves the phone and lands on the desk screen
      05. fan        ipad · photo cards fan out of the tablet into a 3D arc
      06. widgets    imac · widgets pop out and hover with a slow drift
      07. modal      chrome · a dialog jumps toward the camera, the page stays behind
      08. bubbles    iphone · chat bubbles leave the phone and stack in the world beside it
      09. swarm      laptop · twelve tiles converge from twelve origins into the grid
      10. layers     iphone · the UI splits into z-layers, one card flies THROUGH the lens

    AUTHORING NOTE — only the tags in the emitter's CONTENT_TAGS list group into
    a parent's <children>; the rest (paragraph, headline, rich-text-block, …) is
    emitted loose and appended AFTER its plain siblings at parse time. Each one
    below therefore sits in its own
    `card(w=hug h=hug fill=transparent shadow=false)`.

    Capture: `nx run tools:capture:webgl -- --project promos/primitives/uis/ui/ui-fly.promo`
    Preview: /packages/runtime/index.html?project=promos/primitives/uis/ui/ui-fly.promo
promo#ui-fly
  // =======================================================================
  // 01 · PEEL — cards peel off the phone toward the camera, then snap back
  // =======================================================================
  scene#s01-peel(duration=8 transition=match-move transition-duration=0.8)
    camera(type=perspective fov=36 near=8.5 far=17000 position="0 0 420" look_at="0 0 0")
      position
        0 30 10 450
        3.5 easeInOutCubic -50 16 390
        8 easeInOutCubic 0 0 420
      look_at
        0 0 0 0
        8 easeInOutCubic 0 0 0
    background(top=#0b1020 bottom=#04060c)
    lights
      light(type=ambient color=#8fb2ff intensity=0.85)
      light(type=directional color=#ffffff intensity=2.1 position="340 680 510")
      light(type=directional color=#7aa2ff intensity=1.25 position="-510 170 340")
    environment(hdr="studio_small_04_2k" as_background=false background_color=#05070f exposure=1.0 blurriness=0.5 intensity=0.8)
    postprocessing
      step(name=render)
      step(name=unreal_bloom strength=0.18 radius=0.45 threshold=0.88)
    haze#s01-hz-a(match=hz-a blend=add opacity=0.24 position="-380 200 -600" color=#2563EB size="2400 1800" pulse=0 decay=0)
      position
        0 0 0 0
        8 easeInOutSine 60 -30 0
    haze#s01-hz-b(match=hz-b blend=add opacity=0.2 position="360 -160 -620" color=#7C3AED size="2600