Skill 18 · Hyperframes Animation
Subchapter 18.97
rules/spring-pop-entrance.mdMarkdown6 KBView on GitHub
Smooth beats bouncy. This entrance defaults to a smooth long-tail settle —
power3.out(orexpo.outfor a faster front) — that decelerates cleanly into the resting size with no overshoot. Bouncyback.outis the #1 instant turn-off in agent-made videos and is almost never executed well; it is a rare, explicitly-playful exception (consumer / fun brand), never the default. When unsure, settle smoothly.
THE entrance primitive: an element (or staggered group) arrives by springing from nothing — scale: 0 → 1, optional small y rise — and settles without bouncing. This is arrival, not reaction: distinct from press-release-spring.md (a click/press → release feedback chain on an element that already rests on screen). Many blueprints used to borrow that rule to fake an entrance; reach for this instead.
One fromTo carries the whole arrival: from { scale: 0, opacity: 0 } (explicit, so t=0 is correct under seek) to { scale: 1, opacity: 1, ease: "power3.out" }. For a group, the same fromTo runs per element at i * STAGGER, capped so the group reads as one arriving beat. The scale grow is load-bearing; the y rise is garnish — drop everything else and it must still read as a clean entrance. Let the ease produce the settle: never hand-key a scale: 1.1 mid-state (it double-bounces against the curve).
<!-- inside a standard scene clip (hyperframes-core) -->
<div class="pop-hero" id="hero">{heroLabel}</div>
<div class="pop-grid">
<div class="pop-item">{itemA}</div>
<div class="pop-item">{itemB}</div>
<div class="pop-item">{itemC}</div>
</div>.pop-hero,
.pop-item {
transform-origin: 50% 50%; /* in-place pop; move to the source point for the anchored variation */
will-change: transform;
}
.pop-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: GRID_GAP;
place-items: center;
}// Single hero pop — smooth long-tail settle, no overshoot.
tl.fromTo(
"#hero",
{ scale: 0, opacity: 0 },
{ scale: 1, opacity: 1, duration: POP_DUR, ease: "power3.out" },
ENTRY_AT,
);
// Staggered group pop — one arriving beat.
gsap.utils.toArray(".pop-item").forEach((el, i) => {
tl.fromTo(
el,
{ scale: 0, opacity: 0, y: Y_RISE },
{ scale: 1, opacity: 1, y: 0, duration: POP_DUR, ease: "power3.out" },
GROUP_ENTRY_AT + i * STAGGER,
);
});power3.out, no rotation, Y_RISE 0–12px — a weighted, confident landing for a hero wordmark or product shot.power3.out or expo.out for a punchier front, Y_RISE ~24px — cards, icons, callouts.springEase({ response: 0.4 }) (critically damped) from ../adapters/gsap-easing-and-stagger.md → Spring Eases; take duration from the helper.transform-origin to that point (e.g. 0% 100%) so scale: 0 → 1 reads as “emerging from the source”, not “inflating in place”.back.out(OVERSHOOT) and optionally settle a small rotation: ROT_FROM → 0 so elements look hand-placed. Only for a deliberately playful register — never product / enterprise / serious tone:tl.fromTo(
el,
{ scale: 0, opacity: 0, rotation: ROT_FROM },
{ scale: 1, opacity: 1, rotation: 0, duration: POP_DUR, ease: `back.out(${OVERSHOOT})` },
GROUP_ENTRY_AT + i * STAGGER,
);Even here keep OVERSHOOT ≤ ~2 — past that it reads as cartoon wobble. Better still: the baked spring at dampingFraction: 0.6–0.7 (same adapters doc) gives ~5–10% overshoot that reads physical where back.out reads cartoon.
| token | range | notes |
|---|---|---|
| EASE | power3.out default; expo.out punchier | back.out(OVERSHOOT) only in the playful variant |
| POP_DUR | 0.4–0.7s | shorter = tight snap; hero must be visible by t ≤ 0.5s |
| STAGGER | 0.04–0.08s | min(0.06, 0.5 / ITEM_COUNT) — self-caps the window |
| ITEM_COUNT | 3–9 | >9 makes the stagger vanish — switch to a wipe/sweep reveal |
| Y_RISE | 0–32px | small; never large enough to read as a slide-up |
| ROT_FROM | −10°–+10° | playful variant only; alternate sign by index (i % 2 ? 6 : -6) |
| ENTRY_AT | 0–0.4s | a beat of quiet, but keep the subject landing by t ≤ 0.5s |
power3.out (no overshoot); back.out only in the explicitly-playful variant, and there OVERSHOOT ≤ ~2.ITEM_COUNT × STAGGER ≤ ~0.5s — the group must land inside one beat.fromTo — never rely on a CSS-hidden start (it renders visible before the tween claims it under seek).transform-origin: 50% 50% for an in-place pop; the source point only for the anchored variation.sine-wave-loop tween.center-outward-expansion (pop while radiating to slots) · press-release-spring (the click-feedback counterpart) · sine-wave-loop (post-arrival jitter, sparingly).