videos
videos
Video primitives — `video` as a UI item, one idea per scene.
Read the rig's notes
A `<video>` inside `<ui>` / `<ui3d>` is an item like any other. It goes
wherever an `image(...)` can go — device glass, a chrome window, a floating
ui3d panel — and adds the two things an image does not need:
A MASK. `clip="inherit"` (the default) reads the SHAPE OF THE PARENT.
A square parent crops square, a rounded card crops to that card's own
radius, an avatar crops to a disc. The same authored line —
video(src="video:product-loop" w="fill" h="fill" fit=cover)
— is a rectangle in one parent and a circle in the next, with nothing
about the shape written on the video itself.
A CLOCK. THE CLIP DOES NOT PLAY, IT IS SAMPLED. Scene time is the only
clock; `start` / `end` / `loop` / `speed` / `freeze` are a mapping from
scene seconds to source seconds, evaluated fresh every frame. That is
what makes a scrub, a re-render and a headless capture agree on the same
frame.
ATTRIBUTES
src|href|url an asset NAME, never a path: `video:product-loop` for the
shared library, `media:aurora-sky` for a clip that lives in
this promo's own folder. The endpoint owns the directory
and the extension.
w / h the layout box in mm. Give one axis and `aspect` (default:
the clip's own) resolves the other.
fit cover (default) | contain | fill — how the clip meets a box
of a different aspect. A UV transform, not a redraw.
clip inherit (default) | square | round | circle | none
r / radius an explicit corner radius, in mm. Beats `clip="inherit"`.
start / end the trim window in the SOURCE, in seconds.
loop true (default) — wrap scene time at the window length.
speed source seconds per scene second. 1 by default.
freeze hold the frame at `start` — a poster still, no decode churn.
color the placeholder fill shown until the first decoded frame.
opacity animatable, like every other item.
THE SHAPE TABLE (what `clip="inherit"` resolves to)
card -> its own r (default 8) container -> its radius (14)
glass-window -> r 12 window-frame -> r 12 / 10
panel -> 18 video-card -> 16
avatar, stat-ring -> a CIRCLE
row/column/grid/stack/group/box -> PASS THROUGH to the nearest drawn
ancestor (scaffolding never resets the shape to square)
the <ui> stage root -> square
anything else -> square
KNOWN LIMIT: a `card path="M…"` silhouette is not followed; the mask
falls back to that card's `r`.
SCENES
01 glass a clip filling real phone glass — square, then r=6
02 chrome the crop follows a rounded card with nothing authored;
the same video again with clip="none"
03 shapes ONE clip, four parents, one frame — the whole feature
04 fit cover vs contain vs fill on a mismatched aspect
05 time trim, speed, freeze — one source, four points in one second
06 wall macbook + ipad + iphone + a floating ui3d panel
07 scroll an ancestor's overflow clip INTERSECTING the video's mask
08 reference every attribute, called out on one board
Scenes 03/04/05/08 are full-stage <ui3d> boards: the default 1920x1080
stage mapped 1:1 into world space, camera at 960 540 <dist>, so every
coordinate below is a stage pixel with the origin at the top-left.
Preview: /packages/runtime/index.html?project=promos/primitives/videos/videos.promo- Topic
- uis
- Scenes
- 8
- Kind
- reference rig
//
Video primitives — `video` as a UI item, one idea per scene.
A `<video>` inside `<ui>` / `<ui3d>` is an item like any other. It goes
wherever an `image(...)` can go — device glass, a chrome window, a floating
ui3d panel — and adds the two things an image does not need:
A MASK. `clip="inherit"` (the default) reads the SHAPE OF THE PARENT.
A square parent crops square, a rounded card crops to that card's own
radius, an avatar crops to a disc. The same authored line —
video(src="video:product-loop" w="fill" h="fill" fit=cover)
— is a rectangle in one parent and a circle in the next, with nothing
about the shape written on the video itself.
A CLOCK. THE CLIP DOES NOT PLAY, IT IS SAMPLED. Scene time is the only
clock; `start` / `end` / `loop` / `speed` / `freeze` are a mapping from
scene seconds to source seconds, evaluated fresh every frame. That is
what makes a scrub, a re-render and a headless capture agree on the same
frame.
ATTRIBUTES
src|href|url an asset NAME, never a path: `video:product-loop` for the
shared library, `media:aurora-sky` for a clip that lives in
this promo's own folder. The endpoint owns the directory
and the extension.
w / h the layout box in mm. Give one axis and `aspect` (default:
the clip's own) resolves the other.
fit cover (default) | contain | fill — how the clip meets a box
of a different aspect. A UV transform, not a redraw.
clip inherit (default) | square | round | circle | none
r / radius an explicit corner radius, in mm. Beats `clip="inherit"`.
start / end the trim window in the SOURCE, in seconds.
loop true (default) — wrap scene time at the window length.
speed source seconds per scene second. 1 by default.
freeze hold the frame at `start` — a poster still, no decode churn.
color the placeholder fill shown until the first decoded frame.
opacity animatable, like every other item.
THE SHAPE TABLE (what `clip="inherit"` resolves to)
card -> its own r (default 8) container -> its radius (14)
glass-window -> r 12 window-frame -> r 12 / 10
panel -> 18 video-card -> 16
avatar, stat-ring -> a CIRCLE
row/column/grid/stack/group/box -> PASS THROUGH to the nearest drawn
ancestor (scaffolding never resets the shape to square)
the <ui> stage root -> square
anything else -> square
KNOWN LIMIT: a `card path="M…"` silhouette is not followed; the mask
falls back to that card's `r`.
SCENES
01 glass a clip filling real phone glass — square, then r=6
02 chrome the crop follows a rounded card with nothing authored;
the same video again with clip="none"
03 shapes ONE clip, four parents, one frame — the whole feature
04 fit cover vs contain vs fill on a mismatched aspect
05 time trim, speed, freeze — one source, four points in one second
06 wall macbook + ipad + iphone + a floating ui3d panel
07 scroll an ancestor's overflow clip INTERSECTING the video's mask
08 reference every attribute, called out on one board
Scenes 03/04/05/08 are full-stage <ui3d> boards: the default 1920x1080
stage mapped 1:1 into world space, camera at 960 540 <dist>, so every
coordinate below is a stage pixel with the origin at the top-left.
Preview: /packages/runtime/index.html?project=promos/primitives/videos/videos.promo
promo#videos
// =======================================================================
// SCENE 01 · GLASS — a clip filling real phone glass
// The video is authored twice and cross-faded: the first is square (the