mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
docs: say one paused ROOT timeline, not "timelines must be paused"
`skills/hyperframes-core/SKILL.md` has always been right: "Each composition
registers exactly one gsap.timeline({ paused: true })... Don't manually nest
sub-timelines into the host."
The four compressed copies dropped both halves and said only "GSAP timelines
must be paused and registered on window.__timelines". Plural, with no cap and
no warning against nesting. An author following that writes a paused timeline
per scene and combines them, which is precisely the shape that renders black:
a paused child never advances when the root is seeked, so every frame is the
t=0 state, and lint, check and validate all pass because none looks at pixels.
This is the drift the skill-catalog rule exists to prevent — a compressed copy
asserting something the skill does not.
The runtime now repairs this shape (#3427), so nobody is stuck. This closes the
door on authoring it in the first place.
Both template files kept byte-identical, as required.
This commit is contained in:
@@ -80,7 +80,7 @@ skills/ → AI agent skill definitions
|
||||
- **Package manager**: bun (not pnpm, not npm for workspace operations)
|
||||
- **Commit format**: Conventional commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`)
|
||||
- **TypeScript**: Avoid `any` and `as T` assertions. Prefer type guards and narrowing.
|
||||
- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. GSAP timelines must be paused and registered on `window.__timelines`.
|
||||
- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. Each composition registers **exactly one** paused GSAP timeline on `window.__timelines`. Don't nest your own paused sub-timelines into it: a paused child never advances when the root is seeked, so the render comes out blank.
|
||||
- **Frame Adapters**: Animation runtimes plug in via the seek-by-frame adapter pattern. GSAP is the primary adapter.
|
||||
- **Deterministic rendering**: No `Date.now()`, no unseeded `Math.random()`, no render-time network fetches.
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ skills/ → AI agent skill definitions
|
||||
- **Package manager**: bun (not pnpm, not npm for workspace operations)
|
||||
- **Commit format**: Conventional commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`)
|
||||
- **TypeScript**: Avoid `any` and `as T` assertions. Prefer type guards and narrowing.
|
||||
- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. GSAP timelines must be paused and registered on `window.__timelines`.
|
||||
- **Compositions**: HTML files with `data-*` attributes. Clips need `class="clip"`. Each composition registers **exactly one** paused GSAP timeline on `window.__timelines`. Don't nest your own paused sub-timelines into it: a paused child never advances when the root is seeked, so the render comes out blank.
|
||||
- **Frame Adapters**: Animation runtimes plug in via the seek-by-frame adapter pattern. GSAP is the primary adapter.
|
||||
- **Deterministic rendering**: No `Date.now()`, no unseeded `Math.random()`, no render-time network fetches.
|
||||
|
||||
|
||||
@@ -90,11 +90,15 @@ Fix all errors before presenting the result. Warnings should be reviewed before
|
||||
|
||||
1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
|
||||
2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
|
||||
3. Timelines must be paused and registered on `window.__timelines`:
|
||||
3. Register **exactly one** paused timeline per composition on `window.__timelines`:
|
||||
```js
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines["composition-id"] = gsap.timeline({ paused: true });
|
||||
```
|
||||
Only that registered timeline is paused. Don't build scene timelines as
|
||||
`gsap.timeline({ paused: true })` and `.add()` them into it — a paused child
|
||||
never advances when the root is seeked, so every frame renders the t=0 state
|
||||
and the video comes out blank with no warning from lint, check or validate.
|
||||
4. Videos use `muted` with a separate `<audio>` element for the audio track
|
||||
5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
|
||||
6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
|
||||
|
||||
@@ -90,11 +90,15 @@ Fix all errors before presenting the result. Warnings should be reviewed before
|
||||
|
||||
1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
|
||||
2. Elements with timing **MUST** have `class="clip"` — the framework uses this for visibility control
|
||||
3. Timelines must be paused and registered on `window.__timelines`:
|
||||
3. Register **exactly one** paused timeline per composition on `window.__timelines`:
|
||||
```js
|
||||
window.__timelines = window.__timelines || {};
|
||||
window.__timelines["composition-id"] = gsap.timeline({ paused: true });
|
||||
```
|
||||
Only that registered timeline is paused. Don't build scene timelines as
|
||||
`gsap.timeline({ paused: true })` and `.add()` them into it — a paused child
|
||||
never advances when the root is seeked, so every frame renders the t=0 state
|
||||
and the video comes out blank with no warning from lint, check or validate.
|
||||
4. Videos use `muted` with a separate `<audio>` element for the audio track
|
||||
5. Sub-compositions use `data-composition-src="compositions/file.html"` to reference other HTML files
|
||||
6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
|
||||
|
||||
Reference in New Issue
Block a user