mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +00:00
* feat(skills): c2v mining pass over animation blueprints and rules Compacts ~45 existing animation rules/blueprints into tighter recipe form (net -3.4k lines) and adds 17 mined from the c2v corpus: - 7 blueprints: agent-progress-theater, camera-journey, fixed-anchor-cycle, panel-edit-live-sync, prompt-type-submit-generate, transcript-scroll-artifact-reveal, zoom-out-workspace-reveal - 10 rules: 3d-camera-flight, anchored-layout-expand, chart-scrub-readout, chromatic-glitch, control-target-sync, cursor-drag, gradient-text-sweep, multi-cursor-choreography, particle-burst, theme-crossfade-morph Both indexes updated. * feat(skills): sync product-launch script bank with mined blueprint roles The role->blueprint script bank in product-launch-video/story-design.md is kept 1:1 with blueprints-index role declarations, which the c2v mining pass expanded. Adds the 25 missing entries (script-shape descriptor + example lines + pattern): 13 for the 7 new blueprints, 12 for role widenings on 7 existing ones (cursor-ui-demo, dataviz-countup, titlecard-reveal, et al.), and states the 1:1 sync contract in the bank's intro. * docs(skills): cover constellation-hub scatter-drift variant in the script bank Review follow-up on #2680: the SOCIAL_PROOF constellation-hub entry patterned only the orbit shape; the c2v pass added a scatter-drift end-card variant with the opposite geometry (no hub, no ring). Adds an example line and extends the pattern so a scatter-drift beat's VO isn't steered toward the orbit shape.
108 lines
6.4 KiB
Markdown
108 lines
6.4 KiB
Markdown
---
|
||
name: spring-pop-entrance
|
||
description: The canonical entrance pop — an element (or staggered group) arrives by scaling 0 → 1 on a smooth long-tail settle (power3 default); bouncy overshoot is a rare, explicitly-playful exception. fromTo so it's correct at t=0 under seek.
|
||
metadata:
|
||
tags: spring, entrance, pop, scale, power3, settle, stagger, reveal, arrival
|
||
---
|
||
|
||
# Spring-Pop Entrance
|
||
|
||
> **Smooth beats bouncy.** This entrance defaults to a smooth long-tail settle — `power3.out` (or `expo.out` for a faster front) — that decelerates cleanly into the resting size with **no overshoot**. Bouncy `back.out` is 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](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.
|
||
|
||
## How It Works
|
||
|
||
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).
|
||
|
||
## Recipe
|
||
|
||
```html
|
||
<!-- 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>
|
||
```
|
||
|
||
```css
|
||
.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;
|
||
}
|
||
```
|
||
|
||
```js
|
||
// 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,
|
||
);
|
||
});
|
||
```
|
||
|
||
## Variations
|
||
|
||
- **Calm settle** (premium / enterprise): `power3.out`, no rotation, `Y_RISE` 0–12px — a weighted, confident landing for a hero wordmark or product shot.
|
||
- **Firm settle** (everyday default): `power3.out` or `expo.out` for a punchier front, `Y_RISE` ~24px — cards, icons, callouts.
|
||
- **Exact-physics settle**: when the settle IS the shot, swap the ease for `springEase({ response: 0.4 })` (critically damped) from `../adapters/gsap-easing-and-stagger.md` → Spring Eases; take `duration` from the helper.
|
||
- **Origin-anchored pop**: a callout growing out of a specific point (marker, pointer tip) sets `transform-origin` to that point (e.g. `0% 100%`) so `scale: 0 → 1` reads as "emerging from the source", not "inflating in place".
|
||
- **Pop into a held slot**: land the pop and hold still — no idle loop baked into the entrance. If the held frame genuinely needs life, hand off to [sine-wave-loop.md](sine-wave-loop.md) for subtle jitter on a separate later tween; prefer revealing the next element on its VO cue.
|
||
- **Bouncy pop (RARE — explicitly-playful only)**: swap the ease for `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:
|
||
|
||
```js
|
||
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.
|
||
|
||
## Values
|
||
|
||
| 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 |
|
||
|
||
## Critical Constraints
|
||
|
||
- Default ease `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.
|
||
- Entrances state the collapsed from-state in `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.
|
||
- This is a finite arrival — idle motion on a held element is a separate, later `sine-wave-loop` tween.
|
||
|
||
## See also
|
||
|
||
`center-outward-expansion` (pop while radiating to slots) · `press-release-spring` (the click-feedback counterpart) · `sine-wave-loop` (post-arrival jitter, sparingly).
|