mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
docs: add documentation quality gates
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# HyperFrames documentation rules
|
||||
|
||||
Before changing a page, read its complete body and verify product behavior in
|
||||
the current source, tests, CLI help, or shipped skills.
|
||||
|
||||
- Write for a smart general user first. Do not assume they are a developer.
|
||||
- Explain what a person can accomplish before explaining implementation details.
|
||||
- Prefer plain words, short examples, screenshots, and visible outcomes.
|
||||
- Keep agent instructions copyable and specific.
|
||||
- Put CLI, SDK, package, schema, deployment, and internals under **Developers**.
|
||||
- Never infer product behavior from page titles or old docs. Verify it in current code.
|
||||
- Do not preserve a page merely because it already exists. Merge, rewrite, redirect, or remove it when that improves the user journey.
|
||||
- Do not publish empty, duplicated, outdated, or aspirational content as fact.
|
||||
- A page should answer a real question or help complete a real task.
|
||||
- Preserve the approved Mintlify header, sidebar, right-side contents, and page-width behavior unless a task explicitly changes the site chrome.
|
||||
|
||||
## Page standard
|
||||
|
||||
Most human-facing pages should contain:
|
||||
|
||||
1. What this lets you do
|
||||
2. When to use it
|
||||
3. A visual or concrete example
|
||||
4. The shortest successful path
|
||||
5. What should happen
|
||||
6. Common problems
|
||||
7. Useful next steps
|
||||
|
||||
Do not force this structure where it makes a page worse. Reference pages may stay reference-shaped.
|
||||
|
||||
## Component doctrine
|
||||
|
||||
One component per job. If two components on a page render the same list, delete one.
|
||||
|
||||
| The job | Use | Never use |
|
||||
| --- | --- | --- |
|
||||
| Choose between destinations | `CardGroup` + `Card`, max 2 columns, linking to the real page | An accordion, or cards pointing at anchors on the same page |
|
||||
| Ordered instructions | `Steps` | A flow diagram that repeats the same steps |
|
||||
| Parallel variants of one instruction (source type, OS, language) | `Tabs` | Repeating the whole block per variant |
|
||||
| Compare attributes across items | A table | Prose paragraphs per item |
|
||||
| Static image | `Frame` with a caption that says what it is | A bare `img` with no context |
|
||||
| Genuinely out-of-band aside | One `Note`, `Tip`, or `Warning` per page | Stacked callouts, or a callout for ordinary prose |
|
||||
|
||||
**Do not use accordions for journeys, choices, instructions, or troubleshooting.** They hide the thing the reader needs, cost a click, and weaken `Cmd+F`, printing, and deep linking. A dense optional reference or example gallery may keep accordions when showing every item at once would make the page unusable; the Prompt Guide's verified-example gallery is the existing exception. Long symptom or task lists become visible `##` sections instead — they get anchors the support team can link directly, and they appear in the page contents.
|
||||
|
||||
**No diagram that restates adjacent prose.** A four-node flow beside a four-step list is the same content twice. Keep whichever is more useful and delete the other.
|
||||
|
||||
**Cards link to pages, never to anchors on the current page.** A card that scrolls the reader a short distance to the same words is the worst pattern in these docs; it has been removed twice.
|
||||
|
||||
**Two columns is the practical maximum** for anything containing text. Three columns in this content width hyphenates titles mid-word.
|
||||
|
||||
**Full films and preview loops are different jobs.** Use `DocsVideo` for a
|
||||
narrated film a reader watches intentionally. A plain `<video>` is only for a
|
||||
small, muted, autoplaying preview loop inside a visual explanation or Catalog
|
||||
item. Do not mix native browser controls with the custom player.
|
||||
|
||||
**Related topics must be visible content.** Mintlify does not render a
|
||||
`related:` frontmatter list. Add a final `## Related topics` section with only
|
||||
the two or three destinations that genuinely help the reader continue.
|
||||
|
||||
### Custom React components
|
||||
|
||||
Mintlify compiles `.jsx` / `.tsx` from `docs/snippets/`. Use one when a native component genuinely cannot express the idea — a scrubber, a comparison slider, a live player — not for styling.
|
||||
|
||||
- Named exports only: `export const Thing = () => ...`. Default exports do not work.
|
||||
- `useState`, `useEffect`, `useRef`, `useCallback`, `useMemo`, `useContext`, `useReducer` are pre-injected; do not import React.
|
||||
- **Do not add a dependency or CDN script for presentation alone.** Prefer browser built-ins (`fetch`, `IntersectionObserver`, Canvas, `<video>`). A version-pinned official runtime is acceptable when that runtime is the subject of the demo and the component provides a useful loading or failure state; the live composition on Introduction is the model.
|
||||
- A snippet cannot import another snippet. Keep each self-contained.
|
||||
- **Declare everything inside the component.** Only the exported component survives
|
||||
compilation; module-level `const`s above it are dropped, so a constant defined
|
||||
outside arrives `undefined` at render. The component then throws inside React,
|
||||
the error boundary swallows it, and the page renders nothing at that position —
|
||||
with no console error to point at it. If a snippet renders blank, check this first.
|
||||
- Client-side only: guard anything touching `window` and give every component a sensible first paint.
|
||||
- Respect `prefers-reduced-motion`, give interactive elements a visible focus state, and never make a component the only route to information.
|
||||
|
||||
## Verification
|
||||
|
||||
After navigation or MDX changes:
|
||||
|
||||
```bash
|
||||
PATH=/opt/homebrew/opt/node@20/bin:$PATH mint validate
|
||||
PATH=/opt/homebrew/opt/node@20/bin:$PATH mint broken-links
|
||||
```
|
||||
|
||||
Use Bun for repository work. Do not create a `pnpm-lock.yaml`.
|
||||
|
||||
## Freshness and ownership
|
||||
|
||||
- A product behavior page is owned by the team that owns the matching product surface.
|
||||
- A package or API reference is owned by the package maintainer.
|
||||
- Workflow pages are owned by the maintainer of the matching agent skill.
|
||||
- When a feature changes, update its task guide, related troubleshooting entry, and screenshot in the same pull request.
|
||||
- Treat screenshots as product claims. Replace them when labels, layout, or the demonstrated workflow changes materially.
|
||||
- Review **Start here**, **Studio**, **Export**, and **Troubleshooting** at least once per release cycle.
|
||||
- Review lower-traffic reference pages at least quarterly.
|
||||
- Remove an unowned update feed instead of letting it become stale.
|
||||
- Use search analytics and support questions to decide which missing task pages to add next.
|
||||
+52
-141
@@ -1,168 +1,79 @@
|
||||
---
|
||||
title: Contributing
|
||||
description: "How to contribute to Hyperframes."
|
||||
title: Contribute to HyperFrames
|
||||
description: Set up the repository, make a focused change, and open a pull request.
|
||||
---
|
||||
|
||||
Thanks for your interest in contributing to Hyperframes! This guide covers everything you need to get set up, run tests, and submit a pull request.
|
||||
|
||||
## Getting Started
|
||||
|
||||
<Steps>
|
||||
<Step title="Fork and clone">
|
||||
Fork the repository on GitHub, then clone your fork:
|
||||
```bash
|
||||
git clone https://github.com/YOUR_USERNAME/hyperframes.git
|
||||
cd hyperframes
|
||||
```
|
||||
</Step>
|
||||
<Step title="Install dependencies">
|
||||
Hyperframes uses [bun](https://bun.sh/) for package management:
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
</Step>
|
||||
<Step title="Build all packages">
|
||||
Build the monorepo to ensure everything compiles:
|
||||
```bash
|
||||
bun run build
|
||||
```
|
||||
</Step>
|
||||
<Step title="Run the studio">
|
||||
Start the development server to verify your setup:
|
||||
```bash
|
||||
bun run dev
|
||||
```
|
||||
If the studio opens at `http://localhost:5190` with a preview, your environment is ready.
|
||||
</Step>
|
||||
<Step title="Create a branch">
|
||||
Create a feature branch for your work:
|
||||
```bash
|
||||
git checkout -b my-feature
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Development
|
||||
|
||||
### Common Commands
|
||||
## Set up the repository
|
||||
|
||||
```bash
|
||||
bun install # Install all dependencies
|
||||
bun run dev # Start the studio (composition editor + live preview)
|
||||
bun run build # Build all packages
|
||||
bun run --filter '*' typecheck # Type-check all packages
|
||||
git clone https://github.com/YOUR_USERNAME/hyperframes.git
|
||||
cd hyperframes
|
||||
bun install
|
||||
bun run build
|
||||
```
|
||||
|
||||
### Studio Editing Work
|
||||
HyperFrames uses Bun for workspace operations. Do not add a `pnpm-lock.yaml` or replace `bun.lock`.
|
||||
|
||||
If you are changing Studio's visual editing surface, read
|
||||
[Studio Manual DOM Editing](/contributing/studio-manual-dom-editing) before
|
||||
editing code. The inspector intentionally exposes only interactions it can
|
||||
persist safely back to HTML, so changes should preserve the capability gates,
|
||||
source patching model, and documented limitations.
|
||||
|
||||
### Running Tests
|
||||
|
||||
<CodeGroup>
|
||||
```bash Core
|
||||
bun run --filter @hyperframes/core test
|
||||
```
|
||||
```bash Engine
|
||||
bun run --filter @hyperframes/engine test
|
||||
```
|
||||
```bash Runtime Contract
|
||||
bun run --filter @hyperframes/core test:hyperframe-runtime-ci
|
||||
```
|
||||
```bash Producer (Docker)
|
||||
cd packages/producer && bun run docker:build:test && bun run docker:test
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Running All Tests
|
||||
Start Studio while working on UI or composition behavior:
|
||||
|
||||
```bash
|
||||
bun run --filter '*' test
|
||||
bun run dev
|
||||
```
|
||||
|
||||
## Packages
|
||||
Studio listens on `http://localhost:5190` when run from the monorepo.
|
||||
|
||||
| Package | Path | Description |
|
||||
|---------|------|-------------|
|
||||
| [`@hyperframes/core`](/packages/core) | `packages/core` | Types, HTML generation, runtime, linter |
|
||||
| [`@hyperframes/sdk`](/packages/sdk) | `packages/sdk` | Headless composition editing engine |
|
||||
| [`@hyperframes/engine`](/packages/engine) | `packages/engine` | Seekable page-to-video capture engine |
|
||||
| [`@hyperframes/player`](/packages/player) | `packages/player` | Embeddable composition player |
|
||||
| [`@hyperframes/producer`](/packages/producer) | `packages/producer` | Full rendering pipeline (capture + encode) |
|
||||
| [`@hyperframes/shader-transitions`](/packages/shader-transitions) | `packages/shader-transitions` | WebGL shader transition engine |
|
||||
| [`@hyperframes/aws-lambda`](/packages/aws-lambda) | `packages/aws-lambda` | AWS Lambda distributed rendering adapter |
|
||||
| [`@hyperframes/gcp-cloud-run`](/packages/gcp-cloud-run) | `packages/gcp-cloud-run` | GCP Cloud Run distributed rendering adapter |
|
||||
| [`@hyperframes/studio`](/packages/studio) | `packages/studio` | Composition editor UI |
|
||||
| [`hyperframes`](/packages/cli) | `packages/cli` | CLI for creating, previewing, and rendering |
|
||||
| `@hyperframes/sdk-playground` (private) | `packages/sdk-playground` | Local SDK playground app |
|
||||
## Check your change
|
||||
|
||||
## What to Work On
|
||||
Run the smallest relevant test while iterating, then the repository gates before opening a pull request:
|
||||
|
||||
Not sure where to start? Here are some ideas:
|
||||
|
||||
- **Good first issues** — look for issues labeled `good first issue` on GitHub
|
||||
- **Documentation** — improve docs, add examples, fix typos
|
||||
- **Linter rules** — add new rules to catch more composition mistakes
|
||||
- **Examples** — create new starter examples
|
||||
- **Bug fixes** — check the issue tracker for reported bugs
|
||||
|
||||
## Pull Requests
|
||||
|
||||
### Commit Format
|
||||
|
||||
Use [conventional commit](https://www.conventionalcommits.org/) format for all commits and PR titles:
|
||||
|
||||
```
|
||||
feat: add timeline export
|
||||
fix: resolve seek overflow at composition boundary
|
||||
docs: add GSAP easing examples
|
||||
refactor: extract frame buffer pool into shared module
|
||||
test: add regression test for nested composition timing
|
||||
```bash
|
||||
bun run lint
|
||||
bun run format:check
|
||||
bun run --filter '*' typecheck
|
||||
bun run test
|
||||
```
|
||||
|
||||
### CI Requirements
|
||||
For a composition or registry item, also run:
|
||||
|
||||
All of the following must pass before your PR can be merged:
|
||||
```bash
|
||||
npx hyperframes lint
|
||||
npx hyperframes check
|
||||
```
|
||||
|
||||
- **Build** — `bun run build` succeeds
|
||||
- **Type check** — `bun run --filter '*' typecheck` reports no errors
|
||||
- **Tests** — all test suites pass
|
||||
- **Semantic PR title** — PR title follows conventional commit format
|
||||
The pre-commit hooks format staged files and run checks for the files you changed.
|
||||
|
||||
### Review Process
|
||||
## Work in the right package
|
||||
|
||||
- PRs require at least 1 approval from a maintainer
|
||||
- Keep PRs focused — one feature or fix per PR
|
||||
- Target alpha-only PRs at `next` instead of `main`; see
|
||||
[Release channels](/contributing/release-channels) for branch policy details
|
||||
- Include a clear description of what changed and why
|
||||
- Add tests for new features and bug fixes
|
||||
| Surface | Package or directory |
|
||||
| --- | --- |
|
||||
| Composition parsing, runtime, types | `packages/core` and `packages/parsers` |
|
||||
| Browser frame capture | `packages/engine` |
|
||||
| Encoding and audio/render orchestration | `packages/producer` |
|
||||
| Command line | `packages/cli` |
|
||||
| Browser editor | `packages/studio` and `packages/studio-server` |
|
||||
| Embeddable player | `packages/player` |
|
||||
| Headless editing API | `packages/sdk` |
|
||||
| AWS and GCP distributed rendering | `packages/aws-lambda` and `packages/gcp-cloud-run` |
|
||||
| Reusable blocks and snippets | `registry` |
|
||||
| Agent instructions | `skills` |
|
||||
|
||||
## Reporting Issues
|
||||
For Studio changes, verify the behavior in the browser and preserve the source-patching and capability-gate contracts described in the [Studio docs](/studio/index).
|
||||
|
||||
- Use [GitHub Issues](https://github.com/heygen-com/hyperframes/issues) for bug reports and feature requests
|
||||
- Search existing issues before creating a new one
|
||||
- For bug reports, include:
|
||||
- Steps to reproduce
|
||||
- Expected behavior vs. actual behavior
|
||||
- Hyperframes version (`npx hyperframes info`)
|
||||
- Operating system and Node.js version
|
||||
## Pull request requirements
|
||||
|
||||
## Community
|
||||
- Keep the change focused and explain the user-visible reason for it.
|
||||
- Add or update tests when behavior changes.
|
||||
- Use a conventional PR title such as `fix: preserve audio after seeking`.
|
||||
- Run formatting, lint, typecheck, and relevant tests.
|
||||
- Include screenshots or a short capture for visual changes.
|
||||
- Target prerelease-only work to the branch described in [Release channels](/contributing/release-channels).
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="GitHub Issues" icon="github" href="https://github.com/heygen-com/hyperframes/issues">
|
||||
Report bugs, request features, and discuss ideas.
|
||||
</Card>
|
||||
<Card title="Code of Conduct" icon="handshake" href="https://github.com/heygen-com/hyperframes/blob/main/CODE_OF_CONDUCT.md">
|
||||
Our community standards and expectations.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
Use [GitHub Issues](https://github.com/heygen-com/hyperframes/issues) for bugs and proposals. A useful bug report includes the smallest reproduction, the first exact error, `npx hyperframes info`, and the operating system.
|
||||
|
||||
## License
|
||||
By contributing, you agree that your work is licensed under the [Apache 2.0 License](https://github.com/heygen-com/hyperframes/blob/main/LICENSE) and follows the [Code of Conduct](https://github.com/heygen-com/hyperframes/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
By contributing, you agree that your contributions will be licensed under the [Apache 2.0 License](https://github.com/heygen-com/hyperframes/blob/main/LICENSE).
|
||||
## Related topics
|
||||
|
||||
- [Test local CLI changes](/contributing/testing-local-changes)
|
||||
- [Contribute a Catalog item](/contributing/catalog)
|
||||
- [Understand release channels](/contributing/release-channels)
|
||||
|
||||
+95
-207
@@ -1,76 +1,53 @@
|
||||
---
|
||||
title: Contributing to the Catalog
|
||||
description: How to add blocks and components to the HyperFrames registry.
|
||||
title: Contribute to the Catalog
|
||||
description: Add a reusable block or component to the HyperFrames registry.
|
||||
---
|
||||
|
||||
Your agent already knows how to build video components. It writes HTML. HyperFrames renders it. The registry is the collection of everything that's been built — 113 blocks and 25 components.
|
||||
The Catalog is generated from the registry in the HyperFrames repository. You
|
||||
can contribute a visual idea or build an item that anyone can install.
|
||||
|
||||
This guide shows you how to add to it.
|
||||
## Choose how to contribute
|
||||
|
||||
<Info>
|
||||
**Quick version** — Fork the repo. Write one HTML file with a paused GSAP timeline. Add `registry-item.json`. Run `hyperframes lint` + `hyperframes check`. Publish with `npx hyperframes publish`. Open a PR.
|
||||
</Info>
|
||||
### Suggest an idea
|
||||
|
||||
## Why Contribute?
|
||||
Open a [GitHub issue](https://github.com/heygen-com/hyperframes/issues) with a
|
||||
visual reference and explain where the effect would be useful. A screen
|
||||
recording, Figma sketch, or example from another tool is enough to start.
|
||||
|
||||
Every block in the registry exists because someone needed it and built it. When you add a block, every HyperFrames user gets it with one command:
|
||||
### Build an item
|
||||
|
||||
```bash
|
||||
npx hyperframes add instagram-follow
|
||||
```
|
||||
Ask your agent to use the `/hyperframes-registry` skill, or follow the same
|
||||
workflow below.
|
||||
|
||||
The registry grows, HyperFrames gets more useful, and your work ships to everyone.
|
||||
## Choose the item type
|
||||
|
||||
## Two Paths
|
||||
| Type | Use it for | Required files |
|
||||
| --- | --- | --- |
|
||||
| Block | A standalone composition with fixed dimensions and duration | `registry-item.json` and the composition HTML |
|
||||
| Component | A snippet installed into another composition | `registry-item.json`, the snippet HTML, and a standalone `demo.html` |
|
||||
|
||||
### Ideas (No Code)
|
||||
Each item has its own directory under `registry/blocks/` or
|
||||
`registry/components/`. Prefix every element ID with a short abbreviation of
|
||||
the item name so it cannot collide when installed as a sub-composition.
|
||||
|
||||
You spot visual trends before anyone. That's the most valuable contribution.
|
||||
|
||||
- Screen-record a caption style from TikTok/YouTube that doesn't exist yet
|
||||
- Sketch a lower-third in Figma with fonts, colors, and timing
|
||||
- Install a component, preview it, report what feels off
|
||||
|
||||
Open an issue on [GitHub](https://github.com/heygen-com/hyperframes/issues) with a visual reference. Tag it `component-request`.
|
||||
|
||||
<Tip>The bar for ideas is low. We'd rather have 100 and build the best 10.</Tip>
|
||||
|
||||
### Build It
|
||||
|
||||
Every block is a single HTML file. No build step, no framework.
|
||||
|
||||
If you use Claude Code with HyperFrames skills:
|
||||
|
||||
> "I want to contribute a new transition that looks like \[description\]"
|
||||
|
||||
The `/hyperframes-registry` skill scaffolds the structure, validates, renders a preview, publishes to [hyperframes.dev](https://hyperframes.dev), and prepares the PR.
|
||||
|
||||
## What Goes in the Registry
|
||||
|
||||
**Blocks** (`registry/blocks/`) — full standalone compositions. Fixed dimensions, fixed duration. Caption styles, VFX effects, title cards, transitions.
|
||||
|
||||
**Components** (`registry/components/`) — reusable snippets. No fixed size. CSS effects, text treatments, overlays that adapt to any composition.
|
||||
|
||||
### Structure
|
||||
|
||||
A block is two files. A component is three, because it also ships the demo the catalog renders it inside.
|
||||
|
||||
```
|
||||
```text
|
||||
registry/blocks/my-block/
|
||||
my-block.html ← the composition
|
||||
registry-item.json ← metadata
|
||||
my-block.html
|
||||
registry-item.json
|
||||
|
||||
registry/components/my-effect/
|
||||
my-effect.html ← the snippet
|
||||
demo.html ← the composition the catalog previews it in
|
||||
registry-item.json ← metadata
|
||||
my-effect.html
|
||||
demo.html
|
||||
registry-item.json
|
||||
```
|
||||
|
||||
<Warning>
|
||||
`demo.html` is required for components. Preview generation skips any component without one, which fails the catalog CI job for your item.
|
||||
</Warning>
|
||||
The Catalog preview generator skips a component without `demo.html`.
|
||||
|
||||
### registry-item.json
|
||||
## Define the manifest
|
||||
|
||||
`registry-item.json` follows the
|
||||
[registry item schema](https://github.com/heygen-com/hyperframes/blob/main/packages/core/schemas/registry-item.json).
|
||||
Blocks declare `dimensions` and `duration`; components must not.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -83,7 +60,12 @@ registry/components/my-effect/
|
||||
"dimensions": { "width": 1920, "height": 1080 },
|
||||
"duration": 5,
|
||||
"params": [
|
||||
{ "key": "--accent", "label": "Accent", "type": "color", "default": "#ff4d4d" }
|
||||
{
|
||||
"key": "--accent",
|
||||
"label": "Accent",
|
||||
"type": "color",
|
||||
"default": "#ff4d4d"
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
@@ -95,167 +77,73 @@ registry/components/my-effect/
|
||||
}
|
||||
```
|
||||
|
||||
#### Expose your block's knobs with `params`
|
||||
Use `params` for the values someone should be able to change in Studio without
|
||||
editing HTML. Supported controls are `color`, `text`, `number`, and `select`.
|
||||
|
||||
Declare `params` and Studio opens a live customization panel the moment someone adds your block. Each entry maps a label to a CSS variable your composition reads, so a user can restyle it without editing HTML.
|
||||
Other useful optional fields include `author`, `authorUrl`, `relatedSkill`,
|
||||
`registryDependencies`, `license`, `sourcePrompt`, `minCliVersion`, and
|
||||
`deprecated`. The TypeScript registry types and existing manifests are the
|
||||
current authority. The published JSON schema validates the shared manifest
|
||||
fields but does not yet describe the block-only `params` field.
|
||||
|
||||
```json
|
||||
"params": [
|
||||
{ "key": "--bg-color", "label": "Background", "type": "color", "default": "#faf9f6" },
|
||||
{ "key": "--headline", "label": "Headline", "type": "text", "default": "Ship it" },
|
||||
{ "key": "--speed", "label": "Speed", "type": "number", "default": "1", "min": 0.5, "max": 2, "step": 0.1 }
|
||||
]
|
||||
## Build for reuse
|
||||
|
||||
Every registry item must:
|
||||
|
||||
- use a paused GSAP timeline registered on `window.__timelines`;
|
||||
- match `data-composition-id` to the registered timeline ID;
|
||||
- use prefixed element IDs;
|
||||
- avoid `Date.now()`, unseeded `Math.random()`, and real-time animation loops;
|
||||
- seek correctly at any frame;
|
||||
- work after installation outside its source directory.
|
||||
|
||||
A one-off example belongs in [Examples](/examples), not the Catalog.
|
||||
|
||||
## Validate and preview
|
||||
|
||||
Run the composition gates:
|
||||
|
||||
```bash
|
||||
npx hyperframes lint
|
||||
npx hyperframes check
|
||||
```
|
||||
|
||||
Types are `color`, `text`, `number`, and `select` (which takes an `options` array).
|
||||
Generate the Catalog page and preview assets:
|
||||
|
||||
<Tip>
|
||||
If your block has any brand surface — a color, a headline, a logo slot — expose it as a param. A block nobody can restyle gets forked instead of reused.
|
||||
</Tip>
|
||||
```bash
|
||||
npx tsx scripts/generate-catalog-pages.ts
|
||||
npx tsx scripts/generate-catalog-previews.ts --only my-block
|
||||
```
|
||||
|
||||
#### Other optional fields
|
||||
These generators read the item directly from the working tree. The `add`
|
||||
command cannot install an unpublished local item by name: it resolves items
|
||||
from the registry URL in `hyperframes.json`. Test `npx hyperframes add my-block`
|
||||
from a clean project after the item is present in that registry manifest.
|
||||
|
||||
| Field | What it does |
|
||||
|-------|--------------|
|
||||
| `author` / `authorUrl` | Credits you on the catalog page |
|
||||
| `relatedSkill` | Links the catalog page to the skill that authors this kind of block |
|
||||
| `registryDependencies` | Other registry items installed alongside yours |
|
||||
| `license` | SPDX identifier, if yours differs from the repo's |
|
||||
| `sourcePrompt` | The prompt that produced the block, for people remixing it |
|
||||
| `minCliVersion` | Guards against installing into a CLI too old to run it |
|
||||
| `deprecated` | Marks the item superseded, with the migration note as the value |
|
||||
Do not hand-edit the generated item page. Fix its registry manifest or the
|
||||
generator and regenerate it.
|
||||
|
||||
## The Rules
|
||||
Watch the preview at full speed. Passing `check` proves the composition is
|
||||
valid; it does not prove that the motion is readable or useful.
|
||||
|
||||
Five things that must be true for every registry item:
|
||||
| Review question | What good looks like |
|
||||
| --- | --- |
|
||||
| Is there one visual hero? | The eye knows where to look in the first second |
|
||||
| Can the important text be read once? | Information lands, then holds before the cut |
|
||||
| Does motion accelerate and settle? | It does not drift at constant speed like a slide |
|
||||
| Can someone restyle it? | Brand-facing values are exposed as parameters |
|
||||
| Is it meaningfully reusable? | It solves a repeated production problem |
|
||||
|
||||
<Steps>
|
||||
<Step title="Deterministic">
|
||||
No `Math.random()`, no `Date.now()`. Use seeded PRNG only.
|
||||
</Step>
|
||||
<Step title="Paused timeline">
|
||||
`gsap.timeline({ paused: true })`. The player controls playback.
|
||||
</Step>
|
||||
<Step title="Register timeline">
|
||||
`window.__timelines["id"]` must match `data-composition-id`.
|
||||
</Step>
|
||||
<Step title="No requestAnimationFrame">
|
||||
Use `tl.eventCallback("onUpdate", render)` for Three.js/WebGL scenes.
|
||||
</Step>
|
||||
<Step title="Hard kills on captions">
|
||||
`tl.set(el, { opacity: 0, visibility: "hidden" }, group.end)` — no lingering text.
|
||||
</Step>
|
||||
</Steps>
|
||||
## Open the pull request
|
||||
|
||||
<Warning>
|
||||
Break any of these and renders won't be reproducible. The renderer captures every frame by seeking the timeline — if your animation depends on real time or random state, it breaks.
|
||||
</Warning>
|
||||
Include:
|
||||
|
||||
Prefix every element ID with a 2-3 letter abbreviation of your item's name (`hz-cg-0`, `vc-canvas`). Unprefixed IDs collide when your block is used as a sub-composition.
|
||||
- the item directory;
|
||||
- the matching entry in `registry/registry.json`;
|
||||
- regenerated Catalog output;
|
||||
- a `hyperframes.dev` preview from `npx hyperframes publish`;
|
||||
- when to use it, its useful duration range, and any known pitfalls.
|
||||
|
||||
## Quality Bar
|
||||
|
||||
Not everything belongs in the registry. The bar is production quality.
|
||||
|
||||
| Type | Minimum standard |
|
||||
|------|-----------------|
|
||||
| Captions | 96px+ font (64-72px for monospace), text-stroke or shadow, `window.__hyperframes.fitTextFontSize()` on every group |
|
||||
| VFX | Solves a problem that takes 4+ hours from scratch |
|
||||
| Transitions | Smoother than CSS — if opacity 0→1 works, it's not a transition |
|
||||
| Blocks | Would a professional use this in a client project? |
|
||||
|
||||
### Motion review
|
||||
|
||||
Passing `check` isn't the same as the motion being good. Watch your rendered preview once at full speed and answer these:
|
||||
|
||||
| Rule | Ask yourself |
|
||||
|------|-------------|
|
||||
| Key information holds still before the block ends | Does the headline or number sit motionless for at least a second after it lands, or is it still drifting at the cut? |
|
||||
| Speed comes from acceleration, not constant velocity | Is anything moving at a constant rate? Linear motion reads as a slide deck. |
|
||||
| Default one notch slower than feels right | Was there anything you couldn't read on the first watch? |
|
||||
| One hero per block | Count what's animating in the first second. More than one and the eye has nowhere to land. |
|
||||
| Light effects aren't sprayed | Count the glints and sweeps. More than one, or any that spills past a rounded corner, is a cut. |
|
||||
|
||||
### Common rejection reasons
|
||||
|
||||
1. **"Looks like a demo"** — a spinning cube is not a component
|
||||
2. **"Text unreadable"** — font too small, no contrast treatment
|
||||
3. **"Non-deterministic"** — `Math.random()` or `Date.now()`
|
||||
4. **"Timeline not found"** — ID mismatch between HTML and JS
|
||||
5. **"Breaks as sub-composition"** — element IDs collide (prefix everything)
|
||||
6. **"Nothing to tune"** — a branded block with no `params`
|
||||
|
||||
## Workflow
|
||||
|
||||
<Steps>
|
||||
<Step title="Fork and create">
|
||||
Fork [heygen-com/hyperframes](https://github.com/heygen-com/hyperframes) and create your block directory:
|
||||
```bash
|
||||
mkdir -p registry/blocks/your-block
|
||||
```
|
||||
</Step>
|
||||
<Step title="Write your block">
|
||||
Create the HTML composition and `registry-item.json`. Use the templates above. For a component, add `demo.html` too.
|
||||
</Step>
|
||||
<Step title="Validate">
|
||||
```bash
|
||||
hyperframes lint
|
||||
hyperframes check
|
||||
npx oxfmt registry/blocks/your-block/*.html
|
||||
```
|
||||
</Step>
|
||||
<Step title="Update registry">
|
||||
```bash
|
||||
# Add to registry index
|
||||
# Update registry/registry.json
|
||||
npx tsx scripts/generate-catalog-pages.ts
|
||||
```
|
||||
</Step>
|
||||
<Step title="Render preview">
|
||||
```bash
|
||||
hyperframes render -o preview.mp4
|
||||
```
|
||||
</Step>
|
||||
<Step title="Publish and PR">
|
||||
```bash
|
||||
npx hyperframes publish
|
||||
```
|
||||
Open a PR with your [hyperframes.dev](https://hyperframes.dev) preview link. Commit your item directory, `registry/registry.json`, and the generated `docs/catalog/` page.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
CI renders the catalog PNG and MP4 for every block or component your PR touches, so there's nothing to attach by hand. A maintainer publishes the final catalog image before merge.
|
||||
|
||||
### What to write in the PR body
|
||||
|
||||
The one-line `description` tells a reader what your block looks like. It doesn't tell them when to reach for it, which is what decides whether it gets used. Three lines in the PR body:
|
||||
|
||||
- **When to use it** — name the moment, e.g. "second beat of a product promo, right after the hero card lands"
|
||||
- **Duration range** — your block has a fixed `duration`; say what range still reads correctly
|
||||
- **Known pitfalls** — a font that must be loaded, a background it needs contrast against, a length past which it stops working
|
||||
|
||||
**HeyGen internal:** run `scripts/upload-docs-images.sh` to push catalog PNGs.
|
||||
|
||||
## What's Needed Right Now
|
||||
|
||||
The catalog is lopsided. It has 29 transitions and 33 code blocks, and almost nothing for the moments that carry a video's shape. These gaps are sorted by the job the shot does, not by the technique it uses.
|
||||
|
||||
| Job in the video | Blocks today | Gap |
|
||||
|------------------|--------------|-----|
|
||||
| Opening / hero reveal | 2 | The most-used moment in any promo has two options |
|
||||
| Outro / end card | 1 | Every video needs one |
|
||||
| Beat-driven cuts | 0 | Speed ramps, freeze frames, cut-on-the-beat — nothing, despite a whole music-to-video workflow |
|
||||
| Interaction demo | 0 | Command palette summon, type-and-filter, cursor performance, theme switch — nothing, despite HyperFrames capturing real product pages |
|
||||
| Data readout | 1 generic | Odometer digit roll, gauge sweep, before-and-after slider scrub |
|
||||
| Captions | 0 blocks | 15 caption components exist, but no ready-to-drop caption block |
|
||||
|
||||
Four specific holes that survived the last round:
|
||||
|
||||
| Category | Gap | Difficulty |
|
||||
|----------|-----|-----------|
|
||||
| Captions | RTL language layouts (Arabic, Hebrew) | Medium |
|
||||
| Data viz | Sankey / flow diagrams | Medium |
|
||||
| VFX | Particle system with physics (collisions, gravity) | Hard |
|
||||
| VFX | Product turntable with HDRI | Hard |
|
||||
|
||||
Pick one, and your first contribution fills a hole instead of being the 30th transition.
|
||||
External contributors should attach the preview MP4. A maintainer will publish
|
||||
the final Catalog media. HeyGen contributors can use
|
||||
`scripts/upload-docs-images.sh` after preview review.
|
||||
|
||||
@@ -77,7 +77,13 @@ Without `--force`, the draft command leaves an existing `releases/vX.Y.Z.md` fil
|
||||
|
||||
## Weekly digest workflow
|
||||
|
||||
Weekly updates are editorial rollups, not release notes. Keep `docs/changelog.mdx` versioned and use `docs/weekly-updates.mdx` for curated weekly highlights that can also be adapted for Discord and X.
|
||||
Weekly packets are editorial source material, not a public documentation page. Keep `docs/changelog.mdx` versioned. Only publish a human-readable product update when there is a real story, an owner, and enough context to help users act.
|
||||
|
||||
When `docs/product-updates.mdx` is public, the release owner reviews it during
|
||||
the first stable release of each month. Update it only when several changes form
|
||||
a useful user story; otherwise keep the latest dated edition and confirm that
|
||||
its claims still describe the current product. Remove the page from navigation
|
||||
if no one owns that review.
|
||||
|
||||
Generate an editable weekly packet from the repository root:
|
||||
|
||||
@@ -87,13 +93,13 @@ bun run changelog:weekly --from 2026-06-01 --to 2026-06-07 --write
|
||||
|
||||
Run it from an up-to-date `main` branch so the selected range reflects public history, not a feature branch.
|
||||
|
||||
This creates:
|
||||
This creates internal editorial drafts:
|
||||
|
||||
- `updates/weekly/2026-06-07.md`
|
||||
- `updates/social/2026-06-07.discord.md`
|
||||
- `updates/social/2026-06-07.x.md`
|
||||
|
||||
It also prepends a matching entry to `docs/weekly-updates.mdx`. Review and rewrite the generated files before publishing. Social drafts are never posted automatically.
|
||||
Review and rewrite the generated files before publishing anything. Social drafts are never posted automatically. Do not recreate or commit `docs/weekly-updates.mdx`; that empty public page was retired.
|
||||
|
||||
## Writing style
|
||||
|
||||
|
||||
@@ -1,315 +0,0 @@
|
||||
---
|
||||
title: Studio Manual DOM Editing
|
||||
description: What the Studio manual DOM editing inspector ships today, including capabilities, UX, and constraints.
|
||||
---
|
||||
|
||||
This page documents the current manual DOM editing surface in HyperFrames Studio. It reflects the implementation that ships in the Studio inspector today, not the earlier design draft that explored third-party transform engines.
|
||||
|
||||
## What Shipped
|
||||
|
||||
Studio now supports a direct DOM editing workflow inside the preview:
|
||||
|
||||
- select supported elements directly in the preview
|
||||
- see an editor-owned overlay around the current selection
|
||||
- move and resize supported elements on canvas when geometry is safe
|
||||
- detach eligible layout-controlled layers with an explicit `Make movable` action
|
||||
- edit style properties from the right-side `Design` inspector
|
||||
- edit text layers for safe text-bearing selections, including empty text values
|
||||
- add and remove child text layers for multi-text selections
|
||||
- edit solid fills, gradients, project-asset image fills, external image fills, opacity, radius, flex metadata, typography, and blend mode
|
||||
- drill into nested compositions from master view instead of pretending every inner node is editable in place
|
||||
- generate an element-scoped `Ask agent` prompt bundle from the right inspector
|
||||
|
||||
The important rule is conservative: Studio only exposes interactions it can round-trip back to authored HTML with deterministic behavior.
|
||||
|
||||
## Current User Experience
|
||||
|
||||
### Preview selection
|
||||
|
||||
- Single click selects a patchable element in the preview.
|
||||
- The selection overlay is rendered in Studio chrome, not injected into authored content.
|
||||
- The overlay is cleared when:
|
||||
- the `Inspector` panel is closed
|
||||
- the user clicks an empty area in the preview
|
||||
- the underlying element disappears after a source refresh
|
||||
|
||||
### Overlay behavior
|
||||
|
||||
The overlay provides:
|
||||
|
||||
- selection bounds
|
||||
- drag behavior for supported elements
|
||||
- a resize handle when width and height are safely patchable
|
||||
- blocked-drag feedback for unsupported movement
|
||||
|
||||
The overlay intentionally does not include a floating action toolbar. `Ask agent` lives in the right inspector header, and style controls live in the `Design` panel.
|
||||
|
||||
The current implementation uses Studio-owned pointer handling in `DomEditOverlay.tsx`. It does **not** use `Moveable`.
|
||||
|
||||
### Inspector behavior
|
||||
|
||||
The `Design` panel currently includes:
|
||||
|
||||
- `Layout`
|
||||
- X / Y / W / H fields
|
||||
- wheel and arrow-key numeric scrubbing
|
||||
- `Make movable` for block-ish layout-controlled layers that can be detached safely
|
||||
- `Flex`
|
||||
- direction, justify, align, gap, clip content
|
||||
- `Radius`
|
||||
- slider + live readout
|
||||
- `Blending`
|
||||
- opacity slider + live readout
|
||||
- blend mode
|
||||
- `Fill`
|
||||
- solid color
|
||||
- multi-stop gradient editing
|
||||
- project asset image fills
|
||||
- inline image upload into the project assets list
|
||||
- external image URL fill
|
||||
- text color
|
||||
- `Color picker`
|
||||
- viewport-clamped floating picker
|
||||
- saturation / brightness crosshair
|
||||
- hue and alpha sliders
|
||||
- hex input
|
||||
- `Text`
|
||||
- direct text layer editing when the selection is safe to patch
|
||||
- add / remove text layers for child text selections
|
||||
- font size, weight, and family controls
|
||||
- `Selection colors`
|
||||
- a summary of detected colors for the current selection
|
||||
|
||||
The inspector is intentionally split from `Renders` with a `Design / Renders` tab control in the right panel. Switching to `Renders` does not mean the header-level `Inspector` panel is closed.
|
||||
|
||||
## What Counts As Editable
|
||||
|
||||
Studio builds a `DomEditSelection` and `DomEditCapabilities` object for each selection.
|
||||
|
||||
### Selection requirements
|
||||
|
||||
A node is only useful to Studio if it can be identified with a stable patch target, for example:
|
||||
|
||||
- `id`
|
||||
- stable selector
|
||||
- selector index scoped to the correct source file
|
||||
- composition host mapping when master view is involved
|
||||
|
||||
### Move support
|
||||
|
||||
Move is allowed only when the selected element:
|
||||
|
||||
- has a stable patch target
|
||||
- is `absolute` or `fixed`
|
||||
- has `left` and `top` values that resolve to pixel values
|
||||
- is not transform-driven (`transform: none`)
|
||||
|
||||
### Resize support
|
||||
|
||||
Resize is allowed only when move is already allowed and Studio can also safely patch pixel `width` and/or `height`.
|
||||
|
||||
### Detach from layout support
|
||||
|
||||
Some block-ish layers are selectable and style-editable, but cannot be moved directly because flex, grid, or normal document flow owns their position.
|
||||
|
||||
For those layers, Studio can expose `Make movable` instead of silently converting on drag. The action measures the current visual rect relative to the composition root and writes conservative inline geometry:
|
||||
|
||||
- `position: absolute`
|
||||
- `left`, `top`, `width`, and `height` in pixels
|
||||
- `margin: 0`
|
||||
|
||||
The UI explains that this detaches the layer from flex/grid flow and preserves the current visual position. Inline text nodes are not detached directly.
|
||||
|
||||
### Text editing support
|
||||
|
||||
Text editing is allowed only for safe text-bearing selections:
|
||||
|
||||
- supported text-bearing tags such as `div`, `span`, `p`, `strong`, and headings
|
||||
- self text selections or leaf child text layers
|
||||
- empty text values after a user clears the content
|
||||
- not a composition host
|
||||
|
||||
For multi-text selections, Studio shows a text-layer list. Users can select a specific text layer, edit content live, change size, weight, and font family, add a sibling text layer, or remove the active layer.
|
||||
|
||||
### Unsupported examples
|
||||
|
||||
Studio intentionally withholds direct geometry editing for:
|
||||
|
||||
- flex/grid children whose position is emergent from layout, unless the user chooses `Make movable`
|
||||
- transform-driven geometry
|
||||
- nested composition internals while the user is still in master view
|
||||
- nodes without a stable patch target
|
||||
- inline text spans as geometry targets
|
||||
|
||||
When geometry is blocked but style edits are still safe, the inspector shows the selection and the reason direct geometry editing is unavailable.
|
||||
|
||||
If the user tries to drag a blocked layer, Studio shows a toast. Layout-owned layers point users to `Make movable`; transform-driven or unsafe targets explain that direct move/resize is limited to absolute or fixed pixel geometry with no transform-driven layout.
|
||||
|
||||
## Nested Composition Rules
|
||||
|
||||
Nested compositions are handled explicitly.
|
||||
|
||||
### In master view
|
||||
|
||||
- clicking content inside a nested composition maps back to the composition host
|
||||
- supported composition hosts can move as a whole when their host geometry is safe
|
||||
- Studio does not expose direct inner-node geometry edits from the master preview
|
||||
- double click drills into the subcomposition
|
||||
|
||||
### After drill-down
|
||||
|
||||
- Studio resolves selections inside that composition normally
|
||||
- direct move/resize becomes available again if the selected inner node meets the capability rules
|
||||
- text, fill, gradient, image, radius, opacity, and typography edits apply to the selected inner node
|
||||
|
||||
This keeps Studio honest about what it can patch safely from the current editing context.
|
||||
|
||||
## Source Patching Model
|
||||
|
||||
Studio still uses authored HTML as the source of truth.
|
||||
|
||||
The manual DOM editing flow patches source through the existing patch pipeline in `packages/studio/src/utils/sourcePatcher.ts`.
|
||||
|
||||
Current patch types used by the inspector include:
|
||||
|
||||
- inline style patches
|
||||
- attribute patches for timeline-linked editing paths
|
||||
- text-content patches
|
||||
- detach-from-layout style patches
|
||||
|
||||
The flow is:
|
||||
|
||||
1. user selects or manipulates an element in the preview
|
||||
2. Studio resolves a stable target
|
||||
3. the preview is updated optimistically for interaction feedback
|
||||
4. the patch is written back to source
|
||||
5. the preview refreshes and selection is reattached
|
||||
|
||||
## Gradient Editing
|
||||
|
||||
The current gradient editor is a structured Studio control, not a raw CSS text field.
|
||||
|
||||
It supports:
|
||||
|
||||
- `linear`, `radial`, and `conic` gradients
|
||||
- repeating variants
|
||||
- multiple stops
|
||||
- stop insertion by clicking the preview strip
|
||||
- stop removal
|
||||
- angle control
|
||||
- radial shape and size controls
|
||||
- radial/conic center controls
|
||||
|
||||
The editor still serializes back to CSS `background-image`, but the inspector works with a parsed gradient model instead of forcing the user to type raw gradient syntax.
|
||||
|
||||
## Image Fill Editing
|
||||
|
||||
The image fill editor is no longer just a raw `background-image` input.
|
||||
|
||||
It supports:
|
||||
|
||||
- selecting an existing project image asset
|
||||
- uploading an image from the fill panel, which also adds it to the Assets tab
|
||||
- previewing the selected project asset in the panel
|
||||
- entering an external URL when the image is not a project asset
|
||||
|
||||
Studio serializes project asset selections back to `background-image: url(...)`, and rewrites asset URLs so nested subcomposition previews still resolve the image correctly.
|
||||
|
||||
## Color Editing
|
||||
|
||||
The color editor is a custom Studio popover instead of the native browser color dialog.
|
||||
|
||||
It supports:
|
||||
|
||||
- opening from the whole color row
|
||||
- staying inside the viewport near the clicked color
|
||||
- saturation / brightness picking with visible crosshair guides
|
||||
- hue and alpha controls with visible handles
|
||||
- a current color swatch, readout, and hex input
|
||||
|
||||
The picker writes CSS `rgb(...)` or `rgba(...)` values and preserves alpha through edits.
|
||||
|
||||
## Numeric Scrubbing
|
||||
|
||||
Numeric layout/detail inputs support lightweight design-tool-style nudging:
|
||||
|
||||
- mouse wheel over the focused field
|
||||
- `ArrowUp` / `ArrowDown`
|
||||
- `Shift` for larger steps
|
||||
- `Alt` for finer steps
|
||||
|
||||
This is currently used across the numeric commit fields in the inspector, including layout metrics and other numeric text inputs that parse cleanly as values plus units.
|
||||
|
||||
## Files That Own The Feature
|
||||
|
||||
The main implementation lives in:
|
||||
|
||||
- `packages/studio/src/App.tsx`
|
||||
- overall inspector wiring
|
||||
- selection lifecycle
|
||||
- preview hit testing
|
||||
- persistence hooks
|
||||
- detach-from-layout commit flow
|
||||
- `packages/studio/src/components/editor/DomEditOverlay.tsx`
|
||||
- overlay box, drag, resize, blocked-drag feedback
|
||||
- `packages/studio/src/components/editor/PropertyPanel.tsx`
|
||||
- right-side inspector UI
|
||||
- `packages/studio/src/components/editor/domEditing.ts`
|
||||
- selection resolution
|
||||
- capability gating
|
||||
- text field modeling
|
||||
- prompt generation
|
||||
- `packages/studio/src/components/editor/colorValue.ts`
|
||||
- color parsing, HSV conversion, and CSS color serialization
|
||||
- `packages/studio/src/components/editor/floatingPanel.ts`
|
||||
- viewport-safe floating panel placement for color picking
|
||||
- `packages/studio/src/components/editor/fontAssets.ts`
|
||||
- imported font asset helpers
|
||||
- `packages/studio/src/components/editor/fontCatalog.ts`
|
||||
- Google font catalog metadata and stylesheet URLs
|
||||
- `packages/studio/src/components/editor/gradientValue.ts`
|
||||
- gradient parsing, serialization, and stop editing helpers
|
||||
- `packages/studio/src/utils/sourcePatcher.ts`
|
||||
- source patch persistence
|
||||
|
||||
Supporting Studio shell changes also landed in:
|
||||
|
||||
- `packages/studio/src/components/nle/NLELayout.tsx`
|
||||
- `packages/studio/src/components/nle/NLEPreview.tsx`
|
||||
- `packages/studio/src/components/sidebar/CompositionsTab.tsx`
|
||||
- `packages/studio/src/components/sidebar/LeftSidebar.tsx`
|
||||
- `packages/studio/src/player/components/Player.tsx`
|
||||
- `packages/studio/src/player/components/Timeline.tsx`
|
||||
- `packages/studio/src/player/components/TimelineClip.tsx`
|
||||
- `packages/studio/src/player/hooks/useTimelinePlayer.ts`
|
||||
- `packages/studio/src/utils/mediaTypes.ts`
|
||||
|
||||
## Current Constraints
|
||||
|
||||
This feature is intentionally **not** a full general-purpose visual builder.
|
||||
|
||||
Still out of scope today:
|
||||
|
||||
- rotation
|
||||
- arbitrary transforms
|
||||
- snapping and alignment guides
|
||||
- multi-select
|
||||
- marquee selection
|
||||
- freeform editing of every DOM node regardless of layout model
|
||||
- editing nested subcomposition internals directly from the master preview without drill-down
|
||||
- automatic conversion to absolute positioning on drag without user confirmation
|
||||
- direct geometry editing of inline text spans
|
||||
|
||||
## Bottom Line
|
||||
|
||||
Studio manual DOM editing is now a narrow, deterministic visual editing layer over authored HTML.
|
||||
|
||||
It does **not** try to make the whole DOM freely editable. Instead it:
|
||||
|
||||
- keeps source HTML as the source of truth
|
||||
- exposes only patchable interactions
|
||||
- uses a Studio-owned overlay layer for direct manipulation
|
||||
- gives users a real inspector for safe style and text edits
|
||||
- treats nested compositions as drill-down boundaries instead of flattening them into an unsafe editing surface
|
||||
|
||||
That tradeoff is the reason the current feature feels reliable instead of deceptive.
|
||||
@@ -1,132 +1,85 @@
|
||||
---
|
||||
title: Testing Local CLI Changes
|
||||
description: How to test unreleased CLI changes outside the monorepo using your local build.
|
||||
title: Test local CLI changes
|
||||
description: Run an unreleased HyperFrames CLI build against a real project outside the monorepo.
|
||||
---
|
||||
|
||||
When you modify the CLI or any package it bundles (core, engine, producer, studio), you need to test those changes against real projects _outside_ the monorepo — the same way an end user would run `hyperframes preview`.
|
||||
Package tests do not prove that the CLI behaves correctly in an ordinary video project. After the focused tests pass, run the changed command against a project outside the HyperFrames repository.
|
||||
|
||||
## Prerequisites
|
||||
## Build the workspace
|
||||
|
||||
Build the monorepo first. Every time you change source files, rebuild before testing.
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
# From the monorepo root
|
||||
bun install
|
||||
bun run build
|
||||
```
|
||||
|
||||
## Option 1: bun link (recommended)
|
||||
Rebuild after changing CLI code or a package bundled by the CLI.
|
||||
|
||||
`bun link` makes the `hyperframes` binary in your `$PATH` point at your local build. It survives across terminal sessions and auto-picks up new builds without re-linking.
|
||||
## Run the local build
|
||||
|
||||
Choose one method.
|
||||
|
||||
### Link the CLI
|
||||
|
||||
Use this when you will test several commands or projects:
|
||||
|
||||
```bash
|
||||
# If you previously installed hyperframes globally, remove it first —
|
||||
# a global install takes priority over bun link and shadows your local build.
|
||||
npm uninstall -g hyperframes 2>/dev/null
|
||||
|
||||
# Link your local build
|
||||
cd packages/cli
|
||||
bun link
|
||||
|
||||
# Verify — should print your local version AND point to the monorepo
|
||||
hyperframes --version
|
||||
which hyperframes
|
||||
```
|
||||
|
||||
Now use `hyperframes` normally in any directory:
|
||||
The resolved binary should point into the local HyperFrames checkout. Run it from a separate project:
|
||||
|
||||
```bash
|
||||
cd ~/my-video-project
|
||||
hyperframes preview .
|
||||
cd /path/to/a/video-project
|
||||
hyperframes lint
|
||||
hyperframes check
|
||||
hyperframes preview
|
||||
```
|
||||
|
||||
**After every `bun run build`** the linked binary is already up to date — no re-linking needed.
|
||||
|
||||
To restore the published release when you're done:
|
||||
Remove the link when finished:
|
||||
|
||||
```bash
|
||||
bun unlink hyperframes
|
||||
npm install -g hyperframes@latest
|
||||
```
|
||||
|
||||
## Option 2: node alias (no PATH changes)
|
||||
### Call the built entry directly
|
||||
|
||||
If you don't want to touch your global `$PATH`, add a shell alias or call `node` directly:
|
||||
Use this when you do not want to change your `PATH`:
|
||||
|
||||
```bash
|
||||
# Temporary alias for your current shell session
|
||||
alias hyperframes="node /path/to/hyperframes/packages/cli/dist/cli.js"
|
||||
|
||||
# Or invoke directly
|
||||
node /path/to/hyperframes/packages/cli/dist/cli.js preview .
|
||||
node /path/to/hyperframes/packages/cli/dist/cli.js preview /path/to/a/video-project
|
||||
```
|
||||
|
||||
Replace `/path/to/hyperframes` with your actual monorepo path.
|
||||
### Test the package archive
|
||||
|
||||
## Option 3: npm pack (test the exact published artifact)
|
||||
|
||||
Use this when you want to verify what would actually ship in a release, including the bundled studio and examples.
|
||||
Use this before a release to check the files that would actually be published:
|
||||
|
||||
```bash
|
||||
cd packages/cli
|
||||
npm pack
|
||||
# Creates: hyperframes-<version>.tgz
|
||||
|
||||
# Test it in an isolated directory
|
||||
mkdir /tmp/pack-test && cd /tmp/pack-test
|
||||
npx /path/to/hyperframes/packages/cli/hyperframes-<version>.tgz init my-video
|
||||
cd my-video
|
||||
npx /path/to/hyperframes/packages/cli/hyperframes-<version>.tgz preview .
|
||||
npx ./hyperframes-<version>.tgz --help
|
||||
```
|
||||
|
||||
## Testing the fix branches
|
||||
Run the archive against an isolated project as well as the command you changed.
|
||||
|
||||
When validating a specific bug fix, extract one of the test project archives and run through the scenario:
|
||||
## What to verify
|
||||
|
||||
```bash
|
||||
# Example: testing audio-after-seek fix
|
||||
unzip golden-lyric-video.zip && cd golden-lyric-video
|
||||
hyperframes preview .
|
||||
# 1. Press Play — confirm audio plays
|
||||
# 2. Drag the timeline scrubber to a different position
|
||||
# 3. Press Play again — audio should resume from the seeked position
|
||||
```
|
||||
Test the user-visible outcome, not only the exit code:
|
||||
|
||||
Common test scenarios:
|
||||
- the command accepts the documented arguments;
|
||||
- errors explain how to recover;
|
||||
- `--json` remains machine-readable when the command supports it;
|
||||
- Preview opens the correct project and reflects file changes;
|
||||
- a render produces a playable file with the expected duration and media;
|
||||
- temporary files and background processes are cleaned up after success and failure.
|
||||
|
||||
| Bug | Project | Steps |
|
||||
|---|---|---|
|
||||
| Audio silent after seek | `golden-lyric-video` | Play → seek → play again, verify audio |
|
||||
| Render stuck at 0% | any | Renders tab → Export → watch progress bar |
|
||||
| Download 404 after restart | any | Complete a render → `Ctrl+C` → restart → Download |
|
||||
| Timeline stops early | `intro-vid` | Play → should reach `0:05`, not stop at `0:03` |
|
||||
| Lottie missing | `hyperframe-build-up-demo` | Play → rocket visible during 0–2 s |
|
||||
| Blank thumbnails | any | Compositions sidebar should show previews |
|
||||
For Studio changes, exercise the exact interaction in Preview. For rendering changes, inspect the output with `ffprobe` or the repository's existing fixture tests rather than relying on visual playback alone.
|
||||
|
||||
## Troubleshooting
|
||||
## Common problems
|
||||
|
||||
**Changes not reflected after `bun run build`**
|
||||
|
||||
The CLI binary is a single bundled file at `packages/cli/dist/cli.js`. If your change is in `@hyperframes/core` or another workspace package, make sure `bun run build` rebuilt _all_ packages — the CLI bundles its dependencies at build time.
|
||||
|
||||
**`hyperframes` still shows the old version / old UI**
|
||||
|
||||
A globally installed `hyperframes` package shadows `bun link`. Check which binary is active:
|
||||
|
||||
```bash
|
||||
which hyperframes
|
||||
```
|
||||
|
||||
If it points to a global store rather than your monorepo, remove the global install and re-link:
|
||||
|
||||
```bash
|
||||
npm uninstall -g hyperframes
|
||||
cd packages/cli && bun link
|
||||
```
|
||||
|
||||
**Port already in use**
|
||||
|
||||
`hyperframes preview` defaults to port 3002 and auto-increments if it's taken. Pass `--port` to use a specific port:
|
||||
|
||||
```bash
|
||||
hyperframes preview . --port 4000
|
||||
```
|
||||
If a globally installed CLI shadows the link, inspect `which hyperframes`, remove the global package, and link again. Preview starts at port `3002` and automatically tries a free port; pass `--port` only when a fixed port is required.
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Anatomy of a one-shot prompt
|
||||
description: "The six-part skeleton — route, spec, beats, copy, technique, negatives — that removes the decisions agents most often get wrong."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Your Level 1 prompts worked because the workflow filled the gaps for you — the palette, the pacing, the structure. This is Level 2: the skeleton is how you take that control yourself.
|
||||
|
||||
The [copy-paste examples](/prompting/examples) share one skeleton. Each part removes a decision agents most often get wrong on a first try:
|
||||
@@ -27,7 +29,11 @@ Assembled:
|
||||
|
||||
> /motion-graphics Make an 8-second 1920x1080 video. Beat 1 (0-4s): dark macOS terminal types "npx skills add heygen-com/hyperframes" character by character, then hold on the blinking cursor. Beat 2 (4-5s): the terminal shatters into fragments. Beat 3 (5-8s): bold white kinetic text on black slams in word by word, snappy: "YOU JUST MADE THIS / WITH HYPERFRAMES." Adapt the `code-typing` and `vfx-shatter` registry blocks; hand-author the kinetic text. No narration, no image or media files.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Anatomy Terminal"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
<Note>
|
||||
@@ -101,7 +107,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> **Mount (7–14s).** Traveling along the wire: it splits into three parallel track lanes; clip chips slide in along the direction of travel and seat onto the lanes on their spoken cues (audio track chip, video track chip, our protagonist chip among them). Small mono labels (`data-start`, `data-track-index`) tag themselves onto chips as the camera passes. The lanes merge back to one wire as the camera accelerates out.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-mount.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Mount"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-mount.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [The specification dial](/prompting/specification-dial) — how much of the skeleton to fill in, and when density stops being optional.*
|
||||
|
||||
@@ -3,7 +3,13 @@ title: Capstone — every technique, one journey
|
||||
description: "One prompt, one continuous camera move, every technique in this guide — the viewer rides the timeline itself from typed markup to rendered MP4."
|
||||
---
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Timeline Default"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*"The Timeline" — 1920x1080, ~62 seconds, one prompt, one unbroken camera move, unedited.*
|
||||
|
||||
The prompt targeted roughly 60 seconds; the delivered render runs 1:02 because the final lockup holds for a two-second breath.
|
||||
@@ -111,7 +117,11 @@ HyperFrames scopes `data-composition-variables` **per composition file**, so the
|
||||
hyperframes render --variables '{"ground":"#0d1420","ink":"#c8ff3d"}' --strict-variables
|
||||
```
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-reskin.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Timeline Reskin"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-reskin.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The same composition, navy/acid-green — the wire, ruler, chart, map, glass, and even the generated mural all follow the override.*
|
||||
|
||||
The mural trick from the previous capstone carries over: the artwork is generated **palette-neutral** (grayscale) and duotoned live by CSS layers driven by the `ground`/`ink` variables, so even the raster re-skins. Keep color in CSS and shapes in the raster whenever a template frame needs to survive a re-skin.
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Captions and talking-head footage
|
||||
description: "Two ways to dress an existing talking-head clip — readable captions or designed graphic overlays — both leaving the footage itself untouched."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
The first two rides built a video from nothing and the third built one from a diff. This one starts from footage you already have — a talking-head clip — and adds a layer on top without touching the shot itself.
|
||||
|
||||
## Your first win
|
||||
@@ -12,7 +14,12 @@ One prompt to [`/embedded-captions`](/prompting/overview), pointed at an existin
|
||||
Captions route by **identity**, not by mode. You pick one look from the catalog; the engine behind it is a lookup detail you never have to name. The default is a clean verbatim rail — `anchor` — with the occasional peak word composited behind the subject.
|
||||
|
||||
> /embedded-captions Add captions to ./interview.mp4. Use the `anchor` identity — clean verbatim rail carrying the spoken words, readable lower-third. Promote the single hardest-hitting word to an embed behind the speaker; highlight one key word in each rail line. Keep the source aspect ratio. Footage stays untouched.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/captions-anchor-rail.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Captions Anchor Rail"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/captions-anchor-rail.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above on generated avatar footage, unedited — one earned embed behind the speaker, everything else on the rail.*
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Caption styles
|
||||
description: "Map caption tone to named caption components, and prompt per-word emphasis for composed videos."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Your faceless explainer from Level 1 already asked for "embedded captions, keywords highlighted in the accent color" and got a sensible default. This chapter is the catalog behind that ask — the named components you can pin instead, by tone, so the highlight color and the animation are a decision, not a default.
|
||||
|
||||
## What caption styles do and when they trigger
|
||||
@@ -40,7 +42,12 @@ Three [Text Effects](/catalog/components/morph-text) components do one focused j
|
||||
|
||||
> /faceless-explainer 30-second vertical explainer. Add [`caption-highlight`](/catalog/components/caption-highlight) captions, TikTok-style — the visible line stays up, one word highlighted at a time.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-captions-catalog.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Captions Catalog"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-captions-catalog.mp4#t=0.1"
|
||||
portrait
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -50,13 +57,21 @@ Three [Text Effects](/catalog/components/morph-text) components do one focused j
|
||||
|
||||
> Hype captions with [`caption-kinetic-slam`](/catalog/components/caption-kinetic-slam): one full-screen word per beat, alternating slam-in direction.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-kinetic-slam.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Caption Kinetic Slam"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-kinetic-slam.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above with an authored 24-word line, unedited.*
|
||||
|
||||
|
||||
> Neon music-video captions using [`caption-neon-glow`](/catalog/components/caption-neon-glow). Make brand names larger with an accent color and highlight the numbers differently.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-neon-glow.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Caption Neon Glow"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/caption-neon-glow.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — the brand renders 1.4x in magenta, numbers in amber, distinct from the default cyan.*
|
||||
|
||||
|
||||
@@ -100,7 +115,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> THEN they speak, and the main **keywords of their own line — derived from the clip's transcription — land word-synced as huge display text BEHIND the cutout**, each keyword slamming in on its spoken moment with the subject's silhouette occluding it (the two-layer text-behind-subject plate); style the keyword type by adapting a bold **catalog caption component** (`caption-kinetic-slam` or similar) at display scale.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Material"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [When to generate artwork](/prompting/generated-artwork) — where hand-drawn HTML/CSS/SVG wins, and where a generated image beats it.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Code changes and PRs
|
||||
description: "What to say to turn a GitHub pull request into a code-change explainer — changelog, feature reveal, fix, or refactor walkthrough."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Two rides in, both built from nothing yet on the page. This one starts from something that already exists and is already true — a merged PR — and turns the diff itself into the story.
|
||||
|
||||
## Your first win
|
||||
@@ -13,7 +15,11 @@ Verified, from the [examples](/prompting/examples) page — a 30-second feature
|
||||
|
||||
> /pr-to-video Make a 30-second 1920x1080 feature-reveal video from [PR URL]. Lead with what users get, not the diff; show the key code change with the `code-diff` block for one beat only; end on version number + repo URL. No narration, kinetic captions instead.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Pr Video"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -47,8 +53,12 @@ What you can already steer from the prompt, before you've learned any technique.
|
||||
<AccordionGroup>
|
||||
<Accordion title="Changelog roundup">
|
||||
> /pr-to-video Make a ~40-second 1920x1080 changelog video from [PR URL]. Changelog angle: open with the release line, then one beat per notable change — a short label and a one-line "what it does" each. Show at most two `code-diff` hunks across the whole video. End on version + repo URL. Calm male TTS narration, no captions.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-pr-changelog.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Variant Pr Changelog"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-pr-changelog.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from this prompt with [PR URL] = heygen-com/hyperframes#2092, unedited.*
|
||||
|
||||
A changelog trades depth for breadth — many small changes, each a beat, rather than one change explored deeply. Keep code beats sparse so the pace stays fast. A PR doesn't carry its shipping version — the agent finds it from the release tag or the package manifest on main.
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Code animations
|
||||
description: "Prompt code walkthroughs — typing, diffing, highlighting, scrolling — and pick a terminal or editor theme by name."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Your PR video from Level 1 named `code-diff` for a single beat and moved on. This chapter is the rest of that catalog: typing, diffing, highlighting, scrolling, and picking a terminal or editor theme by name — for the moments a walkthrough needs to slow down and let the code itself carry the scene.
|
||||
|
||||
Code is the one subject where the framework does the hard part for you. The [Code Animations](/catalog/blocks/code-typing) blocks handle syntax highlighting, caret tracking, diff coloring, and camera moves deterministically — you describe the *walkthrough*, name the block, and paste your snippet. This page is the vocabulary for doing that well; for turning a real pull request into a code-change video, see [Code and PRs](/prompting/code-and-prs).
|
||||
@@ -44,7 +46,11 @@ The first four are the workhorses of a code *walkthrough* — they keep the code
|
||||
> ```
|
||||
> Use the `code-typing` registry block. No narration, no image or media files.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-typing.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Code Typing"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-typing.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -65,13 +71,21 @@ For "here's what changed," hand `code-diff` the before and after and let it colo
|
||||
> added: `const res = await fetch(url, { signal })`
|
||||
> Use the `code-diff` registry block. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-diff.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Code Diff"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-diff.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
> /motion-graphics 5-second 1920x1080 video. Show a 12-line config file; a highlight band sweeps to line 7 (`timeout: 30_000`) while the surrounding lines dim. Hold with line 7 lit and the cursor blinking. Use the `code-highlight` registry block. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-highlight.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Code Highlight"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-code-highlight.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — the agent authors plausible surrounding config lines; paste all 12 if the exact file matters.*
|
||||
|
||||
|
||||
@@ -85,7 +99,11 @@ For "here's what changed," hand `code-diff` the before and after and let it colo
|
||||
|
||||
> /motion-graphics 6-second 1920x1080 video. Scroll a ~60-line source file so line 44 (`return dedupeFrames(frames)`) arrives at center and gets spotlighted; ease the scroll and let it settle without snapping. Use the `code-scroll` registry block. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/code-scroll.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Code Scroll"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/code-scroll.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
**Ask the scroll to ease and settle, not snap.** A linear scroll that stops dead reads mechanical.
|
||||
@@ -120,7 +138,11 @@ The [Code Snippets](/catalog/blocks/code-snippet-monokai) blocks are pre-styled
|
||||
|
||||
> /motion-graphics 5-second 1920x1080 video. A macOS Terminal window in the Ocean profile types `npx skills add heygen-com/hyperframes` character by character, then holds on the typed, unexecuted command with the cursor blinking — no output, no second prompt. Use the `code-snippet-apple-terminal-ocean` registry block. No narration.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/terminal-ocean.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Terminal Ocean"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/terminal-ocean.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -151,7 +173,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> **Type (0–7s).** Black-on-charcoal close-up: a cursor types real HyperFrames markup character by character — `<div class="clip" data-start="0" data-duration="4">` and a `gsap.timeline({ paused: true })` line. As the typed line completes, the text's baseline extends and becomes **the wire** — the underline literally grows into the timeline and the camera begins its dolly along it. The typed div folds into a compact clip chip (persistent element 3) that drops onto the wire. Kinetic display type states "WRITE HTML." as the travel begins.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-type.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Type"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-type.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Data and maps](/prompting/data-and-maps) — the same named-block, quoted-copy pattern, for charts, stats, and maps instead of code.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Color grading and film effects
|
||||
description: "Grade media with a fixed-order pipeline — tonal work, hue keys, print and analogue treatments — and know why the source matters more than the payload."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Every chapter so far has built the image. This one changes what the image appears to have been *recorded on*. A grade is not decoration applied at the end; it is a claim about the medium — that this came off tape, or a press, or a tube, or a camera with a particular stock in it. Viewers read that claim instantly and they read it whether or not you meant it.
|
||||
|
||||
Grading attaches to a single `<img>` or `<video>` through a `data-color-grading` payload. It never touches your text, your cards, or your captions — only the pixels of the media element it is on. The full contract lives in the [Color Grading guide](/guides/color-grading); this chapter is about what to *ask for*, and about the three ways these prompts go wrong.
|
||||
@@ -45,7 +47,11 @@ The most useful thing grading does is not a look. It is protecting one part of t
|
||||
|
||||
> Take the talking-head clip and separate the subject from the room. Leave the person photographic — a gentle skin-softening pass and about a third of a stop of extra exposure, nothing that reads as an effect on skin. Grade the room behind them instead: across the four seconds bring up a halftone screen so the space resolves into small colored dots, and let a restrained bloom build alongside it so the windows lift. Both start at zero so the shot opens ungraded.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-matte-separation-b0ef8e73.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Matte Separation B0ef8e73"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-matte-separation-b0ef8e73.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The room takes the halftone screen and the bloom; the subject takes nothing but a skin-soft pass and a third of a stop.*
|
||||
|
||||
Two traps here. Use the **original clip** as the background plate, not a subject-removed plate — that plate is a hole where the subject was, and a feathered cutout over it gives a dark rim. And if your cutout ships premultiplied alpha, the browser composites it as straight, multiplying edge pixels twice and producing a black outline; rebuild it with `ffmpeg alphamerge` from the original plus its matte.
|
||||
@@ -54,7 +60,11 @@ Two traps here. Use the **original clip** as the background plate, not a subject
|
||||
|
||||
> Matte the subject off the plate, then redact just their face — the rest of them and the room behind both stay completely untouched. Hold pixelation constant at about half strength for the whole shot: no ramp, no fade-up. A redaction that animates on reads as an effect; one that is simply on reads as policy. Size the redaction generously so it takes in the hairline, ears and jaw rather than sitting tight on the features.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-redaction-engaging-ec781f26.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Redaction Engaging Ec781f26"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-redaction-engaging-ec781f26.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Face pixelated, body and room untouched — the region is a `clip-path` on a third layer, not a payload setting.*
|
||||
|
||||
The region comes from a `clip-path` on a *third* layer — a second copy of the cutout carrying the grade, stacked over an ungraded copy. Because the graded layer **is** the cutout, the ellipse can overshoot the head without touching the room; there is nothing outside the silhouette to paint. Size it generously rather than tightly.
|
||||
@@ -71,12 +81,20 @@ Three ways to take the image apart, each saying something different. Pixelation
|
||||
|
||||
> Degrade the picture into a screen over four seconds. Ramp dithering from clean up to 0.85 at mid pattern size, so continuous tone breaks into discrete quantised levels. It should read as a display failing, not as a filter being applied.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-signal-loss-babe88ef.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Signal Loss Babe88ef"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-signal-loss-babe88ef.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Dither ramping from clean to 0.85 — continuous tone breaking into discrete levels.*
|
||||
|
||||
> Blow the highlights out over four seconds. Ramp bloom from nothing all the way to 3 — well past a tasteful highlight lift — on a wide radius, so light spills out of the windows and progressively swallows the frame. I want to see the top of the range, not a subtle glow.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-bloom-out-11531968.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Bloom Out 11531968"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-bloom-out-11531968.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Bloom driven to 3, well past a highlight lift, until the light swallows the frame.*
|
||||
|
||||
<Warning>
|
||||
@@ -87,7 +105,11 @@ Three ways to take the image apart, each saying something different. Pixelation
|
||||
|
||||
> Turn the shot into a painting over four seconds without turning it to mush. Ramp a Kuwahara filter from nothing to full — mid radius, fairly high sharpness so edges stay crisp, and pull the saturation back a little so it reads as brushwork rather than as a filter. Boundaries stay defined while flat areas smooth into strokes. Pick a subject with dense color and dense edges; the effect has nothing to preserve on flat skin or a soft-focus background.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-painterly-ffd5c0f9.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Painterly Ffd5c0f9"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-painterly-ffd5c0f9.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Kuwahara at full strength, on a subject with enough edges to be worth preserving.*
|
||||
|
||||
---
|
||||
@@ -98,7 +120,11 @@ Three ways to take the image apart, each saying something different. Pixelation
|
||||
|
||||
> Take the poster and print it in two inks only: a near-black navy and a warm cream, at mid dot size, like a two-color press run. Everything collapses to those two colors. Bring it up across the four seconds from the untouched poster rather than cutting straight to it. Give it the exact hex values rather than a named palette.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-two-ink-press-3c5662f1.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Two Ink Press 3c5662f1"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-two-ink-press-3c5662f1.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Ten hue families collapsing to three. Dense type is the harshest test of a two-ink reduction.*
|
||||
|
||||
Type is the harshest test of a two-ink reduction — dense small copy either survives the dot screen or turns to mud, and you can see which at a glance. Note the payload takes an explicit hex array; a named palette id is rejected.
|
||||
@@ -107,7 +133,11 @@ Type is the harshest test of a two-ink reduction — dense small copy either sur
|
||||
|
||||
> A single red apple on a teal backdrop. Hold the apple's color and drain everything else — key off hue and collapse saturation everywhere outside the reds, so the backdrop goes fully neutral grey while the apple stays exactly as saturated as it was. Use a hue-vs-saturation curve rather than a global desaturation with the apple keyed back in: global saturation runs first in the pipeline and would kill the apple before the key ever sees it. Keep a generous skirt on the band so the apple's shadowed side doesn't clip grey.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-brand-spotlight-5ebe45bf.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Brand Spotlight 5ebe45bf"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-brand-spotlight-5ebe45bf.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The backdrop drains to neutral grey; the apple holds its saturation exactly.*
|
||||
|
||||
Three things have to be true of the subject, and each one killed an earlier attempt at this shot. It must be **inanimate** — the grade desaturates everything outside the band, and on a person that means a grey, corpse-like face. It must be a **single** subject — a still life of mixed produce is full of color, but half the items fall outside the band and grey out, so it reads as a filter misfiring rather than one color deliberately held. And the surround must **carry** color: against a neutral grey backdrop the grade would desaturate grey to grey and do nothing at all.
|
||||
@@ -130,14 +160,22 @@ The rolling wave is `tapeTracking` and `tapeDamage`. Static interlacing is `scan
|
||||
|
||||
> Make it look like a worn VHS tape. Not one artefact — layer them: strong tape damage with tracking error, a little noise, mid tape speed, scanlines, and noticeable chroma bleed. Any one of these alone reads as a filter; together they read as a failing signal.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-tape-degradation-6050228f.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Tape Degradation 6050228f"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-tape-degradation-6050228f.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Six tape artefacts at once — any one of them alone reads as a filter.*
|
||||
|
||||
### Tube
|
||||
|
||||
> Make this look like it is being displayed on an old CRT television, not like it came off a worn tape. Bow the geometry with barrel curvature so the straight lines curve and the corners pull inward, lay scanlines across it at a fairly fine pitch, add phosphor bleed and enough chromatic aberration to give visible RGB fringing at the edges. Bleed and scanlines want to sit near the top of their range — bleed is subtle even at 0.9. Curvature and chromatic aberration are the exceptions: both read strongly, so hold curvature around half and keep the aberration modest, or the tube turns into a fisheye novelty. Grade the tone as well as the geometry: crush the shadows and blacks, lift the highlights and whites, nudge saturation up, and add a restrained bloom — a CRT has no true black and lets its top end halate. Add grain and a vignette. Use a test card or something with dead-straight lines: curvature is invisible on organic subject matter.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-crt-broadcast-b64dc1a8.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Crt Broadcast B64dc1a8"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-crt-broadcast-b64dc1a8.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Geometry bowed, scanlines laid over it, tone crushed — a tube rather than a filter on a clean image.*
|
||||
|
||||
The tonal work is doing as much as the geometry. Without crushed shadows and a halating top end, curvature and scanlines read as a filter laid over a clean digital image.
|
||||
@@ -148,7 +186,11 @@ If you composite a subject into the shot, do it **before** grading. A CRT warps
|
||||
|
||||
> Take the clip and give it a camcorder grade: crush the shadows and blacks, lift the highlights and whites, pull the saturation back slightly, and add a restrained bloom, film grain for noise, a vignette, interlacing lines, and a little RGB splitting at the edges. Crushed contrast with muted color is what consumer tape actually looked like — crushed and punchy reads as a modern filter. For the split use chromatic aberration, which offsets the channels; chroma bleed is a different thing, a smear rather than a fringe. Keep the interlacing static — no tape tracking and no tape damage, because those produce a rolling horizontal wave that reads as a broken deck rather than as a camera.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-camcorder-overlay-18e80485.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Grade Camcorder Overlay 18e80485"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/grade-camcorder-overlay-18e80485.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The footage degrades; the HUD does not. It is an overlay, composed above the media canvas.*
|
||||
|
||||
The HUD in that shot is not part of the grade. It is a [`camcorder-hud`](/guides/media-overlays) registry block — real HTML, CSS, and a paused GSAP timeline composed *above* the media canvas. Grading never touches it, which is exactly what you want: burn a timestamp into the source pixels and it degrades with them; put it in an overlay and it stays crisp, editable, and timeline-driven while the footage falls apart underneath.
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Data and maps
|
||||
description: "Prompt animated charts, count-up stats, and maps — highlight regions, draw flows, size bubbles — or hand-draw a chart for full control."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Level 3's six-scene SaaS explainer ended on a `cinematic-zoom` into a pricing reveal — a transition doing the work a real number could. This chapter is how to put an actual animated chart or count-up stat in that reveal instead of just a camera move.
|
||||
|
||||
Numbers and geography are the two subjects where "what data" and "how it moves" are separate decisions. The [Data](/catalog/blocks/data-chart) blocks give you a polished chart or map you feed values into; the count-up [showcase](/catalog/blocks/apple-money-count) blocks handle the odometer-and-flourish moment. Everything here plugs into the [one-shot skeleton](/prompting/anatomy) — the data goes in the "copy" slot, the block name in "technique."
|
||||
@@ -22,12 +24,20 @@ Feed data inline or as a file. Small series go straight in the prompt; a CSV get
|
||||
> ```
|
||||
> Use the `data-chart` registry block. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/chart-languages.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Chart Languages"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/chart-languages.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — labels count up while the next bar is already growing.*
|
||||
|
||||
> /motion-graphics 10-second 1920x1080 video, dark slate background. Title "Top languages 2026" top-left. Five horizontal bars (Python, TypeScript, Rust, Go, Java) grow from zero with staggered starts, overtaking each other twice mid-animation; each bar has a right-edge value label counting up to its final %. End state holds 2s, alive — the leader pulses once, timed to finish exactly on the last frame, never a frozen tail. Hand-author the marks (no chart library) and make them *look* hand-drawn: wobbly ink strokes, not clean rectangles. Say which two pairs overtake and when, or the reveal will land on a different number of crossings each run. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/barrace-handdrawn.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Barrace Handdrawn"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/barrace-handdrawn.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — hand-authored ink strokes, no chart library; ranks swap twice.*
|
||||
|
||||
|
||||
@@ -45,7 +55,11 @@ For a single hero number, [`apple-money-count`](/catalog/blocks/apple-money-coun
|
||||
|
||||
> /motion-graphics 6-second 1920x1080 video, dark navy background. Beat 1 (0-1s): label "ARR" fades up small, top-center. Beat 2 (1-4s): a giant number counts up to $4.2M with an odometer roll, easing out as it lands. Beat 3 (4-6s): "+312% YoY" stamps in below in green, then settles into a gentle ambient idle. Use the `apple-money-count` registry block as base. No narration.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/money-count.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Money Count"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/money-count.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -66,7 +80,11 @@ The US map encodings combine — asking to "shade states *and* draw flows betwee
|
||||
|
||||
> /motion-graphics 12-second 1920x1080 video. A US choropleth shades states by adoption rate with staggered reveals and a gradient legend, then connection arcs draw between San Francisco, Austin, and New York. Use the `us-map` and `us-map-flow` registry blocks. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-us-map-flows.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Us Map Flows"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-us-map-flows.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -88,7 +106,11 @@ For a point-to-point journey — a route drawing across a map with a landing bea
|
||||
|
||||
> /motion-graphics 6-second 1920x1080 video. A realistic map with a plane flying between two cities, a marker circle at the origin, and a landing pop at the destination. Use the `nyc-paris-flight` registry block as base — the route runs New York (JFK) → Paris (CDG), labelled at both ends. Keep the block's own title card and route ticks. End on the settled map, not on the block's white-out hand-off frame. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/flight-route.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Flight Route"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/flight-route.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -113,7 +135,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
>
|
||||
> **Everywhere (21–28s).** The wire arcs and the ground falls away: adapt the **`world-map` registry block** — the dotted world map scrolls beneath while the wire becomes a great-circle route arcing across it. Real render infrastructure, truthfully labeled: pulses light up at AWS and Google Cloud regions (US-EAST-1 · EU-WEST-1 · AP-SOUTH-1) with a "CLOUD RENDER · LAMBDA + CLOUD RUN" kicker […]
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-data-map.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Data Map"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-data-map.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Overlays and lower thirds](/prompting/overlays-and-lower-thirds) — naming timed blocks that sit above your footage or scene, instead of ones that render the scene itself.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Design systems and brand
|
||||
description: "Point the agent at a source of brand truth — a design spec, a site, or a Figma file — instead of asking for 'on-brand', and let it compose the frame."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Everything so far was one scene at a time. This level is about videos as systems — design that persists across scenes, edits that don't regress, output that ships. It starts with the most systemic thing a video has: its brand.
|
||||
|
||||
"Make it on-brand" is the single vaguest thing you can ask. The agent has no way to know what your brand *is*, so it invents one. The fix is always the same: give it a **source of brand truth** — a design spec, a live site, or a Figma file — and name it in the prompt. Everything on this page is a way to do that.
|
||||
@@ -97,7 +99,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> **Design system: the provided `frame.md` is the single source of brand truth — read it first and obey it exactly.** It is the real HyperFrames brand (by HeyGen), dark-first: flat near-black ground […] **mint `#3CE6AC` used sparingly as the single accent — mint means go / primary / active**. The mint→cyan gradient (`#3CE6AC → #00E3FF`) appears in exactly one place in the whole film: the final CTA lockup.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Render"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause paying off, rendered — the closing lockup, where the brand file's display face and its one sanctioned gradient finally appear together.*
|
||||
|
||||
*Next: [Variables and templating](/prompting/variables-and-templating) — turn the brand tokens that repeat across a series into named slots you fill per render.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Editing existing videos
|
||||
description: "Direct the agent like an editor — trim, move, retime, swap, restyle — with the NLE verb you already know mapped to the prompt that lands it in one pass."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
A [storyboard](/prompting/storyboards)'s frames still get edited, and so does everything else you build — a templated composition, a one-shot scene, all of it. Most HyperFrames time isn't the first render — it's the twenty edits after it. A composition is plain HTML with `data-*` timing attributes and a GSAP timeline, so every edit you'd make in a non-linear editor maps to a specific, inspectable change in the source. You don't re-specify the video; you name the edit the way you'd say it to a human editor, and the agent makes the smallest change that does it.
|
||||
|
||||
This page maps the editor verbs to the prompts that land them. The examples name elements from a typical composition — swap the noun ("the lower third", "scene 2") for whatever yours is called. Two habits from [Iterating](/prompting/iterating) apply to every one of them, so keep them in mind: **change one thing per render**, and **state targets as absolute values** ("scene 2 = 2 seconds", not "a bit shorter") so the agent lands it in a single pass instead of oscillating.
|
||||
@@ -21,7 +23,7 @@ Every timeline verb resolves to a `data-*` attribute or an inline style. This is
|
||||
| "the audio bed is too loud" | Level | `data-volume` |
|
||||
|
||||
<Note>
|
||||
The mental model the Studio timeline uses: **move** changes when a clip *starts*, **right trim** changes when it *ends*, and **front trim** only exists for media clips — a `<video>` or `<audio>` can skip into its own content, but a GSAP-driven `<div>` can't start halfway through its animation. See [Timeline editing](/guides/timeline-editing) for the full clip-type breakdown. One more surface the map can't show: retiming a scene that spans the whole composition also needs the root's `data-duration` bumped — the root governs total length, so a longer child never renders past it.
|
||||
The mental model the Studio timeline uses: **move** changes when a clip *starts*, **right trim** changes when it *ends*, and **front trim** only exists for media clips — a `<video>` or `<audio>` can skip into its own content, but a GSAP-driven `<div>` can't start halfway through its animation. See [Studio timeline](/studio/timeline) for the full clip-type breakdown. One more surface the map can't show: retiming a scene that spans the whole composition also needs the root's `data-duration` bumped — the root governs total length, so a longer child never renders past it.
|
||||
</Note>
|
||||
|
||||
## Trim, move, and restack
|
||||
@@ -39,10 +41,18 @@ Bound moves by the composition's length — a 4-second clip moved to 0:08 in a 1
|
||||
- ❌ `tighten up the opening`
|
||||
- ✅ `intro clip duration = 3s; leave its animation and position alone` — one attribute, and the freeze clause stops a rebuild from drifting on axes you'd already settled
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-before.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Editing Before"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-before.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Before — the untouched composition.*
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-after.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Editing After"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/editing-after.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*After — four verbatim edits from this page (move, right-trim, retime, restyle-with-freeze); each touched exactly the attribute the verb map promises, gates green after every edit.*
|
||||
|
||||
|
||||
@@ -64,7 +74,7 @@ Retiming starts with the scene's `data-duration`. If the motion should keep its
|
||||
- ✅ `scene 2 duration = 4s, same motion, add the extra time as a hold at the end`
|
||||
|
||||
<Warning>
|
||||
Render duration comes from `data-duration`, not GSAP timeline length. Do not pad a timeline with an empty `tl.set({}, {}, <seconds>)` sentinel. If a scene still ends early, check the scene and composition timing attributes in the [Video editor cheatsheet](/guides/video-editor-cheatsheet#timing-cheatsheet).
|
||||
Render duration comes from `data-duration`, not GSAP timeline length. Do not pad a timeline with an empty `tl.set({}, {}, <seconds>)` sentinel. If a scene still ends early, check the scene and composition timing attributes in [Data attributes](/concepts/data-attributes).
|
||||
</Warning>
|
||||
|
||||
## Make it snappier (retiming *feel*, not just duration)
|
||||
@@ -85,7 +95,7 @@ Individual animation properties are editable — the value, the ease, the timing
|
||||
|
||||
> Give the add-to-cart item an arc instead of a straight diagonal, like it's being tossed into the cart.
|
||||
|
||||
State the property target absolutely (`Move X = 40`, `arc curviness ≈ 1.5`). [Keyframes & arc motion](/guides/keyframes) covers what's editable, arc-motion paths, and gesture recording.
|
||||
State the property target absolutely (`Move X = 40`, `arc curviness ≈ 1.5`). [Animation and keyframes](/studio/animation) covers what's editable, motion paths, and gesture recording.
|
||||
|
||||
<Tip>
|
||||
For an element-specific edit, the Design Panel's clipboard icon copies structured context — the element's id, position, size, and current animation — ready to paste into your prompt. It gives the agent exact spatial context instead of a vague "the title."
|
||||
@@ -125,8 +135,8 @@ Visual tweaks — color, size, weight, position of a single element — are wher
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Iterating" href="/prompting/iterating">One variable per edit, absolute targets, freeze what works</Card>
|
||||
<Card title="Vocabulary" href="/prompting/vocabulary">Pacing and easing words that retime the *feel* of a scene</Card>
|
||||
<Card title="Timeline editing" href="/guides/timeline-editing">Which edits the Studio timeline persists, and how</Card>
|
||||
<Card title="Video editor cheatsheet" href="/guides/video-editor-cheatsheet">The `data-*` attributes as timeline controls</Card>
|
||||
<Card title="Studio timeline" href="/studio/timeline">Move, trim, split, and navigate clips</Card>
|
||||
<Card title="Data attributes" href="/concepts/data-attributes">The `data-*` timing contract</Card>
|
||||
</CardGroup>
|
||||
|
||||
*Next: [Iterating](/prompting/iterating) — the discipline behind every edit on this page: one variable per render, absolute targets, freeze what works.*
|
||||
|
||||
+112
-18
@@ -3,6 +3,8 @@ title: Verified example prompts
|
||||
description: "Copy-paste prompts, every one run end-to-end to a finished video that passes check."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
This is the level's gallery, not a new lesson — read these with the vocabulary you just picked up: the [six-part skeleton](/prompting/anatomy), the [specification dial](/prompting/specification-dial), and the [word list](/prompting/vocabulary) or [full visual spec](/prompting/visual-specs) it maps to. Spot the skeleton parts in each prompt below as you read it.
|
||||
|
||||
Every prompt below has been run end-to-end and one-shots a finished video that passes `check`. Swap the copy, colors, and inputs for your own.
|
||||
@@ -16,44 +18,85 @@ Every prompt below has been run end-to-end and one-shots a finished video that p
|
||||
<AccordionGroup>
|
||||
<Accordion title="Stat count-up">
|
||||
> /motion-graphics 6-second 1920x1080 video, dark navy background. Beat 1 (0-1s): label "ARR" fades up small, top-center. Beat 2 (1-4s): a giant number counts up to $4.2M with an odometer roll, easing out as it lands. Beat 3 (4-6s): "+312% YoY" stamps in below in green, then everything settles into a gentle ambient idle (subtle breathing scale, slow particle drift). Use the `apple-money-count` registry block as base. No narration. **Spectacle beat:** On the land at 4s, a burst of ~60 paper money notes erupts from behind the numeral and flutters down, seeded so every render is identical, settled by 5.5s — the one exaggeration.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Stat Countup"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Animated social post">
|
||||
> /motion-graphics 7-second 1080x1350 vertical video. A real tweet card (handle @hyperframes, text "we render video from HTML now. no timeline UI. just code.") slides up over a soft animated gradient, likes counter ticks 0→1.2K, then the card tilts in 3D and a highlight sweeps the second sentence. Hold on the card at the end. Use the `x-post` and `vfx-liquid-background` registry blocks. No narration, no image or media files. **Spectacle beat:** When the like count lands, the heart pops to 1.6× with a radial burst of ~24 seeded particles and settles — one moment, nothing else exaggerated.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-tweet.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Tweet"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-tweet.mp4#t=0.1"
|
||||
portrait
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Map route">
|
||||
> /motion-graphics 8-second 1920x1080 video. Dark world map, a glowing arc animates from San Francisco to Tokyo over 3s, destination pin drops with a pulse, then camera zooms into Tokyo and the label "LATENCY: 89ms" types on. Use the `nyc-paris-flight` registry block as the base pattern, restyle to teal on charcoal. No narration. **Spectacle beat:** The destination pin's landing fires a triple concentric shockwave that expands past the label and fades, with a brief chromatic split on the pin.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-map-route.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Map Route"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-map-route.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Logo sting with shader transition">
|
||||
> /motion-graphics 5-second 1920x1080 logo sting. Beat 1 (0-2s): the word "ACME" assembles from scattered particles. Beat 2 (2-3s): full-frame `swirl-vortex` shader transition. Beat 3 (3-5s): logo lockup + tagline "Ship faster." settles on white, holds. Use `code-particle-assemble` for the assembly. **Spectacle beat:** The particle assembly IS the spectacle — ~1200 seeded particles converging with visible motion trails, and a single bloom flash on the frame the wordmark completes.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-logo-sting.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Logo Sting"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-logo-sting.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Product launch from a URL">
|
||||
> /product-launch-video Make a 45-second 1920x1080 launch video for https://linear.app. Energetic but minimal, use the site's own palette and screenshots. Structure: hook stating the problem, 3 feature beats with UI captures and one-line captions, end card with logo + "Try it free". Female TTS voice, confident tone, subtle electronic BGM under -18dB. **Spectacle beat:** One exaggerated moment: the end card's logo lands with a bloom flash and a fast light-sweep across the wordmark. Feature beats stay restrained.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Product Launch"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Explainer from pasted text">
|
||||
> /faceless-explainer Turn this into a ~60-second 1080x1920 vertical explainer: [paste your text]. One idea per scene, big typography, diagrams over stock footage, brand color #FF5533 on off-black. Male TTS voice, calm. Embedded captions, keywords highlighted in the brand color. **Spectacle beat:** One exaggerated moment: the final CTA's key phrase slams in at 1.5× with a chromatic split that resolves in 0.2s. Every other scene stays typographically calm.
|
||||
|
||||
With a verbatim script, final duration follows the narration — ask for "~60 seconds", not exactly 60.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Explainer"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4#t=0.1"
|
||||
portrait
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="GitHub PR reveal">
|
||||
> /pr-to-video Make a 30-second 1920x1080 feature-reveal video from [PR URL]. Lead with what users get, not the diff; show the key code change with the `code-diff` block for one beat only; end on version number + repo URL. No narration, kinetic captions instead. **Spectacle beat:** The added line in the diff ignites — a green light-sweep travels its length and the line blooms as the camera settles on it.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Pr Video"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-pr-video.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Beat-synced slideshow">
|
||||
> /music-to-video 20-second 1080x1080 video. Resolve a dark, driving electronic track and cut to its analyzed beat grid — one image per bar, punch-in on downbeats, whip-pan transitions on phrase changes. Generate the eight images rather than using stock: brutalist concrete details as high-contrast monochrome abstracts, one consistent visual language across all eight, each carrying a single cyan light thread. Chrome: a `PLATE 0N/08` counter. End card "CAST IN PLACE" in condensed caps over a hard-edged opaque scrim, with the sub-line "EIGHT SURFACES · ONE HUNDRED BPM". No TTS. **Spectacle beat:** On the loudest downbeat, one image punches to 1.25× with an RGB channel split that snaps back on the next beat. The other cuts stay clean.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Music Slideshow"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@@ -63,52 +106,103 @@ Every prompt below has been run end-to-end and one-shots a finished video that p
|
||||
<AccordionGroup>
|
||||
<Accordion title="Kinetic quote">
|
||||
> 12-second 1920x1080 video, off-white background. The quote "Simplicity is the ultimate sophistication" builds word by word in massive black serif type, each word snapping in with a slight overshoot; "sophistication" lands last in italic with a hand-drawn underline drawing on. Attribution "— Leonardo da Vinci" fades in small, bottom-right, at 9s. Settle into a barely-visible ambient idle to the end. No audio. **Spectacle beat:** The final word lands 1.4× oversized with an ink-bleed bloom before settling to its true size — the sentence's payoff.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-kinetic-quote.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Kinetic Quote"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-kinetic-quote.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Countdown title card">
|
||||
> 6-second 1920x1080 video. Numbers 3, 2, 1 each fill the frame for one second — each number wipes in with a diagonal mask and its background alternates black/white with inverted text. At 3s the frame slams to "LAUNCH DAY" in condensed caps with a screen-shake, holds with a subtle grain flicker. No audio. **Spectacle beat:** The frame snap at 3s is the moment — a hard white flash frame and a 1.5° rotation kick settling in 0.25s.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-countdown.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Countdown"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-countdown.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Bar chart race">
|
||||
> 10-second 1920x1080 video, dark slate background. Title "Top languages 2026" top-left. Five horizontal bars (Python, TypeScript, Rust, Go, Java) grow from zero with staggered starts, overtaking each other twice mid-animation; each bar has a right-edge value label counting up to its final %. End state holds 2s with the leader pulsing once. Hand-draw everything — no chart library. No audio. **Spectacle beat:** The leader's single end pulse is the moment — a +16px overshoot and a bright cap flare, returning to rest exactly on the last frame.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-bar-race.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Bar Race"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-bar-race.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Before / after split">
|
||||
> 8-second 1920x1080 video. Vertical split: left half labeled "BEFORE" shows a cluttered mock UI (grey, 12 overlapping windows drawn in CSS), right half "AFTER" shows one clean card. Both halves settle within the first second. A vertical divider line sweeps left to right at 4s, wiping the clutter into the clean state across the full frame. End on "One tool." centered. No audio. **Spectacle beat:** The divider's wipe is the moment — a bright scan-line travels the split with a bloom as it crosses, and the AFTER half resolves behind it.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-before-after.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Before After"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-before-after.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Loader → reveal">
|
||||
> 7-second 1920x1080 video, black background. A thin white progress ring draws from 0° to 360° over 4s while a percentage counter (0→100) ticks in the center in mono type, matching the arc exactly. Ring and counter fade out fully by 4.2s; at 4.2s the ring bursts outward into short radial dashes and "READY." stamps into the center, then holds. No audio. **Spectacle beat:** The ring's completion at 100% detonates — it flashes white, expands past frame, and the reveal rides that expansion out.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-loader-ready.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Loader Ready"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-loader-ready.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="3D cards (Three.js)">
|
||||
> 9-second 1920x1080 video, light warm cream background. Build the scene in Three.js via the adapter: three rounded card meshes labeled "Design", "Build", "Ship" lie flat on the ground plane, camera at a fixed 3/4 isometric angle, soft directional light + ambient so the cards cast soft shadows. One at a time each card lifts and straightens upright to face the viewer center-frame while the other two slide apart and dim; then it returns. Finish with all three standing upright in a row by 8.5s, hold. All easing power3.inOut. No audio. **Spectacle beat:** As the cards rise into their stack, a single specular sweep rakes across all three faces in sequence, catching each edge.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example 3d Cards"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="SVG line-draw logo reveal">
|
||||
> 6-second 1920x1080 video, deep green background. A minimal mountain-range logo draws on as an SVG stroke over 2.5s, then the stroke fills with cream, the wordmark "NORTHTRAIL" letterspaces in beneath it, and a thin rule expands from center. Hold the last 1.5s. No audio. **Spectacle beat:** The stroke's completion is the moment — the drawn path flares once along its whole length, then the fill floods from that flare.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-svg-logo.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Svg Logo"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-svg-logo.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Word-swap headline">
|
||||
> 8-second 1920x1080 video, white background. Static sentence "Make it ___." in huge black type stays centered while the blank cycles through "faster", "simpler", "yours" — each swap flips vertically like a split-flap board, 1.5s apart, with a slight blur on motion. Final word "yours." lands in orange and the period pops. No audio. **Spectacle beat:** The last swap lands hardest — that word arrives 1.3× behind a motion-blur streak that resolves as it settles.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-word-swap.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Word Swap"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-word-swap.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Stat tile dashboard">
|
||||
> 10-second 1920x1080 video, near-black background. Four stat tiles slide up in a 2x2 grid, staggered: "99.99% uptime", "42ms p50", "18M req/day", "0 incidents". Each tile's number counts or decrements to its value with its own easing; sparklines draw underneath in teal. At 8s the grid scales back and "Built to hold." fades in above. No audio. **Spectacle beat:** When the fourth tile lands, all four numerals flare in unison for three frames — one synchronized accent, then back to restrained idles.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-data-ticker.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Data Ticker"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-data-ticker.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
<Accordion title="Vertical social hook">
|
||||
> 9-second 1080x1920 vertical video, charcoal background. Social-style hook: "nobody talks about this" types on center in bold white, then each following phrase replaces it on a hard cut every 1.5s — "it's not your code", "it's your prompts", "here's the fix" — with yellow highlight bars behind key words, alternating tilt. Last phrase holds with an arrow-down bounce. No audio. **Spectacle beat:** The final phrase is the payoff — it slams in at 1.35× with a three-frame shake and a chromatic split that resolves fast.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-vertical-hook.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Vertical Hook"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-vertical-hook.mp4#t=0.1"
|
||||
portrait
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Explainers
|
||||
description: "What to say to turn an article, notes, or a topic into a faceless explainer — where every visual is invented, not captured."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
The last ride pointed a workflow at a website. This one drops the site entirely — arbitrary text is the whole input, and every visual downstream is invented rather than captured.
|
||||
|
||||
## Your first win
|
||||
@@ -13,7 +15,12 @@ Verified, from the [examples](/prompting/examples) page — a ~60-second vertica
|
||||
|
||||
> /faceless-explainer Turn this into a ~60-second 1080x1920 vertical explainer: [paste your text]. One idea per scene, big typography, diagrams over stock footage, brand color #FF5533 on off-black. Male TTS voice, calm. Embedded captions, keywords highlighted in the brand color.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Explainer"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-explainer.mp4#t=0.1"
|
||||
portrait
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -51,7 +58,11 @@ What you can already steer from the prompt, before you've learned any technique.
|
||||
|
||||
Shorter runtime, landscape for YouTube / embed. Fewer scenes means the topic has to compress — naming the takeaway tells the workflow what to keep.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-explainer-landscape.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Variant Explainer Landscape"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-explainer-landscape.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from this prompt with the topic swapped to HTTP caching (cache diagram as the metaphor), unedited — 26s, because the narration sets the length.*
|
||||
|
||||
</Accordion>
|
||||
|
||||
@@ -3,6 +3,8 @@ title: When to generate artwork
|
||||
description: "Code-drawn wins for UI, type, geometry, and 3D; illustration-led hero art comes from an image model, animated as layers."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Your Level 1 music slideshow cut real photos to the beat — there was real art to work with. This chapter is for the opposite case: a hero character, a painterly scene, sculptural objects that don't exist as a photo or a footage capture yet.
|
||||
|
||||
Code-drawn HTML/CSS/SVG excels where the medium is native: UI mockups, typography, geometric shapes, charts, pixel art, and 3D via Three.js. For **illustration-led** hero art — characters, painterly scenes, sculptural objects — hand-drawn SVG tops out at clipart quality no matter how well you prompt. The fix is a hybrid:
|
||||
@@ -19,10 +21,18 @@ Three rules that make this work:
|
||||
|
||||
The same brief — four people arm in arm, warm gradient sweaters, flat-illustration style — built both ways. Same animation beats, same craft layer (lighting, atmosphere, grade); the only variable is where the figures came from.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-hand-drawn.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Artwork Hand Drawn"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-hand-drawn.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Hand-drawn SVG figures — clean, but the proportions and gesture read as clipart.*
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-generated.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Artwork Generated"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/artwork-generated.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Generated illustration animated as layers — real anatomy and editorial shading; the animated line still passes behind the figures because the artwork was keyed to transparency.*
|
||||
|
||||
<Note>
|
||||
@@ -33,7 +43,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> […] over a **generated-artwork backdrop** — a flat abstract mural evoking motion trails, generated **palette-neutral (grayscale) and duotoned live by CSS** from the two variables so it re-skins with everything else. **The mural is a full-frame, screen-fixed backdrop: it never moves on screen — the widening iris circle alone reveals it already in place at full frame […] and it exits by fading out.**
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Surface"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Color grading and film effects](/prompting/color-grading) — treat the media itself: tonal work, hue keys, print and analogue looks, and why the source matters more than the payload.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Media and audio
|
||||
description: "Ask for the voiceover, music, sound, captions, cutouts, and assets a composition needs — with the precise, unambiguous phrasing the media pipeline acts on."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
By now your video moves and reads right; this level gives it a voice. HyperFrames owns media *playback*; a sibling media pipeline resolves everything else — voice, music, sound effects, images, icons, logos, captions, and background removal. You reach all of it by describing what the composition needs, and the agent resolves each need to a frozen local file. The craft here is precision: vague media asks ("add some music," "no sound") are the ones that come back wrong, because the pipeline does exactly what the words say.
|
||||
|
||||
## Voiceover (TTS)
|
||||
@@ -96,7 +98,11 @@ None of this changes how you phrase the ask: name the footage by path like any o
|
||||
|
||||
> Build a short picture-in-picture piece from `source-hevc.mp4` — inset it bottom-right over a full-bleed background scene, with a soft rounded border.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/proxy-footage.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Proxy Footage"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/proxy-footage.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — the source clip is a plain H.265/HEVC file; render decoded it directly via FFmpeg, while preview would have used the automatic H.264 proxy.*
|
||||
|
||||
See the [Rendering guide](/guides/rendering#input-video-codecs) for the mechanics — proxy generation, caching, and which codecs it covers.
|
||||
@@ -136,7 +142,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> […] a real talking-head clip (generate a short clip of a person speaking one neutral line via the media pipeline's avatar video generation […] **transcode it to HEVC `hvc1`** so the automatic proxy subsystem carries preview) sits as a clip on the wire. The order of operations IS the story: as the camera arrives and BEFORE the person speaks, the framework mattes the footage — **the background peels away via background removal** […] THEN they speak, and the main **keywords of their own line — derived from the clip's transcription — land word-synced** […] The clip's own audio ducks the BGM briefly; the VO resumes as the camera pulls away.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Material"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Design systems and brand](/prompting/design-systems) — pointing the agent at a source of brand truth instead of describing a vibe.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Motion graphics
|
||||
description: "Short, design-led pieces where motion is the message — kinetic type, a stat hit, a logo sting — and the knobs that decide MP4 versus transparent overlay."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Five rides in, five different inputs — a site, plain text, a PR, footage, a track. This last one drops narration and asset input altogether: a short, design-led motion graphic where motion alone carries the message.
|
||||
|
||||
## Your first win
|
||||
@@ -13,7 +15,11 @@ The canonical shape: routed, spec'd, beat-timestamped, copy quoted, technique pi
|
||||
|
||||
> /motion-graphics Make an 8-second 1920x1080 video. Beat 1 (0-4s): dark macOS terminal types "npx skills add heygen-com/hyperframes" character by character, then hold on the blinking cursor. Beat 2 (4-5s): the terminal shatters into fragments. Beat 3 (5-8s): bold white kinetic text on black slams in word by word, snappy: "YOU JUST MADE THIS / WITH HYPERFRAMES." Adapt the `code-typing` and `vfx-shatter` registry blocks; hand-author the kinetic text. No narration, no image or media files.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Anatomy Terminal"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-anatomy-terminal.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
|
||||
+62
-12
@@ -3,6 +3,8 @@ title: Motion that reads premium
|
||||
description: "Eight motion-grammar rules from frame-by-frame study of professional work — nothing stops, the camera acts, action overlaps, imperfection stays reproducible."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
By now you can specify a frame precisely — exact copy, exact colors, exact layout, exact timing. This level makes it move. But "make it move" is the wrong instruction, and it is worth understanding why before you write a single motion clause.
|
||||
|
||||
## Motion is a claim, not a coat of paint
|
||||
@@ -59,7 +61,11 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> 6-second 1920x1080 live telemetry panel: an `ARR · LIVE` eyebrow with a status dot, `PROD · US-EAST-1` opposite, `$4.200M` at display scale with a delta chip, a sparkline of the reading history beneath, and a footer row reading `LAST SYNC` and `READINGS`. The panel rises in and lands by 1.9s, then stays alive because the feed is — a new reading arrives every 300ms and each one moves exactly what it should: the last digits change, the sparkline extends one segment with its leading dot, `LAST SYNC` restamps, `READINGS` increments. The status dot keeps a 1s heartbeat because the connection is up. Nothing else moves. Fix the sparkline's y-scale up front so an arriving reading never rescales the axis.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule1-nothing-stops.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule1 Nothing Stops"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule1-nothing-stops.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — from 2.0s the left's 120 remaining frames share a single hash; all 180 of the right's are distinct. Every movement on the right answers "because": the dot beats because the connection is up, the digits change because a reading arrived, the sparkline extends because that reading is now history. That's the test — not "is there enough motion" but "can each thing that moves say why".*
|
||||
|
||||
*The clearest artifact is the footer. The frozen half reads `LAST SYNC 09:41:21.75 · READINGS 22` while the live one reads `09:41:23.95 · 30`. A still frame of the left half looks like a perfectly good stat card; the moment it sits next to a running one you can read exactly how long the feed has been dead. That is what a frozen hold communicates to a viewer, whether or not you meant it.*
|
||||
@@ -74,7 +80,11 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> …an isometric deploy pipeline of five stages, each with its own accent colour — `SOURCE` mint, `BUILD` cyan, `TEST` violet, `DEPLOY` amber, `EDGE` rose — bolted along a rail with support posts and numbered floor bays. The block at each stage and its card wear the same colour. Lay the stages out where they really are, 640px apart across 2.5 frame widths, and **move the camera** across the whole run in one continuous linear pass, `ease: none`. The floor and rail travel with the camera 1:1 because they are the same space; distant structures track at a fifth. A packet of work runs the wire and ignites each stage in its colour as it reaches it, so a stage is revealed by arriving at it rather than by appearing.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule2-camera-actor-v2.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule2 Camera Actor V2"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule2-camera-actor-v2.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — same five stages, same colours, same six seconds. On the left the block never leaves the centre of frame: five stages, one place. On the right you travel to each one, and neighbours stay visible on the way, so the five read as five points along a single run.*
|
||||
|
||||
*The rule is usually stated as "give every scene a camera move," which undersells it. The real claim is about what a **cut throws away**. A move carries the spatial relationship between two shots; a cross-fade carries none, so the colour simply becomes a different colour where it stood. Watch the amber `DEPLOY` block still sitting behind frame-left as the camera settles on rose `EDGE` — that adjacency is information, and it does not survive a dissolve.*
|
||||
@@ -91,7 +101,11 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> …`Rolling out to every region` over a dotted world map with twelve edge regions marked and a live `n / 12` tally. A progressive rollout spreads outward from `us-east-1`, reaching each region in order of its distance from the origin, 0.09s apart: a link draws from the nearest already-live region and lands exactly as that region's core ignites, its dot field turns mint, a ping carries onward and an ACK dash returns up the link. Each region's 0.5s ignite is still running when the next three begin.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule3-overlapping-action.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule3 Overlapping Action"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule3-overlapping-action.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — twelve distinct ignition frames on the right, 0.088s apart, against a single frame on the left. At peak, all twelve regions are animating at once.*
|
||||
|
||||
*Stagger here isn't a styling preference, it's the difference between a true statement and a false one. A rollout propagates; twelve regions cannot go live on the same frame, and the simultaneous version says something about the system that isn't true. Watch the tally: the left jumps `0 → 12` in one frame and the map gives you no way to tell where the rollout started, because there is no order to read. Note also what is **not** staggered — the twelve region markers all appear on the same frame in both halves, because the regions already existed. Stagger what is happening, not what is merely present.*
|
||||
@@ -106,7 +120,11 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> …an itemized coffee-shop receipt; a payment-confirmation sheet rises 470px over 1.2s to cover its lower half while fading up from 0. Rotation, scale and blur are never touched. The receipt dims behind it. The sequence plays twice.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule4-compound-properties.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule4 Compound Properties"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule4-compound-properties.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — identical travel (470px), identical window (0.25s → 1.45s), identical ease. The only difference is how many properties ride along. Both halves are pixel-identical at rest, so everything you see mid-flight is the cost of the extra three. On the left, "Payment confirmed" is an unreadable tilted smear for most of its arrival; on the right it is legible the whole way up. Two properties agreeing on one claim — this is arriving — beat four properties each making a different one.*
|
||||
|
||||
### Rule 5 — Overshoot and follow-through
|
||||
@@ -119,7 +137,11 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> …a bolted airport departure board, `HF 402 · SAN FRANCISCO`, its split-flap gate cells riffling to **42**. The flap plates drop 34px and rotate from −16° on `back.out(5)`, swinging past their rest position and settling back; the housing recoils ~7px when they land, and each plate's cast shadow reaches its own peak one frame later than the plate that casts it. Transforms only — the gate number never overshoots **42**. The sequence plays twice.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule5-overshoot.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule5 Overshoot"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule5-overshoot.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — the right's plates swing 1.51× past their travel before settling; every transform on the left has peak == final. The shadow's lag is measured at 0.033s, exactly one frame at 30fps. Note the one thing that does **not** overshoot on either side: the number itself tops out at 42 and stays there. Overshoot is a claim about mass, and a value has none — a counter that flies to 47 and falls back is reporting a number that was never true.*
|
||||
|
||||
### Rule 6 — Depth planes
|
||||
@@ -132,7 +154,11 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> …a render-farm corridor: CSS-3D floor and ceiling converging on a single vanishing point, a bank of server racks with blinking status LEDs, a distant rack row near the horizon, and one rack column close to the lens. `CLUSTER 04 · WEST / Every frame, in parallel.` on a camera-locked HUD panel. The camera trucks forward for the full 6s and each plane drifts at its own distance: the horizon row at a fifth of the room's rate, the room and its racks at full rate, and the near column sweeping past at six times — `blur(22px)`, close enough to cross in front of the headline. Haze the far plane slightly.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule6-depth-planes.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule6 Depth Planes"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule6-depth-planes.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — measured travel ratios on the right are exactly 0.20× / 1.00× / 6.00×; on the left all five planes displace an identical 240px with `filter: none`. The strongest cue isn't the blur, it's the occlusion: the near column crosses in front of the headline for about a third of the shot, which is only possible if it's in the room. One foreground element does this — a second would just be clutter with a blur on it.*
|
||||
|
||||
### Rule 7 — Match pacing to genre
|
||||
@@ -145,7 +171,11 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> …a three-beat product showreel, each beat a titled panel with its own live evidence: `SEEK ANY FRAME` over a scrubbing timeline reading out frame 147, `RENDER ON LAMBDA` over six worker lanes filling their own frame ranges, `SHIP THE MP4` over a player with an encode bar. Showreel pace — 1.1 seconds per beat, cutting hard rather than dissolving, all three delivered by 3.3s, then hold the last beat on a live idle. A rail under each half tracks time consumed and time spare.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule7-pacing.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule7 Pacing"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule7-pacing.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — same three ideas, same evidence, same 6 seconds. At 3.6s the left is still working through beat 2 with `SPARE 0.00`; the right has already delivered all three and banked `+0.33s`. The left is not badly animated, it is correctly animated at the wrong tempo — which is why this failure survives review so often. Pace is a genre decision you make before you touch an ease.*
|
||||
|
||||
### Rule 8 — Handmade imperfection stays reproducible
|
||||
@@ -158,17 +188,29 @@ Each subject is chosen so the rule is *unavoidable* given the content: a live fe
|
||||
|
||||
> …a hanging paper mobile: five cut-paper shapes on fine visible wires from a wooden dowel, each with real paper grain, irregular hand-cut edges and its own layered drop shadow. They sway through the same ±12° arc, but driven by a mulberry32 PRNG seeded once at composition start and stepped on a two-frame hold quantized to the integer frame index — so the cadence is stop-motion, not a tween, and every render is byte-identical. A readout shows the current frame and how many distinct states the six seconds contain.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule8-seeded-handmade.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Rule8 Seeded Handmade"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-rule8-seeded-handmade.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Left `WITHOUT`, right `WITH` — the right holds each pose for exactly two frames: 90 states across 180 frames, no irregular holds, while the left has 180 distinct ones. Rendered twice, the whole thing came back byte-identical both times. This is the rule that is easy to get wrong in the wrong direction — reaching for `Math.random()` to buy the same irregularity produces a composition that renders differently every time and can never be re-rendered or resumed.*
|
||||
|
||||
## The grammar, measured
|
||||
|
||||
The same composition built twice — identical content, identical layout; the only variable is the motion treatment. The first build commits the anti-patterns above: simultaneous identical entrances, no camera, a frozen final 2.4 seconds. The second applies the eight rules.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-before.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Before"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-before.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Every anti-pattern: tiles enter together, nothing overlaps, the last seconds are a freeze-frame.*
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-after.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion After"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-after.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The eight rules: staggered overshoot entrances, a continuous 5% push, ambient idle, a blurred foreground plane, sparkline draw-ins as secondary motion.*
|
||||
|
||||
The difference is measurable, not just visible: in the final second the frozen build has bit-identical consecutive frames, while the motion-grammar build changes every single frame — corroborated by the encoder (211KB vs 2.5MB for the same content). A frozen final second is the cheap-motion tell you can test for.
|
||||
@@ -200,7 +242,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> ONE continuous camera journey with a dwell-and-sweep rhythm. The whole film is a single wide world (one large scene space) that the camera dollies across […] in one unbroken move with NO hard cuts anywhere except inside the two sanctioned seam moments named below. The rhythm: the camera SWEEPS between regions, then eases to a genuine REST at each region's hero moment — a full stop of roughly 1.5–2.5 seconds while the main point lands […] then accelerates away. The dwell is what gives the sweep meaning: without the rest, emphasis dies mid-motion. During a dwell the WORLD keeps resolving (counters tick, labels stamp, secondary motion continues) — the camera rests, the film never freezes.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-camera.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Camera"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-camera.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered: accelerating out of one region, arriving in the next, stopping to let the beat land — no cut anywhere in the span.*
|
||||
|
||||
This method is expensive. One continuous space is more to author than a cut, and it only pays when the piece has a through-line worth following. For a 6-second stat card, cut.
|
||||
@@ -226,7 +272,11 @@ Rule 1's ambient idle is *continuous* — a slow, smooth breathing scale. Rule 8
|
||||
|
||||
> A paper-cutout garden scene: flowers, leaves, and a bee drifting on visible wires, like stop-motion. Seed a random offset per element at the start (same seed every render) so each leaf sways to a slightly different rhythm, but hold each position for exactly two frames before stepping to the next — discrete jumps, not a smooth tween. It should read as intentionally handmade, not glitchy.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-handmade.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Motion Handmade"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/motion-handmade.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — paper cutouts on visible wires, every position held for exactly two frames, and byte-identical across two separate renders.*
|
||||
|
||||
Name the seed and the hold length explicitly — "seeded" and "two-frame hold" are the two words that keep an agent from reaching for `Math.random()` and quietly breaking every re-render.
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Music videos and slideshows
|
||||
description: "Two music- and slide-driven outputs that look alike in a brief but ship differently — a beat-synced MP4 versus a navigable deck — and how to route to the right one."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
You've dressed footage and turned a PR into a story — now the driving input changes again: a track's own beat, or a deck of slides, sets the pace instead of a script.
|
||||
|
||||
## Your first win
|
||||
@@ -13,7 +15,11 @@ The verified starting point: photos cut to a track, exported to a square MP4.
|
||||
|
||||
> /music-to-video 20-second 1080x1080 video from ./track.mp3 (pick the best 20 seconds of the track) and the 8 photos in ./shots/. Cut on the beat grid, one photo per bar, punch-in on downbeats, `whip-pan` transitions on phrase changes. End on the last photo with "SUMMER '26" in condensed caps. No TTS.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Music Slideshow"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-music-slideshow.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -88,7 +94,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> **Rhythm (45–52s).** The wire becomes a waveform: **resolve the BGM first, run `hyperframes beats` on it, and drive this region on the detected grid** — the waveform pulses and compact media cards (a lyric line, a photo card, a chart flash) snap onto the wire on real analyzed beats while the camera keeps traveling; each snap gets a tick SFX. At least six beat-hits. SANCTIONED SEAM #2: the beat-hits may hard-cut card content ON the beat — the sanctioned exception, because the camera itself never stops moving through them.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-rhythm.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Rhythm"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-rhythm.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Motion graphics](/prompting/motion-graphics) — the shortest one yet, a single motion graphic where motion alone is the message.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Overlays and lower thirds
|
||||
description: "Prompt named lower-third and social-post overlay blocks with timing, copy, and brand tone."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Level 1's founder-clip.mp4 got named lower-thirds and card overlays through `/talking-head-recut`, which designs bespoke cards synced to that specific transcript. This chapter is the reverse case: ready-made lower-third and social-overlay blocks you drop into a composition you're building from scratch, no existing footage required — the same vocabulary, pointed at a scene instead of a shot.
|
||||
|
||||
## What overlays do and when they trigger
|
||||
@@ -51,7 +53,11 @@ Quote the exact copy — unquoted names and titles get paraphrased (see [anatomy
|
||||
|
||||
> Add a lower third at 0:03 for 5 seconds, on a track above the footage, with [`lt-clean-bar`](/catalog/blocks/lt-clean-bar). Name: "Dana Ríos". Title: "Head of Design".
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-lower-third.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Lower Third"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-lower-third.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above over stand-in footage, unedited.*
|
||||
|
||||
|
||||
@@ -63,13 +69,22 @@ Quote the exact copy — unquoted names and titles get paraphrased (see [anatomy
|
||||
|
||||
> During the intro, show an [`x-post`](/catalog/blocks/x-post) card with the quote "we shipped it in a weekend" and 12.4K likes, then slide it out before the demo.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-xpost.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Overlay Xpost"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-xpost.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above over stand-in scenes, unedited — the card's built-in like-tap ticks 12.4K → 12.5K.*
|
||||
|
||||
|
||||
> /motion-graphics Transparent overlay only — a [`spotify-card`](/catalog/blocks/spotify-card) now-playing widget animating in, bottom-left. Export as transparent WebM so I can drop it over footage in my editor.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Overlay Spotify Preview"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4#t=0.1"
|
||||
portrait
|
||||
loop
|
||||
/>
|
||||
*MP4 preview of the transparent WebM over a checkerboard — the delivered file carries real VP9 alpha (verified via ALPHA_MODE + alphaextract).*
|
||||
|
||||
|
||||
@@ -112,7 +127,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> […] as the camera arrives and BEFORE the person speaks, the framework mattes the footage — **the background peels away via background removal**, sliding off along the travel direction and leaving the cutout standing alone on the brand ground. […] A designed lower-third chip renders behind the subject.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Material"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-material.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Caption styles](/prompting/captions-catalog) — the same timed-block pattern, tuned to on-screen text instead of name cards and social replicas.*
|
||||
|
||||
@@ -3,7 +3,13 @@ title: Prompt Guide
|
||||
description: "How to prompt AI agents to author HyperFrames videos — setup, the two prompt shapes, and the map of this guide."
|
||||
---
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Timeline Default"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-timeline-default.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*By the end of this guide, you can build this with a prompt.*
|
||||
|
||||
HyperFrames is built for AI agents — compositions are plain HTML, the CLI is non-interactive, and the framework ships [skills](https://github.com/vercel-labs/skills) that teach agents the patterns docs alone don't cover. This guide shows how to prompt agents effectively once skills are installed — the vocabulary that changes output, the iteration patterns that save time, and the rules that prevent breakage.
|
||||
@@ -147,17 +153,29 @@ Three prompts from this guide and their unedited renders — one workflow warm s
|
||||
|
||||
> /product-launch-video Make a 45-second 1920x1080 launch video for https://linear.app. Energetic but minimal, use the site's own palette and screenshots. Structure: hook stating the problem, 3 feature beats with UI captures and one-line captions, end card with logo + "Try it free". Female TTS voice, confident tone, subtle electronic BGM under -18dB.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Product Launch"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
> /motion-graphics 6-second 1920x1080 video, dark navy background. Beat 1 (0-1s): label "ARR" fades up small, top-center. Beat 2 (1-4s): a giant number counts up to $4.2M with an odometer roll, easing out as it lands. Beat 3 (4-6s): "+312% YoY" stamps in below in green, then everything settles into a gentle ambient idle. Use the `apple-money-count` registry block as base. No narration.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Stat Countup"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-stat-countup.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
And at the far end of the [specification dial](/prompting/specification-dial), a full visual+motion spec one-shots a broadcast-style animated globe — see [Recreating something you saw](/prompting/recreating-references) for the spec:
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Recreate Globe Oneshot"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*One-shot render from the distilled spec, no iteration.*
|
||||
|
||||
## Explore the guide
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Product launch videos
|
||||
description: "What to say to turn a product URL, a script, or a brief into a launch or promo video — and when to reach for a site tour instead."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
This is Level 1 of the Prompt Guide: a run of one-prompt rides, each handing a workflow a single ask and getting a finished video back. You don't need any technique yet — one sentence describing your product, aimed at the right workflow, is already enough for a first draft.
|
||||
|
||||
## Your first win
|
||||
@@ -13,7 +15,11 @@ Verified, from the [examples](/prompting/examples) page — a 45-second launch f
|
||||
|
||||
> /product-launch-video Make a 45-second 1920x1080 launch video for https://linear.app. Energetic but minimal, use the site's own palette and screenshots. Structure: hook stating the problem, 3 feature beats with UI captures and one-line captions, end card with logo + "Try it free". Female TTS voice, confident tone, subtle electronic BGM under -18dB.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example Product Launch"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-product-launch.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -62,7 +68,11 @@ What you can already steer from the prompt, before you've learned any technique.
|
||||
|
||||
With no URL the workflow takes the no-capture path: no screenshots, no site palette to borrow, so name your brand colors and fonts if you have them (or the agent invents a palette). Verbatim scripts set the duration — figure roughly 130 spoken words per minute, so a 30-second video wants a 65–70 word script. Saying "use it verbatim" pre-answers the workflow's keep-or-restructure question.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-launch-script.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Variant Launch Script"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/variant-launch-script.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from this prompt shape with a different, longer script (78 words, fictional dev-tool "Relay"), unedited — it ran 35.5s because the words set the length.*
|
||||
|
||||
</Accordion>
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Recreating something you saw
|
||||
description: "Transcribe motion, iterate with absolute targets, distill the constants — and know where the text-only ceiling is."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
[Iterating](/prompting/iterating) covered the discipline in general. This page is its hardest test: matching a specific reference you watched rather than a look you're inventing. In practice, matching a specific reference from text alone reaches roughly 90% — but only with a specific workflow, and knowing where the ceiling is. (The percentages on this page are observed results from the guide's own recreation builds, judged frame-against-frame; treat them as the shape of the curve, not a guarantee.)
|
||||
|
||||
## Transcribe motion, not just composition
|
||||
@@ -33,7 +35,12 @@ A distilled spec that one-shots a broadcast-style animated globe:
|
||||
> CAPTION: "Across 82 Countries" — Inter 300, 34px, 0.06em tracking, white at 90%, top-center 12% from the top; left-to-right per-letter fade starting t=1.0s completing ~1.45s, then a slow 6px upward drift still easing at the final frame.
|
||||
>
|
||||
> No audio.
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Recreate Globe Oneshot"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/recreate-globe-oneshot.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The one-shot render produced by this exact spec on a fresh build — no iteration.*
|
||||
</Accordion>
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Rendering and output
|
||||
description: "What to say to get the right file out — quality tier, format, resolution, framerate, and cloud rendering — without over-speccing a render that slows to no benefit."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Everything before this point — including the frame-by-frame matching in [Recreating something you saw](/prompting/recreating-references) — shapes the composition. This page is about the *export*: the words that pick a quality tier, a container format, a resolution, and where the render runs. The defaults — MP4, 1920×1080, 30fps, `standard` quality — are deliberately good, so most of the skill here is knowing when *not* to ask for more. The mechanics live in the [Rendering guide](/guides/rendering); this page owns what to say.
|
||||
|
||||
## Quality tier
|
||||
@@ -41,7 +43,12 @@ Transparency also only *means something* on a design that has empty space to see
|
||||
- ❌ `render my full-screen product promo as a transparent WebM`
|
||||
- ✅ `render the promo as MP4; export just the lower-third overlay as transparent WebM` — transparency belongs to the layer meant to sit *over* other footage, not the finished full-frame film
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Overlay Spotify Preview"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/overlay-spotify-preview.mp4#t=0.1"
|
||||
portrait
|
||||
loop
|
||||
/>
|
||||
*A transparent VP9 WebM overlay previewed over a checkerboard. To verify alpha from the CLI: VP9 stores it out-of-band, so look for ALPHA_MODE=1 in ffprobe (a pix_fmt-only check false-negatives) or extract it with ffmpeg alphaextract.*
|
||||
|
||||
|
||||
@@ -124,7 +131,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> A **seeded confetti burst** fires — mulberry32, **seed 42, each piece holding position for exactly two frames before stepping** (stop-motion feel) — and the VO lands the honest punchline: identical on every render, because determinism is the whole point.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Render"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the seeded confetti, identical on every render of this composition.*
|
||||
|
||||
*Next: [Porting from Remotion](/prompting/remotion-migration) — bringing an existing Remotion project into everything you now know.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Runtimes and 3D
|
||||
description: "GSAP is the default and you rarely name it — but real 3D, existing animation files, and scene transitions each have a runtime worth pinning in the prompt."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Level 2's copy-paste examples include an isometric-cards prompt that asks to "Build the scene in Three.js via the adapter" — this chapter is why that line is there, and the rest of the runtime map for when GSAP, the default, isn't the right tool.
|
||||
|
||||
HyperFrames animates through the [frame-adapter](/concepts/frame-adapters) pattern: any runtime that can answer "what should the screen look like at frame N?" plugs in and renders deterministically. [GSAP](/guides/gsap-animation) is the default adapter and covers most motion — you rarely need to name it. The cases below are the ones where the default choice can go wrong, so the prompt should pick the runtime for you.
|
||||
@@ -16,7 +18,11 @@ This is the one pin to state every time. For anything with genuine **depth, ligh
|
||||
- ❌ `isometric cards floating in CSS 3D with perspective`
|
||||
- ✅ `build the isometric scene in Three.js via the adapter, with real depth and lighting`
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Example 3d Cards"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/example-3d-cards.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The Three.js version of the isometric-cards prompt — real shadows and lighting, one-shot.*
|
||||
|
||||
|
||||
@@ -24,7 +30,11 @@ The engine rationale: CSS `perspective` transforms skew flat planes — they rea
|
||||
|
||||
Camera moves are part of the same rule. A "drone orbit", dolly, or push-in only exists where there's an actual camera:
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Orbit"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*A seek-driven Three.js drone orbit — the camera sweeps a continuous arc; impossible with CSS transforms.*
|
||||
|
||||
|
||||
@@ -94,7 +104,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> **Depth (52–56s).** The wire spirals off the flat plane into real 3D — a **Three.js scene via the frame adapter** (never CSS fake-3D): the camera descends following the wire as it coils around a rim-lit faceted form (ink material on charcoal), mono axis readouts landing on cue, then rises back to the plane with the wire leading the way out. The coil winds up out of the wire and collapses back onto it — its ends never float cut off in mid-air — and the protagonist chip joins the 3D scene for the crossing: it rides the wire straight through the coil's loops and passes behind the form with true depth occlusion, never floating over the geometry as a flat overlay.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-depth.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Depth"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-depth.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Media and audio](/prompting/media-and-audio) — precise phrasing for voiceover, music, sound, and assets, instead of motion and rendering.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Storyboards
|
||||
description: "For multi-scene work, don't prompt the scenes one by one — prompt the plan: the arc, the per-frame beats, and the pacing rule the build follows to fill them in."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
[Variables and templating](/prompting/variables-and-templating) was about reusing one composition across many renders. This page is the other axis of scale: one film with many scenes. Past a handful of beats, describing each scene from a blank page — "then frame 2 shows X, then frame 3 shows Y" — is the slow way and the way that drifts, because nothing ties the frames to each other. The fast way is to prompt the **plan** once — the throughline, the job each frame does, the rule that paces reveals — and let the build put frames against it.
|
||||
|
||||
This narrative vocabulary is a writing discipline, not additional `STORYBOARD.md` schema: the workflow translates the plan into the smaller machine-readable shape the build consumes.
|
||||
@@ -85,7 +87,11 @@ Without stating the return explicitly, a rebuild is free to treat the early moti
|
||||
>
|
||||
> Frame 3 — Landing (10.0–15.0s), type: cta, persuasion: callback + distillation, beat: resolve + inevitability, focal: the completed motif. At 10.0s: the accent dot from frames 1–2 expands and fills into the full Fernwell wordmark lockup — same motif, now complete, denser and larger. At 12.0s: tagline "Fernwell. Built for flow." stamps in below it. Hold 13.5–15.0s.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/storyboard-mini.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Storyboard Mini"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/storyboard-mini.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — no audio track, exactly as asked.*
|
||||
|
||||
## Related
|
||||
@@ -100,7 +106,7 @@ Without stating the return explicitly, a rebuild is free to treat the early moti
|
||||
<Card title="Design systems and brand" icon="palette" href="/prompting/design-systems">
|
||||
The two-color discipline and brand tokens a storyboard's direction block draws from.
|
||||
</Card>
|
||||
<Card title="The HyperFrames pipeline" icon="route" href="/guides/pipeline">
|
||||
<Card title="How a HyperFrames project works" icon="route" href="/concepts">
|
||||
`STORYBOARD.md` as a production artifact — where this chapter's plans land, downstream of `BRIEF.md`.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -113,7 +119,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> **The clip card** — the `<div class="clip">` typed in the opening travels the whole journey: it slides onto the wire as a clip chip after being typed, rides ahead of the camera between regions (handing itself off — visible leaving one region and arriving in the next), and is the thing that finally renders at the end. It is the protagonist.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Render"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-render.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause paying off, rendered — the protagonist chip arriving at the render slot after a full minute on the wire.*
|
||||
|
||||
*Next: [Editing existing videos](/prompting/editing-existing-videos) — the editor verbs that turn a first render, storyboard or not, into the twenty edits after it.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Transitions
|
||||
description: "Map energy and mood to named shader and CSS transition blocks, and prompt them per seam."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
[Motion](/prompting/motion)'s eight rules were written for what happens inside one scene. Rule 2's camera and rule 3's overlap apply *between* scenes too — a transition is that same grammar aimed at the cut itself, not a separate feature to bolt on afterward.
|
||||
|
||||
## What transitions do and when they trigger
|
||||
@@ -54,7 +56,11 @@ Name the block and the seam — transitions are the one place where per-seam con
|
||||
|
||||
> /general-video Six-scene SaaS explainer. Use [`whip-pan`](/catalog/blocks/whip-pan) as the primary transition between related points, and one [`cinematic-zoom`](/catalog/blocks/cinematic-zoom) into the final pricing reveal. Medium energy, ~0.4s each.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-transitions.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Transitions"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-transitions.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — whip-pan on four seams, cinematic-zoom into the pricing reveal.*
|
||||
|
||||
|
||||
@@ -98,7 +104,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> SANCTIONED SEAM #1: the camera pushes through an **`sdf-iris` shader transition** — the iris opens ONTO the continuation of the same wire (the wire is visible through the iris throughout; this is a lens the journey passes through, not a cut).
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Surface"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Code animations](/prompting/code-blocks) — naming a block and pasting real code for walkthroughs, diffs, and terminal takes.*
|
||||
|
||||
@@ -3,15 +3,25 @@ title: Variables and templating
|
||||
description: "Ask for the parts that should change to become named slots, then re-render the same composition with different values — one output per record."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
[Design systems](/prompting/design-systems) covered the parts of a video that should *never* change per render — the brand. This page covers the parts that should: a card per customer, a stat per quarter, a name per recipient. When you know a composition will be reused, say so in the prompt, and name the parts that change. The agent turns them into declared [variables](/concepts/variables): typed, labeled slots filled at render time instead of hardcoded into the HTML.
|
||||
|
||||
The trigger phrase is simple — call out the slots:
|
||||
|
||||
> Build a 6-second title card. Make the **name**, the **logo**, and the **accent color** variables; everything else stays fixed.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-default.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Variables Default"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-default.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Default variable values.*
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-variant.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Variables Variant"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-variables-variant.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*The same composition re-rendered with `--variables` overrides — different name, logo, and accent, zero re-prompting.*
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ title: VFX and liquid glass
|
||||
description: "Prompt device mockups, liquid-glass UI, shatter/portal/magnetic moments, and ambient polish — and know which effects need the canvas pipeline."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
Your motion-graphics terminal piece from Level 1 already named one of these — `vfx-shatter`, for the beat where the terminal breaks apart. This chapter is the rest of that showy end of the catalog: 3D device mockups, frosted-glass Apple UI, and cinematic moments where HTML shatters or gets sucked through a portal. Two groups do the work — the [HTML-in-Canvas](/catalog/blocks/vfx-iphone-device) blocks (real WebGL, live HTML rendered as GPU textures) and the [Effects](/catalog/components/vignette) components (lightweight CSS polish). Knowing which is which is the difference between an effect that renders and one that surprises you. All of it slots into the [one-shot skeleton](/prompting/anatomy) at the "technique" step.
|
||||
|
||||
### Device mockups
|
||||
@@ -11,7 +13,11 @@ To put your product UI inside a real phone or laptop, name [`vfx-iphone-device`]
|
||||
|
||||
> /product-launch-video 15-second 1920x1080 video. Our dashboard UI lives on the screen of a real iPhone 15 Pro Max that turntables slowly under product-review lighting, then a MacBook Pro slides in beside it showing the same UI wider. Use the `vfx-iphone-device` registry block. No narration.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-device-mockup.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Validate Device Mockup"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/validate-device-mockup.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above (the block's demo UI on screen), unedited.*
|
||||
|
||||
|
||||
@@ -36,7 +42,11 @@ The four `liquid-glass-*` panel blocks share the aurora-shader stage, so they co
|
||||
|
||||
> /motion-graphics 8-second 1920x1080 video. Frosted glass notification cards drift in and stack over an aurora shader background, each reading a fake alert ("Build passed", "Deploy live", "0 incidents"). Real translucency — the aurora must be visible through each card. Smoke the glass enough to keep white text above 3:1 against the brightest part of the aurora. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/glass-notify.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Glass Notify"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/glass-notify.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — CSS `backdrop-filter` glass over a Three.js aurora.*
|
||||
|
||||
<Warning>
|
||||
@@ -63,7 +73,11 @@ The `vfx-*` blocks are single cinematic beats — spend them on a transition or
|
||||
|
||||
> /motion-graphics 8-second 1920x1080 video. Beat 1 (0-4s): a landing-page hero holds under directional light. Beat 2 (4-6s): the whole page shatters into glass fragments that scatter. Beat 3 (6-8s): bold white text slams in on black. Use the `vfx-shatter` registry block; the final beat reads "HTML IS VIDEO". No narration, no image or media files.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/vfx-shatter.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Vfx Shatter"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/vfx-shatter.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited.*
|
||||
|
||||
|
||||
@@ -88,7 +102,11 @@ These are the ambient layer of the [motion grammar](/prompting/motion): grain an
|
||||
|
||||
> /motion-graphics 6-second 1920x1080 video. A wordmark logo — "HYPERFRAMES" in platinum on near-black — settles center-frame, then holds — but keep it alive with a film grain overlay and a slow 3% push-in, plus one shimmer sweep across the wordmark at 4s. Use the `grain-overlay`, `parallax-zoom`, and `shimmer-sweep` registry components. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/logo-polish.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Logo Polish"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/logo-polish.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — the "hold" stays alive on grain, a 3% push, and one shimmer pass.*
|
||||
|
||||
|
||||
@@ -125,7 +143,11 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-full-pr
|
||||
|
||||
> Inside: frosted-glass inspector panels (real translucency — blur over what's behind; the product's Studio design language) hover above the wire carrying live values (`ease: power3.out`, a color token, an fps readout) […] Glass surfaces use the file's `--glass-*` tokens with real backdrop blur.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Capstone Region Surface"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/capstone-region-surface.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Runtimes and 3D](/prompting/runtimes-and-3d) — picking GSAP, Three.js, or Lottie by what the moment actually needs, including the real depth these effects render on.*
|
||||
|
||||
@@ -3,11 +3,17 @@ title: High-fidelity looks
|
||||
description: "Write a visual spec — every element named, positioned, colored, and timed — to carry a specific look in words."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
This is the dial's third setting, [full visual spec](/prompting/specification-dial), pushed all the way: not a word from the [vocabulary](/prompting/vocabulary) list, but every element of a scene written out like a designer's spec. You can carry a specific look in words alone when the prompt reads like a designer's spec — every element named, positioned, colored, and timed. Compare a loose description ("dark night scene, mountain, glowing ring, title fades in") with a spec:
|
||||
|
||||
> 8-second 1920x1080 title card. Scene, back to front: #0a0e2a night sky with faint grain; an orange radial glow (#ff6a2b core ~150px, falling off to transparent by ~430px) igniting at the mountain peak's right shoulder from 2s, positioned so its upper falloff reaches the wordmark's baseline; over it a huge concentric ring system (5 rings, 1px strokes at 8% white opacity, innermost ring glowing #4a5fd9) centered 40% from the top; a low-poly mountain (6-8 dark navy facets, #141a3d–#1e2650) filling the lower third with its apex left of center, a white road S-curving up its face with a soft glow; thin horizontal cloud streaks (white, 6% opacity) drifting right at two heights; a man's silhouette, pure black, ~90px tall, bottom-right, fading in at 2.5s. At 3.5s "SHOWREEL" — thin geometric sans, ~140px, 0.35em tracking, white at 90% — fades in per letter across the ring center, the glow bleeding up through the letterforms above the peak. Slow 4% push-in across the full 8s. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-showreel.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Spec Showreel"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-showreel.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the spec above, unedited.*
|
||||
|
||||
<Note>
|
||||
@@ -33,12 +39,20 @@ The same density applied to a product-UI piece and a typographic piece — both
|
||||
|
||||
> 6-second 1920x1080. A frosted-glass command palette (640x84px, 20px radius, rgba(255,255,255,0.08) fill, 1px rgba(255,255,255,0.25) border, heavy backdrop blur) centered on a #0b0f1a field with two soft accent glows drifting slowly — #5b6cff upper-left, #22d3a5 lower-right, ~400px, 20% opacity. At 0.4s the palette scales in 0.96→1 settling with back.out(1.2). At 0.8s a grey placeholder "Search commands…" types on; at 2.2s it fades out over 0.2s and the query "render 4k" types in white. At 2.8s three result rows (56px tall, 12px gaps: icon square, label, shortcut chip) cascade in as a detached list below the fixed bar, staggered 0.12s, each rising 12px with back.out(1.4). At 4.2s a 10%-opacity #5b6cff fill sweeps left to right across the first row and its shortcut chip pulses once. Rows and glows keep a barely-visible drift to the end. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-command-palette.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Spec Command Palette"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-command-palette.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the spec above, unedited.*
|
||||
|
||||
> 7-second 1920x1080. Off-black #101014 field with fine static film grain at 4%. The word "PRECISION" in ~220px heavy condensed caps (a heavy system face condensed with scaleX 0.82), white, 0.02em tracking, centered: its letters assemble from alternating top/bottom 40px offsets with power3.out and a 0.05s stagger, starting 0.3s. At 1.8s a 2px hairline rule draws left-to-right beneath the word, 60% of its width, centered. At 2.4s a 40px tabular-mono counter fades in below and ticks 99.999 → 00.001 mm over 2.2s with expo.out deceleration. At 5.2s the whole lockup eases to 1.03 scale over 0.5s while the word cools from white to #d8d8de, then settles into a slow ±1% breathing idle to the end. No audio.
|
||||
|
||||
<video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-precision-type.mp4#t=0.1" style={{ borderRadius: "0.5rem", marginTop: "0.75rem" }}></video>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Spec Precision Type"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/spec-precision-type.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the spec above, unedited.*
|
||||
|
||||
*Next: [Verified example prompts](/prompting/examples) — the level's gallery, read with the vocabulary you now have.*
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Vocabulary that changes output
|
||||
description: "Natural-language adjectives the skills map to specific framework settings — easing, captions, transitions, audio, voices."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
[The dial](/prompting/specification-dial) told you *how much* to specify; this page is the word list for the cheap-precision setting — style tokens that cost you nothing to say and remove real ambiguity. The skills map natural-language adjectives to specific framework settings. Using the right word gets you the right result without specifying technical details.
|
||||
|
||||
## Motion & easing
|
||||
@@ -23,12 +25,36 @@ Describe how motion should *feel* and the agent picks the matching GSAP ease:
|
||||
Each word, rendered — the same move, only the ease changes:
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: "1rem", margin: "1.25rem 0" }}>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power2-out.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>smooth · power2.out</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power4-out.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>snappy · power4.out</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-back-out.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>bouncy · back.out</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-elastic-out.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>springy · elastic.out</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-expo-out.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>dramatic · expo.out</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-sine-inout.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>dreamy · sine.inOut</div></div>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Ease Power2 Out"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power2-out.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Ease Power4 Out"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-power4-out.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Ease Back Out"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-back-out.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Ease Elastic Out"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-elastic-out.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Ease Expo Out"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-expo-out.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Ease Sine Inout"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/ease-sine-inout.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -49,13 +75,41 @@ Compositions have no physical camera, but camera words translate directly into s
|
||||
The same scene under each camera word:
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: "1rem", margin: "1.25rem 0" }}>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-push-in.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>slow push-in</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pull-back.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>pull back</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pan.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>pan across</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-crane.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>crane down</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-whip.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>whip to</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-parallax.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>parallax</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>drone orbit (Three.js)</div></div>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Push In"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-push-in.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Pull Back"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pull-back.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Pan"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-pan.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Crane"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-crane.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Whip"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-whip.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Parallax"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-parallax.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Camera Orbit"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/camera-orbit.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -171,11 +225,31 @@ Hand-drawn emphasis effects for text:
|
||||
The five modes on the same sentence:
|
||||
|
||||
<div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: "1rem", margin: "1.25rem 0" }}>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-highlight.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>highlight</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-circle.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>circle</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-burst.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>burst</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-scribble.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>scribble</div></div>
|
||||
<div><video controls muted loop playsinline preload="metadata" src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-sketchout.mp4#t=0.1" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover", borderRadius: "0.4rem", display: "block" }}></video><div style={{ fontSize: "0.8em", textAlign: "center", opacity: 0.7, marginTop: "0.35rem" }}>sketchout</div></div>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Marker Highlight"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-highlight.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Marker Circle"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-circle.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Marker Burst"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-burst.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Marker Scribble"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-scribble.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
<DocsVideo
|
||||
title="HyperFrames video: Marker Sketchout"
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/marker-sketchout.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
</div>
|
||||
|
||||
## Text-to-speech voices
|
||||
|
||||
Reference in New Issue
Block a user