Skip to content

feat(engine): per-subtree time remapping#64

Merged
LeadcodeDev merged 1 commit into
mainfrom
feat/time-remapping
Jul 19, 2026
Merged

feat(engine): per-subtree time remapping#64
LeadcodeDev merged 1 commit into
mainfrom
feat/time-remapping

Conversation

@LeadcodeDev

Copy link
Copy Markdown
Owner

Closes #53.

Goal: slow-motion/replay of a group without touching each child — time_scale/time_offset on containers remap time for their whole subtree.

  • Semantics: t_local = (t_global − time_offset) × time_scale, composed in cascade as an affine (scale, shift) transform. The animation ctx stays global through the recursion; each node derives its local time from the composed remap — the pre-remapped-ctx variant double-applies the transform (a sub-agent introduced exactly that bug; caught and fixed during the workstream).
  • Everything time-driven follows: CSS animation overrides, timeline style states, audio-reactive bindings, motion-blur ghost offsets. start_at/end_at windows are shifted by stagger in local time, then converted back to global ((t_local − shift)/scale) for the paint-pass check.
  • BuiltScene.time_params (per-node, stagger_delays pattern) feeds the dispatcher: internal animations (counter, draw_in, typewriter) and PaintCtx.time advance at local time; scene_duration stays global (documented in code + skill).
  • validate rejects time_scale ≤ 0; the builder clamps defensively. HTML: <rm-flex time_scale="0.5"> already works via the generic rm-* mapping (snake_case attrs; documented in the new skill rule).

Tests: 7 new — five pixel tests (slowed fade, delayed start, window under scale, 0.5×0.5 cascade, internal draw_in through the dispatcher path) + two validator tests. 339 total, all green. Process caveat recorded: tests were written alongside the implementation (parallel sub-agents), not observed red against the final code — they did catch the double-remap bug.

Verify: cargo test --workspace → 339 passed ✓ · cargo fmt --check ✓ · clippy gated ≤1 ✓

time_scale/time_offset on containers (flex/grid/card/div/positioned)
remap time for their whole subtree: t_local = (t - offset) * scale,
composed in cascade as an affine (scale, shift) transform threaded
through the builder recursion. The animation ctx stays GLOBAL down
the recursion — each node derives its local time from the composed
remap (a pre-remapped ctx double-applies; caught in review).
Animations, timeline states, audio-reactive bindings and motion-blur
ghosts follow the local time; start_at/end_at windows convert back to
global after local stagger shifting; BuiltScene.time_params feeds the
dispatcher so internal animations and PaintCtx.time advance at local
time (scene_duration stays global, documented). validate rejects
time_scale <= 0; builder clamps defensively. Skill rule added.
@LeadcodeDev
LeadcodeDev merged commit d5365f5 into main Jul 19, 2026
@LeadcodeDev
LeadcodeDev deleted the feat/time-remapping branch July 19, 2026 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(engine): per-subtree time remapping

1 participant