Commit Graph
2378 Commits
Author SHA1 Message Date
Miguel Angel Simon Sierra 1a9190db27 fix(registry): match GSAP center-stagger slot semantics in world-map reveal
GSAP's stagger { each: 0.02, from: 'center' } gives every element a UNIQUE
20ms slot in center-out order (total span = each * (n-1) = 3.52s for 177
countries; measured live: 21/57/93/121/155 countries visible at
t=1.5/2.23/2.93/3.5/4.19s, complete at 4.7s). anime.stagger(20,
{ from: 'center' }) scales delay by DISTANCE from center instead, so
equidistant pairs share a slot and the reveal finished at t=2.93s -- the
whole map filled roughly twice too early, matching the damaged t=1.68-4.61s
band against the baseline.

Precompute the GSAP rank order (sort by |i - center|, ties lower-index
first) and pass explicit per-element delays. Live probe after the fix:
21/58/93/121/156/177 -- within one country of GSAP at every checkpoint.
Snapshot frames at t=2.23/2.93/4.19 now match the pinned baseline.
2026-07-10 12:57:40 -04:00
Miguel Angel Simon Sierra 5bcdb37e99 fix(registry): register vfx-iphone-device timeline after GLTF models load
The GSAP original assigned window.__timelines['devices-canvas'] inside
onReady() -- only after both DRACO/GLTF device models finished loading and the
screens were captured -- so the render pipeline's readiness poll waited for
the models before capturing frame 0. The anime.js port moved registration to
script-parse time, letting the pipeline start capturing while the models were
still loading: frame 0 rendered an empty pedestal, and early-window frames
drifted against the baseline.

Move hyperframesAnime.register() into onReady() (after captureScreens), which
also makes the registration-time priming pass paint from a fully-loaded scene,
and drop the duplicate parse-time registration.

Verified by snapshot at t=0/9.13/11.08 vs the pinned GSAP baseline: 9.13 and
11.08 now match exactly (device positions and captured screen content); t=0
shows the authored hero state while the baseline's own opening 0.6s is black
(GSAP-side model-load race at the pinned fork).
2026-07-10 12:45:52 -04:00
Miguel Angel Simon Sierra d87d722df0 fix(registry): paint vfx-portal frame 0 directly after deferred panel capture
Same class as the vfx-shatter fix: hyperframesAnime.register() primes the
timeline (seek to end, back to 0), so the deferred init's tl.seek(0) is a
no-op that never fires onUpdate, and the WebGL canvas stays black for the
first captured frame (t=0 hard-fail at 3.3dB, baseline shows the light
landing page). Call renderPortal(0) directly.

Verified by snapshot at t=0/3.3/3.9 vs the pinned GSAP baseline: t=0 now
shows the landing page. The remaining PSNR gap on this item is baseline-side:
the pinned GSAP baseline's drawElementImage capture is missing ALL text
(logo, nav, hero headline, card copy) for the entire clip, while the anime.js
candidate captures it correctly.
2026-07-10 12:40:38 -04:00
Miguel Angel Simon Sierra be14c9e653 fix(registry): paint vfx-shatter frame 0 directly after deferred panel capture
hyperframesAnime.register() primes the timeline (seek to end, then back to 0),
so by the time the deferred init has captured the HTML panels into WebGL
textures, tl.currentTime is already 0 and its tl.seek(0) is a no-op that never
fires onUpdate. Nothing repaints the canvas until the first nonzero seek,
leaving the very first rendered frame solid black (single damaged checkpoint
at t=0, 19.5dB, baseline shows the full hero). Call renderFrame(0) directly
instead of seeking.

Verified via snapshot at t=0/0.5/2.0 against the pinned GSAP baseline: frame 0
now shows the hero and matches.
2026-07-10 11:02:53 -04:00
Miguel Angel Simon Sierra 0684ff71f1 fix(cli): enable CanvasDrawElement in snapshot Chrome to match render pipeline
The engine's browserManager launches render Chrome with
--enable-features=CanvasDrawElement globally, but the snapshot command's own
puppeteer launch omitted it, so any composition using ctx.drawElementImage()
(vfx-shatter, vfx-portal, ios26-liquid-glass, ...) showed its 'API required'
placeholder in snapshots while rendering fine in the real pipeline.
2026-07-10 11:02:46 -04:00
Miguel Angel Simon Sierra c7e6e5820e fix(registry): re-assert morph-text t=0 word state after anime.js priming
hyperframesAnime.register() primes each timeline by seeking to its end and
back to 0. morph-text drives its word swap from an onUpdate proxy tween with
manual DOM writes, so the mid-word text painted by the priming seek has
nothing for anime.js to restore on the return seek and the wrong headline
stuck at t=0 (baseline shows 'Do more with less.', port showed a later word).

Re-assert applyMorph(0) after registration, and normalize the modulo in
applyMorph so a float-rounding hair-below-zero T from the return seek cannot
floor to the last word. Applied to both demo.html and the distributable
morph-text.html (same pattern in both twins).

Verified by frame comparison against the pinned GSAP baseline at t=0, 10.03,
10.5 and 12.0: t=0 now matches; the t=10-14.9s soft cluster is blur-morph
antialiasing jitter with identical content.
2026-07-10 08:06:43 -04:00
Miguel Angel Simon Sierra 0f75d83846 fix(registry): drop non-authored grid option from grid-pixelate-wipe stagger
The GSAP source used a plain 1D stagger (stagger: { amount, from }, no grid),
which on a row-major 16x9 element list produces a horizontal-band reveal
(middle rows first). The anime.js port added an explicit grid: [16, 9] option
that wasn't in the original, switching anime.js to true 2D geometric
distance and producing a radial/circular reveal instead, a visibly different
wipe shape confirmed against the pinned baseline at t=2.7s.

Removing the grid option restores the original array-index-distance stagger
and matches the baseline's band-shaped reveal.
2026-07-10 02:49:13 -04:00
Miguel Angel Simon Sierra ad2a632e7f fix(registry): drive per-word glow/glitch text-shadow via numeric custom properties
anime.js v4.5.0 cannot interpolate a text-shadow tween whose from/to values
have a mismatched layer shape (a 1-layer base shadow vs. a 3-layer glitch
shadow in caption-glitch-rgb, or "none" vs. a 3-layer glow in
caption-neon-glow): it silently freezes at the last-applied value (and can
scramble color channels) instead of animating, so glitch-rgb's per-word RGB
split never resets and neon-glow's glow never appears at all.

Confirmed live via getComputedStyle probes seeking the registered timeline at
10ms increments, and by frame comparison against the pinned GSAP baseline.

Fix both by tweening only plain numbers (--glitch-off/--glitch-alpha,
--glow-r/-g/-b/-alpha) and letting CSS reconstruct the shadow, sidestepping
anime's compound-value interpolation entirely.
2026-07-10 02:29:38 -04:00
Miguel Angel Simon Sierra 268a530443 fix(core): only correct the earliest implicit transform tween per target/property (U-final)
The prior implicit-transform-from fix corrected EVERY implicit-from tween
matching a decomposed transform property, not just the first one on a given
target. Confirmed via a real render + PSNR A/B test against the commit
before that fix: registry/examples/product-promo's nested
scene1-logo-intro.html animates each Figma logo piece with two tweens on
the same target+property (an instant duration:0 jump off-screen, then an
implicit-from "converge to center" tween) -- the second tween correctly
inherits its "from" from the first tween's just-set value inside anime.js,
but the prior fix overwrote it with the element's true CSS/page-load
identity value instead, making the piece appear already-assembled at the
center from frame 0. This regressed product-promo's PSNR from ~50.5dB to
~47.0dB.

Only apply the CSS-cascade correction to the tween with the smallest
`_absoluteStartTime` for each distinct (target, property) pair; every later
implicit-from tween on that same pair is left untouched, since anime.js
already chains it correctly from the preceding tween. Verified: the
product-promo regression is resolved (51.2dB, back above baseline) while
flowchart/kinetic-type retain their original fix's improvement.
2026-07-09 20:59:16 -04:00
Miguel Angel Simon Sierra 7818e6a9c0 fix(core): rewrite anime.js clip-path "none" resets after a circle() shape (U-final)
anime.js v4.5.0 cannot correctly resolve a literal "none" clip-path target
when an earlier tween on the same element used a structured circle()
shape. Confirmed via internal tween inspection: it silently re-templates
"none" as a zeroed copy of the preceding circle()'s numeric parameters
(`_toNumbers` become `[0, 0, 0]`, reusing the prior string template),
rendering as `circle(0% at 0% 0%)` -- a near-fully-clipped, effectively
black/empty box -- instead of the intended fully-revealed state. This is
baked in at `.add()`-call time, before any seek ever runs, so it cannot be
fixed by mutating tween fields afterward.

Patch every timeline's `.add()` to rewrite a literal `clipPath: "none"`
into an equivalent fully-open `circle(150% at X% Y%)` (same shape function
anime already interpolates correctly, radius large enough to cover any
aspect ratio) whenever a tracked preceding value for that element was a
circle() shape. Leaves "none" untouched when there is no preceding
structured shape to conflict with (anime resolves that case correctly on
its own), and leaves every other property/shape untouched.

Verified against registry/blocks/transitions-light and
registry/blocks/transitions-radial (the confirmed "Family B" black/hidden
content defect from the U-final adjudication) with real render+compare-item
PSNR improvement; no regression on the other Family B members
(vfx-portal/vfx-shatter/play-mode), which do not use this clip-path pattern
and remain open with a different, not-yet-identified root cause.
2026-07-09 20:35:37 -04:00
Miguel Angel Simon Sierra 20e25341e9 fix(core): correct anime.js implicit transform from-values against CSS cascade (U-final)
anime.js v4.5.0 does not read an element's CSS-cascaded `transform` value
when resolving an implicit "from" for decomposed transform sub-properties
(translateX/Y, scale, scaleX/Y, rotate) authored without an explicit
`[from, to]` array. It silently defaults to identity instead, so any
element relying on a stylesheet rule like
`.node { transform: translate(-50%, -50%) scale(0); }` to start hidden
renders at (or near) its final position/scale from the very first frame.
Confirmed via isolated puppeteer reproduction: this is baked into anime's
internal tween node (`_fromNumber`) at `.add()` time, independent of seek
order or priming.

Correct each affected tween's `_fromNumber`/`_number` with the true
CSS-cascaded value (decomposed via DOMMatrixReadOnly) before the instance's
first-ever seek, in the existing per-instance priming pass. Verified
against registry/blocks/flowchart and registry/examples/kinetic-type
(same "content resolves ahead of schedule" defect family from the U-final
adjudication) with real render+compare-item PSNR improvement.
2026-07-09 20:27:14 -04:00
Miguel Angel Simon Sierra 3d87d63bc2 fix(core): recognize scoped hyperframesAnime self-registrations in sub-composition readiness poll 2026-07-09 18:11:12 -04:00
Miguel Angel Simon Sierra 66b4e0cc9b fix(core): recognize hyperframesAnime registrations in sub-composition readiness poll 2026-07-09 17:25:27 -04:00
Miguel Angel Simon Sierra ff57ded8ac fix(eval): recognize hyperframesAnime.register as a standalone-composition signal (U10z) 2026-07-09 17:13:29 -04:00
Miguel Angel Simon Sierra 792bcff2a8 fix(core): restore priming-stranded style properties by keyframe timing not a fixed allowlist (U10z) 2026-07-09 16:33:49 -04:00
Miguel Angel Simon Sierra 09b0849c95 fix(registry): partially fix north-korea-locked-down label centering (U10z) 2026-07-09 15:49:07 -04:00
Miguel Angel Simon Sierra 3434cc80cc fix(registry): confirm yt-lower-third centering wrapper fix (U10z) 2026-07-09 15:48:30 -04:00
Miguel Angel Simon Sierra cdfab41128 fix(registry): fix transitions-mechanical outro fade timing (U10z) 2026-07-09 15:47:53 -04:00
Miguel Angel Simon Sierra 522009180e fix(registry): apply GSAP immediateRender semantics to vpn-youtube-spot addFrom (U10z) 2026-07-09 15:47:11 -04:00
Miguel Angel Simon Sierra 8c9e17ec52 fix(core): seek nested anime.js compositions with local, offset time (U10z)
The anime.js adapter registers every composition and sub-composition as a
flat entry in window.__hfAnime and seeked ALL of them with the same raw
global time. Unlike GSAP (where sub-composition timelines are nested inside
a parent timeline and inherit correct local time from that nesting), each
anime.js registration needs its own composition's cumulative start time
subtracted before seeking, or a sub-composition mounted at a nonzero
data-start renders far ahead of where it should be (confirmed: at global
t=1.6s with data-start=1.5s, the child received seek(1600ms) instead of the
correct seek(100ms)).

Resolve each registration's host via data-composition-id, subtract its
cumulative start (reusing the existing runtime start-time resolver), and
clamp to the authored/host duration before seeking.

Verified: registry/examples/product-promo average PSNR vs GSAP baseline
20.5dB -> wait, 33.3dB -> 50.5dB (damaged checkpoints 77 -> 32) with no
regressions in the other items spot-checked. Full regression suite passes
(82 files, 1168 tests) plus a new red/green test for the nested-seek case.
2026-07-09 14:39:46 -04:00
Miguel Angel Simon Sierra 2ce3d56fc4 fix(registry): reproduce GSAP transform-axis-loss centering bug in x-post (U10z)
x-post.x-card-frame statically centered both axes (translate(-50%,-50%)),
but the GSAP baseline's gsap.to(card,{y:0}) only preserves the axis it
never animates (x); the animated y axis loses the CSS percentage
centering entirely, pinning the card's top edge at raw top:50% instead
of true vertical center. Drop the Y half of the wrapper's static
transform (translateX(-50%) only) so the anime.js port lands at the
same asymmetric resting position as the pinned GSAP baseline.

Verified: avg PSNR vs baseline 20.5dB -> 53.2dB, hard-fail checkpoints
(<30dB) 87 -> 0; residual low-band checkpoints sit at ~44dB (just under
the 45dB soft threshold), consistent with font/antialiasing render
noise rather than a positional defect.
2026-07-09 13:44:04 -04:00
Miguel Angel Simon Sierra abd1b1edf4 revert(registry): remove ios26 seek reset (U10y)
This reverts commit b078f8c09.
2026-07-09 13:08:05 -04:00
Miguel Angel Simon Sierra edb6d85b4f revert(registry): remove x-post anchor nudge (U10y)
This reverts commit 3e31e84e8.
2026-07-09 13:07:16 -04:00
Miguel Angel Simon Sierra 1cd8e6fb8e fix(registry): reset ios26-liquid-glass opening frame (U10y) 2026-07-09 12:59:37 -04:00
Miguel Angel Simon Sierra c3b9561581 fix(registry): restore x-post centering (U10y) 2026-07-09 12:58:52 -04:00
Miguel Angel Simon Sierra c6ace46482 fix(registry): keep 3d transition scene visible under outro 2026-07-09 12:37:51 -04:00
Miguel Angel Simon Sierra b83d07ec38 fix(core): preserve primed anime numeric styles 2026-07-09 12:37:01 -04:00
Miguel Angel Simon Sierra 8b95b6d59f fix(registry): render anime.js canvas scenes after explicit seeks (U10y) 2026-07-09 12:15:14 -04:00
Miguel Angel Simon Sierra 48bdb0fe56 fix(registry): preserve centered card offsets in anime.js ports (U10y) 2026-07-09 12:14:33 -04:00
Miguel Angel Simon Sierra bffd500479 fix(core): stop anime.js priming from stranding visibility set() calls (U10y) 2026-07-09 12:13:46 -04:00
Miguel Angel Simon Sierra 2d34320575 fix(studio,parsers,core): browser-safe subpath exports for classifier and ease map
The studio browser bundle imported the parsers and core package roots
(via classifyAnimationRuntime and resolveEase), dragging in node-only
assetPaths through the barrel under vite's import condition. Adds
animation-runtime-detection and ease-map subpath exports and points the
browser imports at them; repo-wide oxfmt pass for files agents missed.
2026-07-09 07:43:56 -04:00
Miguel Angel Simon Sierra ca19d29356 docs(catalog): regenerate catalog pages from ported registry (U16) 2026-07-09 03:10:32 -04:00
Miguel Angel Simon Sierra 1c3208aa06 Merge branch 'animejs-u10h' into worktree-feat-animejs-first-party 2026-07-09 03:10:01 -04:00
Miguel Angel Simon Sierra be65888d1b feat(registry): port maps, effect components, and examples to anime.js (U10h) 2026-07-09 03:09:20 -04:00
Miguel Angel Simon Sierra c73138633f docs: anime.js first-party across docs and agent surfaces (U16)
Split the animation guide into anime.js default and GSAP adapter paths.
Align docs, README, and agent templates on the new registration contract.
2026-07-09 01:16:46 -04:00
Miguel Angel Simon Sierra 3160020ff1 Merge branch 'animejs-u10x' into worktree-feat-animejs-first-party 2026-07-09 00:41:14 -04:00
Miguel Angel Simon Sierra 4c0c58bb96 fix(registry): correct broken amount-mode stagger for blue-sweater prompt typing (U10x) 2026-07-09 00:24:53 -04:00
Miguel Angel Simon Sierra 97da4f7ac9 fix(registry): rebuild code-snippet typing as seekable spans, not imperative mutation (U10x) 2026-07-09 00:13:05 -04:00
Miguel Angel Simon Sierra 8ceec2aae9 feat(studio): anime.js client editing behind the engine-neutral interface (U14) 2026-07-08 23:56:25 -04:00
Miguel Angel Simon Sierra e20e794d8c fix(registry): remediate centering and seek-reversibility defects from PSNR checkpoint (U10x) 2026-07-08 23:54:45 -04:00
Miguel Angel Simon Sierra 6d4ad62d2a feat(studio-server,studio): anime.js edit path behind runtime detection (U13)
Anime parse/mutation routes alongside untouched /gsap-* routes;
classifier-backed engine detection replacing divergent ad hoc regexes;
anime Studio-motion and manual-edit render scripts registering via
hyperframesAnime; engine-routed soft reload with a new anime path;
mixed-file property-collision edits rejected. U5 characterization
snapshots pass unmodified.
2026-07-08 22:52:51 -04:00
Miguel Angel Simon Sierra cb0c3f00d8 Merge branch 'animejs-u10c' into worktree-feat-animejs-first-party 2026-07-08 22:50:43 -04:00
Miguel Angel Simon Sierra 9c268c95a0 Merge branch 'animejs-u11c' into worktree-feat-animejs-first-party 2026-07-08 22:50:25 -04:00
Miguel Angel Simon Sierra d8ecea7780 Merge branch 'animejs-u10g' into worktree-feat-animejs-first-party 2026-07-08 22:50:07 -04:00
Miguel Angel Simon Sierra 0ff516e804 feat(registry): port transitions collections to anime.js (U10c) 2026-07-08 22:49:25 -04:00
Miguel Angel Simon Sierra 4984476280 Merge branch 'animejs-u10d' into worktree-feat-animejs-first-party 2026-07-08 22:48:46 -04:00
Miguel Angel Simon Sierra 47aa6f5540 Merge branch 'animejs-u10a' into worktree-feat-animejs-first-party 2026-07-08 21:26:38 -04:00
Miguel Angel Simon Sierra 0f6d408335 feat(registry): port lower-thirds and social blocks to anime.js (U10a) 2026-07-08 21:25:04 -04:00
Miguel Angel Simon Sierra 8bfe923fc8 Merge branch 'animejs-u10e' into worktree-feat-animejs-first-party 2026-07-08 21:17:44 -04:00
Miguel Angel Simon Sierra 7b74a92981 Merge branch 'animejs-u10b' into worktree-feat-animejs-first-party 2026-07-08 21:15:35 -04:00