Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 23 additions & 26 deletions DOCS_GUIDELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@ Title

### Always annotate code blocks

```mdx
```html index.html
<div data-composition-id="root" ...>
```​
```
`````mdx
````html index.html
<div data-composition-id="root" ...>```​</div>
````
`````

`````

The filename after the language tag tells readers where the code goes.

Expand Down Expand Up @@ -97,32 +99,27 @@ npx hyperframes dev

### Use CodeGroup for multi-platform commands

```mdx
````mdx
<CodeGroup>
```bash macOS
brew install ffmpeg
```​
```bash Ubuntu
sudo apt install ffmpeg
```​
```bash macOS brew install ffmpeg ```​ ```bash Ubuntu sudo apt install ffmpeg ```​
</CodeGroup>
```
`````

## Mintlify Components — When to Use

| Component | Use When |
|-----------|----------|
| `<Steps>` | Sequential setup or tutorial instructions |
| `<CodeGroup>` | Same action across platforms/languages |
| `<Tabs>` | Alternative approaches with equal weight |
| `<Card>` / `<Columns>` | Navigation to related pages, next steps |
| `<Accordion>` | FAQ or optional detail that would bloat the page |
| `<Note>` | Non-obvious behavior the reader should know |
| `<Warning>` | Something that will break if ignored |
| `<Tip>` | Helpful shortcut or best practice |
| `<Info>` | Context that aids understanding |
| `<Tree>` | File/directory structure |
| `<Frame>` | Screenshots or diagrams with captions |
| Component | Use When |
| ---------------------- | ------------------------------------------------ |
| `<Steps>` | Sequential setup or tutorial instructions |
| `<CodeGroup>` | Same action across platforms/languages |
| `<Tabs>` | Alternative approaches with equal weight |
| `<Card>` / `<Columns>` | Navigation to related pages, next steps |
| `<Accordion>` | FAQ or optional detail that would bloat the page |
| `<Note>` | Non-obvious behavior the reader should know |
| `<Warning>` | Something that will break if ignored |
| `<Tip>` | Helpful shortcut or best practice |
| `<Info>` | Context that aids understanding |
| `<Tree>` | File/directory structure |
| `<Frame>` | Screenshots or diagrams with captions |

### Callout budget: max 2-3 per page

Expand Down
17 changes: 17 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions docs/concepts/compositions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ A composition is an HTML document that defines a video timeline. Every clip -- v
Every composition needs a root element with `data-composition-id`:

```html index.html
<div id="root" data-composition-id="root"
data-start="0" data-width="1920" data-height="1080">
<div id="root" data-composition-id="root" data-start="0" data-width="1920" data-height="1080">
<!-- Elements go here -->
</div>
```
Expand Down Expand Up @@ -68,6 +67,7 @@ You can embed one composition inside another in two ways: loading from an extern
</div>
</template>
```

</Tab>
<Tab title="Inline">
Define a nested composition directly inside the parent. This is simpler for one-off compositions that do not need to be reused.
Expand All @@ -93,6 +93,7 @@ You can embed one composition inside another in two ways: loading from an extern
```

Inline compositions do not use `<template>` tags or `data-composition-src`.

</Tab>
</Tabs>

Expand Down Expand Up @@ -122,15 +123,17 @@ Every composition has two layers:
- **Script** -- effects, transitions, dynamic DOM, canvas, SVG -- creative animation via [GSAP](/guides/gsap-animation). Scripts do **not** control media playback or clip visibility.

<Warning>
Never use scripts to play/pause/seek media elements or to show/hide clips based on timing. The framework handles this automatically from data attributes. Scripts that duplicate this behavior will conflict with the framework. See [Common Mistakes](/guides/common-mistakes) for examples.
Never use scripts to play/pause/seek media elements or to show/hide clips based on timing. The
framework handles this automatically from data attributes. Scripts that duplicate this behavior
will conflict with the framework. See [Common Mistakes](/guides/common-mistakes) for examples.
</Warning>

## Variables

Compositions can expose variables for dynamic content:

```html compositions/card.html
<div data-composition-id="card" data-var-title="string" data-var-color="color">
<div data-composition-id="card" data-var-title="string" data-var-color="color"></div>
```

Variables make compositions reusable as [templates](/guides/templates) -- the same composition can render different content by injecting variable values at render time.
Expand Down
71 changes: 40 additions & 31 deletions docs/concepts/data-attributes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,35 @@ Hyperframes uses HTML data attributes to control timing, media playback, and [co

## Timing Attributes

| Attribute | Example | Description |
|-----------|---------|-------------|
| `data-start` | `"0"` or `"intro"` | Start time in seconds, or a clip ID reference for [relative timing](#relative-timing) |
| `data-duration` | `"5"` | Duration in seconds. Required for images. Optional for video/audio (defaults to source duration). Not used on compositions. |
| `data-track-index` | `"0"` | Timeline track number. Controls z-ordering (higher = in front) and groups clips into rows. Clips on the same track cannot overlap. |
| Attribute | Example | Description |
| ------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `data-start` | `"0"` or `"intro"` | Start time in seconds, or a clip ID reference for [relative timing](#relative-timing) |
| `data-duration` | `"5"` | Duration in seconds. Required for images. Optional for video/audio (defaults to source duration). Not used on compositions. |
| `data-track-index` | `"0"` | Timeline track number. Controls z-ordering (higher = in front) and groups clips into rows. Clips on the same track cannot overlap. |

## Media Attributes

| Attribute | Example | Description |
|-----------|---------|-------------|
| `data-media-start` | `"2"` | Media playback offset / trim point in seconds. Default: `0` |
| `data-volume` | `"0.8"` | Audio/video volume, 0 to 1 |
| `data-has-audio` | `"true"` | Indicates video has an audio track |
| Attribute | Example | Description |
| ------------------ | -------- | ----------------------------------------------------------- |
| `data-media-start` | `"2"` | Media playback offset / trim point in seconds. Default: `0` |
| `data-volume` | `"0.8"` | Audio/video volume, 0 to 1 |
| `data-has-audio` | `"true"` | Indicates video has an audio track |

## Composition Attributes

| Attribute | Example | Description |
|-----------|---------|-------------|
| `data-composition-id` | `"root"` | Unique ID for [composition](/concepts/compositions) wrapper (required on every composition) |
| `data-width` | `"1920"` | Composition width in pixels |
| `data-height` | `"1080"` | Composition height in pixels |
| `data-composition-src` | `"./intro.html"` | Path to external [composition](/concepts/compositions) HTML file |
| Attribute | Example | Description |
| ---------------------- | ---------------- | ------------------------------------------------------------------------------------------- |
| `data-composition-id` | `"root"` | Unique ID for [composition](/concepts/compositions) wrapper (required on every composition) |
| `data-width` | `"1920"` | Composition width in pixels |
| `data-height` | `"1080"` | Composition height in pixels |
| `data-composition-src` | `"./intro.html"` | Path to external [composition](/concepts/compositions) HTML file |

## Element Visibility

Add `class="clip"` to all timed elements so the runtime can manage their visibility lifecycle:

```html index.html
<h1 id="title" class="clip"
data-start="0" data-duration="5" data-track-index="0">
Hello World
</h1>
<h1 id="title" class="clip" data-start="0" data-duration="5" data-track-index="0">Hello World</h1>
```

## Relative Timing
Expand All @@ -59,12 +56,22 @@ Add `+ N` or `- N` after the ID to offset from the end of the referenced clip:

```html index.html
<!-- 2-second gap after intro -->
<video id="scene-a" data-start="intro + 2" data-duration="20"
data-track-index="0" src="..."></video>
<video
id="scene-a"
data-start="intro + 2"
data-duration="20"
data-track-index="0"
src="..."
></video>

<!-- 0.5-second overlap with intro (crossfade) -->
<video id="scene-b" data-start="intro - 0.5" data-duration="20"
data-track-index="1" src="..."></video>
<video
id="scene-b"
data-start="intro - 0.5"
data-duration="20"
data-track-index="1"
src="..."
></video>
```

<Note>
Expand All @@ -74,16 +81,18 @@ Add `+ N` or `- N` after the ID to offset from the end of the referenced clip:
<Accordion title="Relative timing rules and constraints">
**Same composition only** -- references resolve within the clip's parent [composition](/concepts/compositions). You cannot reference a clip in a sibling or parent composition.

**No circular references** -- A cannot start after B if B starts after A. The resolver detects cycles and throws an error.
**No circular references** -- A cannot start after B if B starts after A. The resolver detects cycles and throws an error.

**Referenced clip must have a known duration** -- either an explicit `data-duration` or a duration inferred from source media. If the referenced clip has no known duration, the reference cannot resolve.
**Referenced clip must have a known duration** -- either an explicit `data-duration` or a duration inferred from source media. If the referenced clip has no known duration, the reference cannot resolve.

**Parsing rules** -- if the value is a valid number, it is treated as absolute seconds. Otherwise it is parsed as one of:
- `<id>` -- start when that clip ends
- `<id> + <number>` -- start N seconds after that clip ends
- `<id> - <number>` -- start N seconds before that clip ends
**Parsing rules** -- if the value is a valid number, it is treated as absolute seconds. Otherwise it is parsed as one of:

- `<id>` -- start when that clip ends
- `<id> + <number>` -- start N seconds after that clip ends
- `<id> - <number>` -- start N seconds before that clip ends

**Chain length** -- references can chain (`A` -> `B` -> `C`), but deeply nested chains make the timeline harder to reason about. Keep chains under 3-4 levels for readability.

**Chain length** -- references can chain (`A` -> `B` -> `C`), but deeply nested chains make the timeline harder to reason about. Keep chains under 3-4 levels for readability.
</Accordion>

## Next Steps
Expand Down
4 changes: 3 additions & 1 deletion docs/concepts/determinism.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ npx hyperframes render --docker -o output.mp4
```

Docker mode uses an exact Chrome version and font set, ensuring:

- Same Chromium rendering engine across all platforms
- Same system fonts (no platform-specific font substitution)
- Same FFmpeg encoder version
Expand All @@ -71,7 +72,8 @@ The browser preview and the rendered MP4 should match. Hyperframes achieves this
- **Readiness gates** -- `__playerReady` and `__renderReady` ensure the [composition](/concepts/compositions) is fully loaded before any frame is captured

<Note>
Local rendering (without Docker) may show slight differences due to platform-specific font rendering and Chrome version. Use Docker mode when exact reproducibility matters.
Local rendering (without Docker) may show slight differences due to platform-specific font
rendering and Chrome version. Use Docker mode when exact reproducibility matters.
</Note>

## For Adapter Authors
Expand Down
17 changes: 9 additions & 8 deletions docs/concepts/frame-adapters.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ The Frame Adapter pattern is how Hyperframes supports multiple animation runtime
If a runtime can answer that, it can plug into Hyperframes.

<Info>
The Adapter API is currently at **v0** (experimental). Breaking changes are possible until v1. The core contract (seek-by-frame, deterministic output) is stable, but method signatures may evolve.
The Adapter API is currently at **v0** (experimental). Breaking changes are possible until v1. The
core contract (seek-by-frame, deterministic output) is stable, but method signatures may evolve.
</Info>

## How It Works
Expand Down Expand Up @@ -106,13 +107,13 @@ These rules are non-negotiable for any adapter. They are the foundation of Hyper

First-party adapters:

| Runtime | Seek Method | Status |
|---------|------------|--------|
| [GSAP](/guides/gsap-animation) | `timeline.seek(frame / fps)` | Available |
| CSS/WAAPI | `animation.currentTime` | Planned |
| Lottie | Set animation frame/progress | Planned |
| Three.js/WebGL | Compute deterministic scene state | Planned |
| SVG/Anime | Implement seek + duration contract | Planned |
| Runtime | Seek Method | Status |
| ------------------------------ | ---------------------------------- | --------- |
| [GSAP](/guides/gsap-animation) | `timeline.seek(frame / fps)` | Available |
| CSS/WAAPI | `animation.currentTime` | Planned |
| Lottie | Set animation frame/progress | Planned |
| Three.js/WebGL | Compute deterministic scene state | Planned |
| SVG/Anime | Implement seek + duration contract | Planned |

Community adapters are welcome -- if it can seek by frame, it belongs in Hyperframes.

Expand Down
Loading
Loading