mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-07 01:56:04 +00:00
feat(skills): align easing docs with motion doctrine, add baked springEase (#1989)
* feat(skills): align easing docs with motion doctrine, add baked springEase The easing adapter contradicted the workflow doctrine: it taught a power2.out entrance default and pitched back/elastic as playful defaults, while motion-language.md says power3 / smooth-beats-bouncy. A worker following the adapter produced exactly the flat, cheap motion users complain about. - gsap-easing-and-stagger: power3.out becomes the documented house default; back/elastic/bounce capped as RARE playful-only; new "Spring Eases (baked physics, seek-safe)" section — closed-form damped-spring ease springEase(response, dampingFraction), measured damping ladder, response/duration table, craft notes - gsap-timeline-and-labels: last leftover power2.out default -> power3 - spring-pop-entrance: exact-physics option (zeta=1) for the settle; playful variant now prefers spring zeta 0.6-0.7 over back.out - motion-language x3 (product-launch-video, faceless-explainer, pr-to-video): doctrine "Smooth beats bouncy" wired to the baked springEase — real physics, same doctrine, not a license for bounce Verified with node + GSAP 3.15: zeta=1 strictly monotone with zero overshoot; scrambled out-of-order seeks return bit-identical values; ease(0)=0 and ease(1)=1 exact; snippet re-extracted from the published markdown and re-run. * chore: format README.md (landed unformatted on main; unblocks the repo-wide Format check)
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
"files": 144
|
"files": 144
|
||||||
},
|
},
|
||||||
"faceless-explainer": {
|
"faceless-explainer": {
|
||||||
"hash": "868057217d0499e8",
|
"hash": "d147102be8cb2c6a",
|
||||||
"files": 18
|
"files": 18
|
||||||
},
|
},
|
||||||
"figma": {
|
"figma": {
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"files": 1
|
"files": 1
|
||||||
},
|
},
|
||||||
"hyperframes-animation": {
|
"hyperframes-animation": {
|
||||||
"hash": "6323b750d67287e9",
|
"hash": "efec72bc46353a6a",
|
||||||
"files": 116
|
"files": 116
|
||||||
},
|
},
|
||||||
"hyperframes-cli": {
|
"hyperframes-cli": {
|
||||||
@@ -58,11 +58,11 @@
|
|||||||
"files": 132
|
"files": 132
|
||||||
},
|
},
|
||||||
"pr-to-video": {
|
"pr-to-video": {
|
||||||
"hash": "0bc51f6ba74b2bfd",
|
"hash": "84d65fb2b1dfd782",
|
||||||
"files": 22
|
"files": 22
|
||||||
},
|
},
|
||||||
"product-launch-video": {
|
"product-launch-video": {
|
||||||
"hash": "40bfb0bf49ae17cd",
|
"hash": "47d206f75c193862",
|
||||||
"files": 20
|
"files": 20
|
||||||
},
|
},
|
||||||
"remotion-to-hyperframes": {
|
"remotion-to-hyperframes": {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ These four rules are the difference between a clip that reads as a serious expla
|
|||||||
|
|
||||||
Elements should use **long-tail decel curves that let them settle smoothly. `power3` is enough in most cases.** No bouncy, no overshoot, no `back.out` / `bounce.out` / `elastic.out` as a default.
|
Elements should use **long-tail decel curves that let them settle smoothly. `power3` is enough in most cases.** No bouncy, no overshoot, no `back.out` / `bounce.out` / `elastic.out` as a default.
|
||||||
|
|
||||||
Bouncy is the **#1 instant turn-off** in user-made Remotion / HyperFrames videos, and the agent almost never gets it right — it thinks bouncy adds emphasis, but it buys that emphasis at the cost of cleanliness. The serious motion-design shops feel the same. **Smooth always wins.** Overshoot is demoted to a **rare, explicitly-playful exception** (a consumer/fun logo slam, a deliberate bell-hit) — never the house style. Name the intent as a long-tail settle; the worker maps `power3` (or `expo.out` on a fast arrival). See `../hyperframes-animation/rules/spring-pop-entrance.md` — it now leads with the smooth settle.
|
Bouncy is the **#1 instant turn-off** in user-made Remotion / HyperFrames videos, and the agent almost never gets it right — it thinks bouncy adds emphasis, but it buys that emphasis at the cost of cleanliness. The serious motion-design shops feel the same. **Smooth always wins.** Overshoot is demoted to a **rare, explicitly-playful exception** (a consumer/fun logo slam, a deliberate bell-hit) — never the house style. Name the intent as a long-tail settle; the worker maps `power3` (or `expo.out` on a fast arrival). See `../hyperframes-animation/rules/spring-pop-entrance.md` — it now leads with the smooth settle. (The exact form of that settle is a critically-damped spring; the worker has a baked, seek-safe `springEase` — ζ=1 — in `../hyperframes-animation/adapters/gsap-easing-and-stagger.md` → Spring Eases for when the settle is the hero. Real physics, same doctrine — not a license for bounce.)
|
||||||
|
|
||||||
## 2. Sequential reveal in the back ~50%, timed to the voiceover
|
## 2. Sequential reveal in the back ~50%, timed to the voiceover
|
||||||
|
|
||||||
|
|||||||
@@ -7,53 +7,134 @@ Built-in eases: `power1`, `power2`, `power3`, `power4`, `back`, `bounce`, `circ`
|
|||||||
Each has `.in`, `.out`, `.inOut` variants.
|
Each has `.in`, `.out`, `.inOut` variants.
|
||||||
|
|
||||||
| Ease | Use for |
|
| Ease | Use for |
|
||||||
| -------------------------- | ----------------------------------------------------------------------- |
|
| ------------------------------------------ | ----------------------------------------------------------------------------------------------- |
|
||||||
| `power1.out`, `power2.out` | Standard UI motion. Default for most entrances. |
|
| `power1.out`, `power2.out` | Gentle motion for secondary elements (a caption fade, a small shift). NOT the entrance default. |
|
||||||
| `power3.out`, `power4.out` | Punchier deceleration. Title cards, hero reveals. |
|
| `power3.out` (house default), `power4.out` | The standard long-tail settle. Entrances, title cards, hero reveals. |
|
||||||
| `sine.inOut` | Long, slow, calm motion. Crossfades, ambient drift. |
|
| `sine.inOut` | Long, slow, calm motion. Crossfades, ambient drift. |
|
||||||
| `back.out(1.7)` | Slight overshoot. Playful entrances. The arg controls overshoot amount. |
|
| `back.out(1.7)` | Overshoot then settle. RARE — explicitly-playful register only, never a default. |
|
||||||
| `elastic.out(1, 0.3)` | Springy bounce. First arg = amplitude, second = period. |
|
| `elastic.out(1, 0.3)` | Springy bounce. Same playful-only rule; prefer a baked spring (see Spring Eases below). |
|
||||||
| `expo.inOut` | Snappy, dramatic. Quick transitions between hero scenes. |
|
| `expo.inOut` | Snappy, dramatic. Quick transitions between hero scenes. |
|
||||||
| `none` (linear) | Camera moves with timed counterpoint, mechanical motion. |
|
| `none` (linear) | Camera moves with timed counterpoint, mechanical motion. |
|
||||||
|
|
||||||
Pick `.out` for entrances, `.in` for exits, `.inOut` for symmetric moves and continuous motion.
|
Pick `.out` for entrances, `.in` for exits, `.inOut` for symmetric moves and continuous motion.
|
||||||
|
|
||||||
|
**Smooth beats bouncy** — the motion doctrine (`rules/spring-pop-entrance.md`, the workflows' `motion-language.md`): entrances default to `power3.out` or the baked critically-damped spring (see Spring Eases below); overshoot eases (`back` / `elastic` / `bounce`) are a rare, explicitly-playful register, never the house style.
|
||||||
|
|
||||||
## Easing Vocabulary (character & mood)
|
## Easing Vocabulary (character & mood)
|
||||||
|
|
||||||
Easings are tone of voice: a video that only whispers is boring; one that varies between whisper, normal, and punch is engaging. Every composition should use at least 3 different easings — `power2.out` for everything produces flat, monotonous motion.
|
Easings are tone of voice: a video that only whispers is boring; one that varies between whisper, normal, and punch is engaging. A composition should draw on ~3 easing characters across its beats — but vary **within the smooth families by energy** (`sine` / `power1` calm → `power3` standard → `power4` / `expo` punch); don't reach for overshoot to add variety. Overshoot is a _register_ (explicitly playful), not a spice. One ease everywhere reads flat; bounce everywhere reads cheap — the second failure is worse.
|
||||||
|
|
||||||
The full palette by character (each family has `.in`, `.out`, `.inOut` variants):
|
The full palette by character (each family has `.in`, `.out`, `.inOut` variants):
|
||||||
|
|
||||||
| Family | Character | Typical use |
|
| Family | Character | Typical use |
|
||||||
| -------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
| -------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `power1`–`power4` | Gentle (1) to aggressive (4) acceleration curves | General purpose. power2 is the workhorse, power4 for dramatic snaps |
|
| `power1`–`power4` | Gentle (1) to aggressive (4) acceleration curves | General purpose. **power3 is the house workhorse**; power2 for gentle secondary motion, power4 for dramatic snaps |
|
||||||
| `back(N)` | Overshoot then settle. N controls how far past the target (1=subtle, 4=wild) | Logo reveals, badge pops, card entrances. `back.out(2.5)` for playful, `back.out(1.2)` for elegant |
|
| `back(N)` | Overshoot then settle. N controls how far past the target (1=subtle, 4=wild) | RARE — explicitly-playful register only, never a default. Keep N ≤ 2; prefer a baked spring at ζ 0.6–0.7 (physical settle, see Spring Eases) |
|
||||||
| `elastic(amp, freq)` | Spring bounce. amp=magnitude, freq=oscillation speed | Panel scatter, energetic drops, fun reveals |
|
| `elastic(amp, freq)` | Spring bounce. amp=magnitude, freq=oscillation speed | RARE — same playful-only rule; the baked spring (below) is the physical version |
|
||||||
| `bounce` | Ball-drop bouncing | Physical interactions, icons landing, score counters |
|
| `bounce` | Ball-drop bouncing | RARE — physical-comedy register only (something literally dropping) |
|
||||||
| `expo` | Extreme acceleration curve (much steeper than power4) | Premium/luxury reveals, dramatic entrances |
|
| `expo` | Extreme acceleration curve (much steeper than power4) | Premium/luxury reveals, dramatic entrances |
|
||||||
| `sine` | Smooth, organic, no hard edges | Ambient float, breathing, Ken Burns, anything that loops. `.inOut` for yoyo motion |
|
| `sine` | Smooth, organic, no hard edges | Ambient float, breathing, Ken Burns, anything that loops. `.inOut` for yoyo motion |
|
||||||
| `circ` | Circular acceleration (starts very fast, ends very gentle or vice versa) | Camera moves, scene transitions, orbital motion |
|
| `circ` | Circular acceleration (starts very fast, ends very gentle or vice versa) | Camera moves, scene transitions, orbital motion |
|
||||||
| `steps(N)` | Discrete N-step jumps, no interpolation | Typing effects, cursor blink, counter ticks, retro/digital aesthetics |
|
| `steps(N)` | Discrete N-step jumps, no interpolation | Typing effects, cursor blink, counter ticks, retro/digital aesthetics |
|
||||||
|
|
||||||
**Mood mapping:** Match easing character to the beat's emotional content. Smooth/organic easings (`sine`, `power1`) feel contemplative and drifting. Aggressive deceleration (`power4.out`, `expo.out`) feels snappy and confident. Spring overshoot (`back.out`) feels bouncy and physical. The storyboard's mood description should guide which character fits — not a formula.
|
**Mood mapping:** Match easing character to the beat's emotional content. Smooth/organic easings (`sine`, `power1`) feel contemplative and drifting. Aggressive deceleration (`power4.out`, `expo.out`) feels snappy and confident. Spring overshoot (`back.out`) feels bouncy and physical — but bouncy is a register, not an emphasis tool; reach for it only on explicitly-playful beats. The storyboard's mood description should guide which character fits — not a formula.
|
||||||
|
|
||||||
## Defaults
|
## Defaults
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const tl = gsap.timeline({
|
const tl = gsap.timeline({
|
||||||
paused: true,
|
paused: true,
|
||||||
defaults: { duration: 0.6, ease: "power2.out" },
|
defaults: { duration: 0.6, ease: "power3.out" }, // the house settle — smooth beats bouncy
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
Or globally:
|
Or globally:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
gsap.defaults({ duration: 0.6, ease: "power2.out" });
|
gsap.defaults({ duration: 0.6, ease: "power3.out" });
|
||||||
```
|
```
|
||||||
|
|
||||||
Setting defaults at timeline scope is preferred — it documents the motion language of that composition in one place.
|
Setting defaults at timeline scope is preferred — it documents the motion language of that composition in one place.
|
||||||
|
|
||||||
|
## Spring Eases (baked physics, seek-safe)
|
||||||
|
|
||||||
|
The "iOS feel" is a **damped spring's velocity curve**, not a bounce: a fast launch into a long asymptotic settle. Well-made system animations are critically damped or close to it — they barely overshoot, or don't at all. `power3.out` / `expo.out` approximate that curve; when you want the exact one — or a _physical_ overshoot for the rare playful register — bake the spring's closed-form solution into a function ease.
|
||||||
|
|
||||||
|
Why not a real-time spring library: an interactive spring is a stateful integrator (velocity accumulates frame to frame), which cannot be seeked deterministically — you'd have to simulate frames 0…N−1 to render frame N. The closed form below is a **pure function of progress** — no state, nothing to desync, seek-safe by construction. This is also why interaction-lib spring solvers are banned in compositions.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// springEase — a damped spring's exact position curve as a GSAP ease.
|
||||||
|
// response ≈ seconds one oscillation would take (0.3–0.6 for entrances)
|
||||||
|
// dampingFraction 1.0 = critically damped — smooth settle, NO overshoot (house default)
|
||||||
|
// 0.80–0.85 ≈ the iOS system register — ~1–1.5% overshoot, felt not seen
|
||||||
|
// 0.60–0.70 = explicitly playful — ~5–10% overshoot (rare; replaces back.out)
|
||||||
|
function springEase({ response = 0.5, dampingFraction = 1 } = {}) {
|
||||||
|
const w = (2 * Math.PI) / response; // undamped natural frequency
|
||||||
|
const z = dampingFraction;
|
||||||
|
let pos; // x(t): 0 → 1, starting at rest (v0 = 0)
|
||||||
|
if (z < 1) {
|
||||||
|
const wd = w * Math.sqrt(1 - z * z);
|
||||||
|
pos = (t) => 1 - Math.exp(-z * w * t) * (Math.cos(wd * t) + ((z * w) / wd) * Math.sin(wd * t));
|
||||||
|
} else if (z > 1) {
|
||||||
|
const wo = w * Math.sqrt(z * z - 1);
|
||||||
|
pos = (t) =>
|
||||||
|
1 - Math.exp(-z * w * t) * (Math.cosh(wo * t) + ((z * w) / wo) * Math.sinh(wo * t));
|
||||||
|
} else {
|
||||||
|
pos = (t) => 1 - Math.exp(-w * t) * (1 + w * t);
|
||||||
|
}
|
||||||
|
// Settle time: last moment the curve sits outside ±0.1% of target.
|
||||||
|
// Fixed-step scan, runs once at setup — deterministic (no Math.random / Date.now).
|
||||||
|
const EPS = 0.001;
|
||||||
|
const rate = z <= 1 ? z * w : (z - Math.sqrt(z * z - 1)) * w; // slowest decay mode
|
||||||
|
const SCAN = 12 / rate;
|
||||||
|
const N = 4800;
|
||||||
|
let T = SCAN;
|
||||||
|
for (let i = N; i >= 0; i--) {
|
||||||
|
const t = (i / N) * SCAN;
|
||||||
|
if (Math.abs(1 - pos(t)) > EPS) {
|
||||||
|
T = ((i + 1) / N) * SCAN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const xT = pos(T);
|
||||||
|
return {
|
||||||
|
duration: T, // use as the tween's duration — the settle time IS the physics
|
||||||
|
ease: (p) => pos(p * T) + p * (1 - xT), // normalized so ease(1) === 1 exactly
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage — take **both** the ease and the duration from the helper (the settle time is part of the physics; overriding the duration just re-times the same curve, so tune speed via `response` instead):
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const settle = springEase({ response: 0.4 }); // critically damped → duration ≈ 0.59s
|
||||||
|
tl.fromTo(
|
||||||
|
"#hero",
|
||||||
|
{ scale: 0, opacity: 0 },
|
||||||
|
{ scale: 1, opacity: 1, duration: settle.duration, ease: settle.ease },
|
||||||
|
0.2,
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
| dampingFraction | overshoot | register |
|
||||||
|
| ----------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **1.0 (default)** | none (monotone) | The house settle — the exact curve `power3.out` approximates. Product / enterprise / serious tone. |
|
||||||
|
| 0.80–0.85 | ~1–1.5% | "Alive, not bouncy" — the iOS system default register. The overshoot is felt, not seen. |
|
||||||
|
| 0.60–0.70 | ~5–10% | Explicitly-playful ONLY (same rule as `back.out`, which this replaces — a spring's second-order settle reads physical where `back` reads cartoon). |
|
||||||
|
| < 0.55 | > 12% | Don't. Cartoon-wobble territory. |
|
||||||
|
|
||||||
|
| response | duration (ζ=1) | feel |
|
||||||
|
| --------- | -------------- | ------------------------------------------------------------ |
|
||||||
|
| 0.25–0.35 | 0.37–0.51s | tight snap — chips, small UI |
|
||||||
|
| 0.35–0.50 | 0.51–0.74s | standard entrance |
|
||||||
|
| 0.50–0.70 | 0.74–1.03s | weighted hero landing — check the `t ≤ 0.5s` visibility rule |
|
||||||
|
|
||||||
|
Craft notes:
|
||||||
|
|
||||||
|
- **ζ=1 vs `power3.out`**: the true spring front-loads harder (~67% vs ~58% travelled at quarter-time) and settles on a longer asymptotic tail; max shape difference ~11%. That long tail is the "premium" read — use it when the settle IS the shot (a wordmark landing, a final lockup).
|
||||||
|
- **At ζ<1, overshooting curves go on transforms only** — never on `opacity` (it would push past 1) or color. Split opacity onto its own `power2.out` tween at the same timeline position.
|
||||||
|
- **Doctrine unchanged**: ζ below ~0.8 is still the rare, explicitly-playful exception (`rules/spring-pop-entrance.md`). The default of this section is ζ=1 — real spring physics is not a license for bounce.
|
||||||
|
|
||||||
## Stagger
|
## Stagger
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ HyperFrames is a seek-driven runtime. Build one paused timeline per composition,
|
|||||||
```javascript
|
```javascript
|
||||||
const tl = gsap.timeline({
|
const tl = gsap.timeline({
|
||||||
paused: true,
|
paused: true,
|
||||||
defaults: { duration: 0.5, ease: "power2.out" },
|
defaults: { duration: 0.5, ease: "power3.out" },
|
||||||
});
|
});
|
||||||
|
|
||||||
tl.to(".a", { x: 100 }).to(".b", { y: 50 }).to(".c", { opacity: 0 });
|
tl.to(".a", { x: 100 }).to(".b", { y: 50 }).to(".c", { opacity: 0 });
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ tl.fromTo(
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
Keep `OVERSHOOT` modest even here (≤ ~2) — past that it reads as a cartoon wobble, not an arrival.
|
Keep `OVERSHOOT` modest even here (≤ ~2) — past that it reads as a cartoon wobble, not an arrival. Better still: the baked spring at `dampingFraction: 0.6–0.7` (`../adapters/gsap-easing-and-stagger.md` → Spring Eases) gives ~5–10% overshoot with a second-order settle that reads physical where `back.out` reads cartoon.
|
||||||
|
|
||||||
### Origin-anchored pop (callout springs from a pointer / source)
|
### Origin-anchored pop (callout springs from a pointer / source)
|
||||||
|
|
||||||
@@ -195,6 +195,7 @@ When a popped element then **holds** an ongoing slot (a constellation node, a pe
|
|||||||
|
|
||||||
- **EASE** — the settle curve (the load-bearing decision)
|
- **EASE** — the settle curve (the load-bearing decision)
|
||||||
- Default: **`power3.out`** — a smooth long-tail settle, no overshoot; the house style for product / enterprise / serious tone. Use `expo.out` for a punchier, faster-front arrival (still smooth).
|
- Default: **`power3.out`** — a smooth long-tail settle, no overshoot; the house style for product / enterprise / serious tone. Use `expo.out` for a punchier, faster-front arrival (still smooth).
|
||||||
|
- Exact-physics option: `springEase({ response: 0.4 })` (critically damped, ζ=1) from `../adapters/gsap-easing-and-stagger.md` → Spring Eases — the curve `power3.out` approximates, with a harder front and a longer settle tail; take `duration` from the helper. Use when the settle IS the shot (a wordmark landing, a final lockup).
|
||||||
- Playful exception only: `back.out(OVERSHOOT)` — see the Bouncy pop variation; reach for it only when a bounce is clearly the brand intent.
|
- Playful exception only: `back.out(OVERSHOOT)` — see the Bouncy pop variation; reach for it only when a bounce is clearly the brand intent.
|
||||||
|
|
||||||
- **OVERSHOOT** — `back.out(OVERSHOOT)` overshoot strength — **only used in the rare bouncy variant**; the smooth default has no overshoot dial
|
- **OVERSHOOT** — `back.out(OVERSHOOT)` overshoot strength — **only used in the rare bouncy variant**; the smooth default has no overshoot dial
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ These four rules are the difference between a clip that reads as a serious code-
|
|||||||
|
|
||||||
Elements should use **long-tail decel curves that let them settle smoothly. `power3` is enough in most cases.** No bouncy, no overshoot, no `back.out` / `bounce.out` / `elastic.out` as a default.
|
Elements should use **long-tail decel curves that let them settle smoothly. `power3` is enough in most cases.** No bouncy, no overshoot, no `back.out` / `bounce.out` / `elastic.out` as a default.
|
||||||
|
|
||||||
Bouncy is the **#1 instant turn-off** in user-made Remotion / HyperFrames videos, and the agent almost never gets it right — it thinks bouncy adds emphasis, but it buys that emphasis at the cost of cleanliness. The serious motion-design shops feel the same. **Smooth always wins.** Overshoot is demoted to a **rare, explicitly-playful exception** (a consumer/fun logo slam, a deliberate bell-hit) — never the house style. Name the intent as a long-tail settle; the worker maps `power3` (or `expo.out` on a fast arrival). See `../hyperframes-animation/rules/spring-pop-entrance.md` — it now leads with the smooth settle.
|
Bouncy is the **#1 instant turn-off** in user-made Remotion / HyperFrames videos, and the agent almost never gets it right — it thinks bouncy adds emphasis, but it buys that emphasis at the cost of cleanliness. The serious motion-design shops feel the same. **Smooth always wins.** Overshoot is demoted to a **rare, explicitly-playful exception** (a consumer/fun logo slam, a deliberate bell-hit) — never the house style. Name the intent as a long-tail settle; the worker maps `power3` (or `expo.out` on a fast arrival). See `../hyperframes-animation/rules/spring-pop-entrance.md` — it now leads with the smooth settle. (The exact form of that settle is a critically-damped spring; the worker has a baked, seek-safe `springEase` — ζ=1 — in `../hyperframes-animation/adapters/gsap-easing-and-stagger.md` → Spring Eases for when the settle is the hero. Real physics, same doctrine — not a license for bounce.)
|
||||||
|
|
||||||
## 2. Sequential reveal in the back ~50%, timed to the voiceover
|
## 2. Sequential reveal in the back ~50%, timed to the voiceover
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ These four rules are the difference between a clip that reads as a serious launc
|
|||||||
|
|
||||||
Elements should use **long-tail decel curves that let them settle smoothly. `power3` is enough in most cases.** No bouncy, no overshoot, no `back.out` / `bounce.out` / `elastic.out` as a default.
|
Elements should use **long-tail decel curves that let them settle smoothly. `power3` is enough in most cases.** No bouncy, no overshoot, no `back.out` / `bounce.out` / `elastic.out` as a default.
|
||||||
|
|
||||||
Bouncy is the **#1 instant turn-off** in user-made Remotion / HyperFrames videos, and the agent almost never gets it right — it thinks bouncy adds emphasis, but it buys that emphasis at the cost of cleanliness. The serious launch-video shops feel the same. **Smooth always wins.** Overshoot is demoted to a **rare, explicitly-playful exception** (a consumer/fun logo slam, a deliberate bell-hit) — never the house style. Name the intent as a long-tail settle; the worker maps `power3` (or `expo.out` on a fast arrival). See `../hyperframes-animation/rules/spring-pop-entrance.md` — it now leads with the smooth settle.
|
Bouncy is the **#1 instant turn-off** in user-made Remotion / HyperFrames videos, and the agent almost never gets it right — it thinks bouncy adds emphasis, but it buys that emphasis at the cost of cleanliness. The serious launch-video shops feel the same. **Smooth always wins.** Overshoot is demoted to a **rare, explicitly-playful exception** (a consumer/fun logo slam, a deliberate bell-hit) — never the house style. Name the intent as a long-tail settle; the worker maps `power3` (or `expo.out` on a fast arrival). See `../hyperframes-animation/rules/spring-pop-entrance.md` — it now leads with the smooth settle. (The exact form of that settle is a critically-damped spring; the worker has a baked, seek-safe `springEase` — ζ=1 — in `../hyperframes-animation/adapters/gsap-easing-and-stagger.md` → Spring Eases for when the settle is the hero. Real physics, same doctrine — not a license for bounce.)
|
||||||
|
|
||||||
## 2. Sequential reveal in the back ~50%, timed to the voiceover
|
## 2. Sequential reveal in the back ~50%, timed to the voiceover
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user