You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 01fa31d
Browse filesBrowse the repository at this point in the historyBrowse files
feat(skills): motion-blur-streak — per-frame-driven form for elements riding a baked track
Extends rules/motion-blur-streak.md with a Per-Frame-Driven Carve-In: when an element is driven
from a baked track (tracked insert, shake-matched title) there is no tween window to share, so the
envelope becomes a per-frame function of the track delta — velocity-gated text-free silhouette
ghosts (Path B, the default for driven subtrees) or a rotate/blur/counter-rotate filter sandwich
(Path A), streak axis from atan2 of the delta. Adds the Values rows, the constraint, and updates
the rules-index row.
Copy file name to clipboardExpand all lines: skills/hyperframes-animation/rules-index.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,7 +93,7 @@ A rule's own **Critical Constraints** section lists only what is SPECIFIC to tha
93
93
<card-morph-anchorpath="rules/card-morph-anchor.md">Container morphs apparent size + corner radius + surface treatment between two shots, then fades to reveal the real target underneath. HyperFrames substitutes uniform `scale` for the forbidden `width`/`height` tween, plus paint-only `borderRadius`/`background`/`boxShadow`. Tags: morph, anchor, transition, border-radius, container, shape, handoff</card-morph-anchor>
94
94
<theme-crossfade-morphpath="rules/theme-crossfade-morph.md">Whole-theme in-place morph under a fixed anchor — background, typography, radii, icons, chrome and logos blend simultaneously (~0.3s) through N pre-styled skins while one anchor element never moves. Stacked complete layers + opacity-only crossfade, anchor rendered once on top (or per-layer at identical geometry); static camera. Single container instead → `card-morph-anchor`. Tags: theme, skin, crossfade, morph, anchor, reskin, cycle, ui</theme-crossfade-morph>
95
95
<spring-pop-entrancepath="rules/spring-pop-entrance.md">The canonical ENTRANCE pop — an element (or staggered group) arrives by springing `scale: 0 → 1` with `back.out` overshoot, `fromTo` so it's correct at t=0 under seek. Single hero, staggered group (≤500ms cap), overshoot tuned by personality. Distinct from `press-release-spring` (a click/press reaction). Tags: spring, entrance, pop, scale-in, overshoot, stagger, arrival</spring-pop-entrance>
96
-
<motion-blur-streakpath="rules/motion-blur-streak.md">Fake directional velocity blur on a fast entrance / camera push-through — blur peaks at max speed, resolves to 0 at the settle. Two paths: SVG `feGaussianBlur` stdDeviation on the motion axis (proxy-tweened), or a deterministic echo/ghost trail that collapses into the lead. Entrances / mid-shot only. Tags: motion-blur, streak, velocity, ghost, echo, fast</motion-blur-streak>
96
+
<motion-blur-streakpath="rules/motion-blur-streak.md">Fake directional velocity blur on a fast entrance / camera push-through — blur peaks at max speed, resolves to 0 at the settle. Two paths: SVG `feGaussianBlur` stdDeviation on the motion axis (proxy-tweened), or a deterministic echo/ghost trail that collapses into the lead. Entrances / mid-shot only. Per-frame-driven form for an element riding a baked track: velocity-gated text-free silhouette ghosts (or a rotate/blur/counter-rotate filter sandwich when a true blur is the look), streak axis from `atan2` of the track delta. Tags: motion-blur, streak, velocity, ghost, echo, fast, driven, tracked</motion-blur-streak>
97
97
<waterfall-entrypath="rules/waterfall-entry.md">Staggered ARRIVAL cascade — words/elements whip in from below, each starting before the previous settles, an accelerating wave that resolves composed. Title cards, segment openers, list intros. Binary 0→1 opacity via `tl.set` — never fade an arrival. Tags: entrance, cascade, stagger, kinetic-text, title-card, arrival, waterfall</waterfall-entry>
98
98
<particle-burstpath="rules/particle-burst.md">Deterministic particle / confetti events — confetti pop that bursts up and drifts down on gravity (optional instant-shrink), dot burst from behind text, glyph dissolve to particles. Fixed pool, index-seeded launch values, one `ease: "none"` driver whose onUpdate computes each particle as a pure ballistic function of time — scrub-safe mid-flight, ≤ ~40 particles. Tags: particles, confetti, burst, dissolve, ballistic, deterministic, punctuation</particle-burst>
99
99
<nudge-curvepath="rules/nudge-curve.md">Slow-fast-slow three-phase group slide (power3.in ramp → linear burst → power4.out tail, 10/65/25 distance, tail ≥3× ramp-in) to reposition a composed group and reveal content during the burst. Tags: slide, reposition, group-motion, nudge, slow-fast-slow</nudge-curve>
Copy file name to clipboardExpand all lines: skills/hyperframes-animation/rules/motion-blur-streak.md
+58-16Lines changed: 58 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
1
---
2
2
name: motion-blur-streak
3
-
description: Fake directional velocity blur on a fast entrance or camera push-through — blur peaks at max speed and resolves to 0 at the settle, so the element streaks in then snaps sharp. Two paths — SVG feGaussianBlur on the motion axis, or an echo/ghost trail that collapses into the lead.
3
+
description: Fake directional velocity blur on a fast entrance or camera push-through — blur peaks at max speed and resolves to 0 at the settle, so the element streaks in then snaps sharp. Two paths — SVG feGaussianBlur on the motion axis, or an echo/ghost trail that collapses into the lead. Plus a per-frame-driven form for an element riding a baked track (tracked insert, shake-matched title): velocity-gated text-free silhouette ghosts (or a rotate/blur/counter-rotate filter sandwich when a true blur is the look), streak axis from the track delta.
@@ -12,7 +12,9 @@ Real motion blur isn't available to a seeked renderer (it integrates over shutte
12
12
-**(A) Directional SVG blur** — inline `<feGaussianBlur stdDeviation="X 0">` (X on the motion axis, 0 across it), tweened via a proxy. Cleanest; a true directional smear.
13
13
-**(B) Echo / ghost trail** — 2–4 duplicates at decreasing opacity, offset backward along the motion vector, collapsing into the lead as it settles. No filter cost; a stylized "speed-line" trail.
14
14
15
-
**Entrances and mid-shot moves only — never a mid-composition exit.** A blurred element fleeing off-frame mid-composition reads as a glitch; a hard exit between scenes is the transition's job (`../transitions/overview.md`). One sanctioned scope extension: the envelope may ride the **camera wrapper** during a travel leg — see the Camera-Travel Carve-Out.
15
+
Both paths assume a **tween window** — an element driven per frame from a baked track has none; that form is the Per-Frame-Driven Carve-In below.
16
+
17
+
**Entrances and mid-shot moves only — never a mid-composition exit.** A blurred element fleeing off-frame mid-composition reads as a glitch; a hard exit between scenes is the transition's job (`../transitions/overview.md`). Two sanctioned scope extensions: the envelope may ride the **camera wrapper** during a travel leg (Camera-Travel Carve-Out), or become a per-frame function of a baked track for a **driven element** (Per-Frame-Driven Carve-In).
When the element is not tweened but **driven** — a tracked insert or callout riding a baked per-frame track, a title matched to camera shake — there is no move window to share. The envelope becomes a per-frame function of the track's own delta, computed in the same `onUpdate` that applies the position:
108
+
109
+
```js
110
+
// inside the frame-lookup driver (an ease:"none" proxy → frames[i]); TRACK.x / TRACK.y are baked arrays
111
+
constj=Math.max(1, i); // frame 0 borrows the frame-1 delta so a seek to t=0 has a defined state
112
+
constdx=TRACK.x[j] -TRACK.x[j -1];
113
+
constdy=TRACK.y[j] -TRACK.y[j -1];
114
+
constspeed=Math.hypot(dx, dy); // px per frame
115
+
constangle= (Math.atan2(dy, dx) *180) /Math.PI; // the streak axis IS the travel direction
116
+
117
+
// Path B, driven form (the default here): text-free silhouette clones trail the lead along −delta.
-**Ghosts are text-free silhouettes** — the lead's box, border, radius and fill with **no content** (`aria-hidden="true"`, `data-layout-allow-overlap`). A 25–50%-opacity clone reads as shape; a clone carrying the text reads as a duplicate element, and content-free clones give the layout and contrast checkers nothing to flag.
135
+
-**Velocity-gated, not window-shaped** — the trail exists only above `TRAIL_GATE` px/frame and scales with speed (`min(TRAIL_MAX, TRAIL_K × speed)`): a slow drift shows nothing, a whip shows a 180°-shutter smear. It is slaved to the lead's own opacity so an entrance or exit fade takes the trail with it.
136
+
-**Axis from the baked delta** — `atan2(dy, dx)` per frame; the streak follows the track around corners with nothing to seed at setup.
137
+
138
+
**Which path for a driven subtree.** Path B is the default: it costs no filter raster (a full filter region re-rasterizes every frame under per-frame drive), its clones carry no text so the layout and contrast checkers see nothing new, and it degrades to nothing when the track is still. Path A in the driven form is legitimate when a true blur is the look. Both forms measured deterministic on the reference host (2026-09-08: single-card 120-frame and three-card 450-frame drives of each path, hardware-GL and software lanes, every double render bit-identical) — but a per-frame-driven filter is the first thing to re-measure on a new host: keep the double-render frame-hash comparison (`--format png-sequence` twice) in the pipeline rather than trusting one clean run. One earlier build (2026-08) observed 1-LSB `feGaussianBlur` jitter under per-frame load and shipped Path B for that reason.
| MOVE_EASE |`expo.out` / `power4.out` (default) / `power3.out`|`out`-family ONLY — `in`/`inOut` puts peak speed in the wrong place; position and blur share it |
108
-
| MOVE_DUR | 0.25–0.6s | over ~0.7s reads as a focus pull, not velocity |
109
-
| ENTER_FROM_X/Y | 40–120% of the element's own dimension | enough runway for the streak to read |
110
-
| PEAK_BLUR | 8–30 (default 18) | >30 erases the glyph at the start; ~18–20 cap at wrapper level |
111
-
| SCALE_FROM | 1.3–2.5 | push-through variation |
112
-
| N (ghosts) | 2–4 | >4 reads as strobe, not streak |
113
-
| ECHO_STEP_PX | 12–40px |`N × step ≲ ENTER_FROM` so the furthest ghost starts inside the runway |
114
-
| GHOST_BASE_OPACITY | 0.3–0.6 | opaque ghosts read as duplicate elements |
115
-
| CARD_STAGGER | 0.05–0.12s | one assembling wave, not separate arrivals |
| MOVE_EASE |`expo.out` / `power4.out` (default) / `power3.out`|`out`-family ONLY — `in`/`inOut` puts peak speed in the wrong place; position and blur share it |
145
+
| MOVE_DUR | 0.25–0.6s | over ~0.7s reads as a focus pull, not velocity |
146
+
| ENTER_FROM_X/Y | 40–120% of the element's own dimension | enough runway for the streak to read |
147
+
| PEAK_BLUR | 8–30 (default 18) | >30 erases the glyph at the start; ~18–20 cap at wrapper level |
148
+
| SCALE_FROM | 1.3–2.5 | push-through variation |
149
+
| N (ghosts) | 2–4 | >4 reads as strobe, not streak |
150
+
| ECHO_STEP_PX | 12–40px |`N × step ≲ ENTER_FROM` so the furthest ghost starts inside the runway |
151
+
| GHOST_BASE_OPACITY | 0.3–0.6 | opaque ghosts read as duplicate elements |
152
+
| CARD_STAGGER | 0.05–0.12s | one assembling wave, not separate arrivals |
153
+
| TRAIL_GATE | 3–6 px/frame (default 4) | driven form: below it the track counts as still — no trail, no blur |
154
+
| TRAIL_K · TRAIL_MAX | 0.05 · 0.32 | driven form: ghost opacity `min(TRAIL_MAX, TRAIL_K × speed)` — hits the cap at ~6 px/frame |
155
+
| TRAIL_OFFSETS | 0.25 / 0.5 of the per-frame delta | two clones = a discrete 180° shutter; a third at 0.75 only for a long whip |
156
+
| SIGMA_MAX | 8–12 | driven Path A: `σ = min(SIGMA_MAX, 0.5 × speed)` along the travel axis |
116
157
117
158
## Critical Constraints
118
159
119
160
- Blur peaks at peak speed and resolves to 0 at the settle — share the ease and window between position and envelope. A blur that lingers after the stop reads as a focus pull.
120
-
- Entrances / mid-shot arrivals only — never a mid-composition exit; wrapper-level use only per the carve-out.
161
+
- Entrances / mid-shot arrivals only — never a mid-composition exit; wrapper-level use only per the Camera-Travel Carve-Out, per-frame-driven use only per the Per-Frame-Driven Carve-In.
121
162
- Seed `stdDeviation` at setup: at `PEAK_BLUR` for the entrance shape, at 0 for a whip / `inOut` leg.
122
163
- Generous filter region (`x="-50%" y="-50%" width="200%" height="200%"`) or the smear clips at the element's box edge.
123
164
- Directional axis: `"X 0"` horizontal, `"0 Y"` vertical, `"B B"` only for a depth/scale move — symmetric blur on a sideways move looks like defocus.
124
165
- Dwell ≥1 s sharp after the snap; a streak landing at the last beat reads as "flashed and gone".
125
166
- Heavy element on a solid field — thin type (< ~120px / 800 weight) or a busy backdrop swallows the smear.
126
167
-`overflow: hidden` on the scene — the smear / furthest ghost extends past the resting position during travel.
168
+
- Driven form: clones are text-free silhouettes (`aria-hidden`, `data-layout-allow-overlap`), opacity slaved to the lead, axis from the baked delta; nothing is seeded at setup except the structural frame-0 state.
127
169
128
170
## See also
129
171
130
-
`kinetic-beat-slam` (streak as one beat's entrance) · `center-outward-expansion` (grid streak-in) · `scale-swap-transition` (same-footprint morph — not an arrival) · `nudge-curve` (the whip sweep's position half) · `3d-camera-flight` / `viewport-change` (the carve-out's wrappers).
172
+
`kinetic-beat-slam` (streak as one beat's entrance) · `center-outward-expansion` (grid streak-in) · `scale-swap-transition` (same-footprint morph — not an arrival) · `nudge-curve` (the whip sweep's position half) · `3d-camera-flight` / `viewport-change` (the Camera-Travel Carve-Out's wrappers).
0 commit comments