mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
style: format
This commit is contained in:
@@ -177,25 +177,27 @@ Rules below came out of two independent website-to-hyperframes builds (2026-04-2
|
||||
|
||||
```html
|
||||
<!-- BAD: two transforms on one element -->
|
||||
<img class="hero" src="...">
|
||||
<img class="hero" src="..." />
|
||||
<script>
|
||||
tl.from(".hero", {y: 50, opacity: 0, duration: 0.6}, 0);
|
||||
tl.to(".hero", {scale: 1.04, duration: beat}, 0); // kills the entrance
|
||||
tl.from(".hero", { y: 50, opacity: 0, duration: 0.6 }, 0);
|
||||
tl.to(".hero", { scale: 1.04, duration: beat }, 0); // kills the entrance
|
||||
</script>
|
||||
|
||||
<!-- GOOD option A: combine into one tween -->
|
||||
<script>
|
||||
tl.fromTo(".hero",
|
||||
{y: 50, opacity: 0, scale: 1.00},
|
||||
{y: 0, opacity: 1, scale: 1.04, duration: beat, ease: "none"},
|
||||
0);
|
||||
tl.fromTo(
|
||||
".hero",
|
||||
{ y: 50, opacity: 0, scale: 1.0 },
|
||||
{ y: 0, opacity: 1, scale: 1.04, duration: beat, ease: "none" },
|
||||
0,
|
||||
);
|
||||
</script>
|
||||
|
||||
<!-- GOOD option B: split across parent + child -->
|
||||
<div class="hero-wrap"><img class="hero" src="..."></div>
|
||||
<div class="hero-wrap"><img class="hero" src="..." /></div>
|
||||
<script>
|
||||
tl.from(".hero-wrap", {y: 50, opacity: 0, duration: 0.6}, 0); // entrance on parent
|
||||
tl.to (".hero", {scale: 1.04, duration: beat}, 0); // Ken Burns on child
|
||||
tl.from(".hero-wrap", { y: 50, opacity: 0, duration: 0.6 }, 0); // entrance on parent
|
||||
tl.to(".hero", { scale: 1.04, duration: beat }, 0); // Ken Burns on child
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -203,25 +205,25 @@ Rules below came out of two independent website-to-hyperframes builds (2026-04-2
|
||||
|
||||
```js
|
||||
// BRITTLE: immediateRender interacts badly with scene boundaries
|
||||
tl.from(el, {opacity: 0, y: 50, duration: 0.6}, t);
|
||||
tl.from(el, { opacity: 0, y: 50, duration: 0.6 }, t);
|
||||
|
||||
// DETERMINISTIC: state is defined at both ends, no immediateRender surprise
|
||||
tl.fromTo(el, {opacity: 0, y: 50}, {opacity: 1, y: 0, duration: 0.6}, t);
|
||||
tl.fromTo(el, { opacity: 0, y: 50 }, { opacity: 1, y: 0, duration: 0.6 }, t);
|
||||
```
|
||||
|
||||
- **Ambient pulses must attach to the seekable `tl`, never bare `gsap.to()`.** Auras, shimmers, gentle float loops, logo breathing — all of these must be added to the scene's timeline, not fired standalone. Standalone tweens run on wallclock time and do not scrub with the capture engine, so the effect is absent in the rendered video even though it looks correct in the studio preview:
|
||||
|
||||
```js
|
||||
// BAD: lives outside the timeline, never renders in capture
|
||||
gsap.to(".aura", {scale: 1.08, yoyo: true, repeat: 5, duration: 1.2});
|
||||
gsap.to(".aura", { scale: 1.08, yoyo: true, repeat: 5, duration: 1.2 });
|
||||
|
||||
// GOOD: seekable, deterministic, renders
|
||||
tl.to(".aura", {scale: 1.08, yoyo: true, repeat: 5, duration: 1.2}, 0);
|
||||
tl.to(".aura", { scale: 1.08, yoyo: true, repeat: 5, duration: 1.2 }, 0);
|
||||
```
|
||||
|
||||
- **Hard-kill every scene boundary, not just captions.** The caption hard-kill rule above generalizes: any element whose visibility changes at a beat boundary needs a deterministic `tl.set()` kill after its fade, because later tweens on the same element (or `immediateRender` from a sibling tween) can resurrect it. Apply to every element with an exit animation:
|
||||
|
||||
```js
|
||||
tl.to (el, {opacity: 0, duration: 0.3}, beatEnd);
|
||||
tl.set(el, {opacity: 0, visibility: "hidden"}, beatEnd + 0.3); // deterministic kill
|
||||
tl.to(el, { opacity: 0, duration: 0.3 }, beatEnd);
|
||||
tl.set(el, { opacity: 0, visibility: "hidden" }, beatEnd + 0.3); // deterministic kill
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user