mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 23:03:09 +00:00
chore(skills): rename compose-video → hyperframes-compose, captions → hyperframes-captions
Namespace skill names with `hyperframes-` prefix for clearer identity in OSS contexts where users may have other skills installed. Updates skill directories, SKILL.md frontmatter, CLAUDE.md, README.md, CLI build script, init command, and project template. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
---
|
||||
name: hyperframes-compose
|
||||
description: Create HyperFrames HTML video compositions. Use when asked to create a video, build an animation, make a composition, add a title card, or generate any HTML-based video content for HyperFrames.
|
||||
---
|
||||
|
||||
# Compose Video
|
||||
|
||||
HTML is the source of truth for video. A composition is an HTML file with `data-*` attributes for timing, a GSAP timeline for animation, and CSS for appearance. The framework handles clip visibility, media playback, and timeline sync.
|
||||
|
||||
## Approach
|
||||
|
||||
Before writing HTML, think at a high level:
|
||||
|
||||
1. **What** — what should the viewer experience? Identify the narrative arc, key moments, and emotional beats.
|
||||
2. **Structure** — how many compositions, which are sub-compositions vs inline, what tracks carry what (video, audio, overlays, captions).
|
||||
3. **Timing** — which clips drive the duration, where do transitions land, what's the pacing.
|
||||
4. **Execute** — then implement using the rules below.
|
||||
|
||||
For small edits (fix a color, adjust timing, add one element), skip straight to the rules.
|
||||
|
||||
When no `visual-style.md` or animation direction is provided, follow [house-style.md](./house-style.md) for motion defaults, sizing, and color palettes.
|
||||
|
||||
## Data Attributes
|
||||
|
||||
### All Clips
|
||||
|
||||
| Attribute | Required | Values |
|
||||
| ------------------ | --------------------------------- | ------------------------------------------------------ |
|
||||
| `id` | Yes | Unique identifier |
|
||||
| `data-start` | Yes | Seconds or clip ID reference (`"el-1"`, `"intro + 2"`) |
|
||||
| `data-duration` | Required for img/div/compositions | Seconds. Video/audio defaults to media duration. |
|
||||
| `data-track-index` | Yes | Integer. Same-track clips **cannot overlap**. |
|
||||
| `data-media-start` | No | Trim offset into source (seconds) |
|
||||
| `data-volume` | No | 0-1 (default 1) |
|
||||
|
||||
`data-track-index` does **not** affect visual layering — use CSS `z-index`.
|
||||
|
||||
### Composition Clips
|
||||
|
||||
| Attribute | Required | Values |
|
||||
| ---------------------------- | -------- | -------------------------------------------- |
|
||||
| `data-composition-id` | Yes | Unique composition ID |
|
||||
| `data-duration` | Yes | Takes precedence over GSAP timeline duration |
|
||||
| `data-width` / `data-height` | Yes | Pixel dimensions (1920x1080 or 1080x1920) |
|
||||
| `data-composition-src` | No | Path to external HTML file |
|
||||
|
||||
## Composition Structure
|
||||
|
||||
Every composition is a `<template>` wrapping a `<div>` with `data-composition-id`. Each must include its own GSAP script and register its timeline:
|
||||
|
||||
```html
|
||||
<template id="my-comp-template">
|
||||
<div data-composition-id="my-comp" data-width="1920" data-height="1080">
|
||||
<!-- content -->
|
||||
<style>
|
||||
[data-composition-id="my-comp"] {
|
||||
/* scoped styles */
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<script>
|
||||
window.__timelines = window.__timelines || {};
|
||||
const tl = gsap.timeline({ paused: true });
|
||||
// tweens...
|
||||
window.__timelines["my-comp"] = tl;
|
||||
</script>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
Load in root: `<div id="el-1" data-composition-id="my-comp" data-composition-src="compositions/my-comp.html" data-start="0" data-duration="10" data-track-index="1"></div>`
|
||||
|
||||
## Video and Audio
|
||||
|
||||
Video must be `muted playsinline`. Audio is always a separate `<audio>` element:
|
||||
|
||||
```html
|
||||
<video
|
||||
id="el-v"
|
||||
data-start="0"
|
||||
data-duration="30"
|
||||
data-track-index="0"
|
||||
src="video.mp4"
|
||||
muted
|
||||
playsinline
|
||||
></video>
|
||||
<audio
|
||||
id="el-a"
|
||||
data-start="0"
|
||||
data-duration="30"
|
||||
data-track-index="2"
|
||||
src="video.mp4"
|
||||
data-volume="1"
|
||||
></audio>
|
||||
```
|
||||
|
||||
## Timeline Contract
|
||||
|
||||
- All timelines start `{ paused: true }` — the player controls playback
|
||||
- Register every timeline: `window.__timelines["<composition-id>"] = tl`
|
||||
- Framework auto-nests sub-timelines — do NOT manually add them
|
||||
- Duration comes from `data-duration`, not from GSAP timeline length
|
||||
- Never create empty tweens to set duration
|
||||
|
||||
## Rules (Non-Negotiable)
|
||||
|
||||
**Deterministic:** No `Math.random()`, `Date.now()`, or time-based logic. The renderer must produce identical output every time.
|
||||
|
||||
**GSAP:** Only animate visual properties (`opacity`, `x`, `y`, `scale`, `rotation`, `color`, `backgroundColor`, `borderRadius`, transforms). Do NOT animate `visibility`, `display`, or call `video.play()`/`audio.play()`.
|
||||
|
||||
**Animation conflicts:** Never animate the same property on the same element from multiple timelines simultaneously — causes flickering in headless renders.
|
||||
|
||||
**Never do:**
|
||||
|
||||
1. Forget `window.__timelines` registration
|
||||
2. Use video for audio — always muted video + separate `<audio>`
|
||||
3. Nest video inside a timed div — use a non-timed wrapper
|
||||
4. Use `data-layer` (use `data-track-index`) or `data-end` (use `data-duration`)
|
||||
5. Animate video element dimensions — animate a wrapper div
|
||||
6. Call play/pause/seek on media — framework owns playback
|
||||
7. Create a top-level container without `data-composition-id`
|
||||
|
||||
## Editing Existing Compositions
|
||||
|
||||
- Read the full composition first — match existing fonts, colors, animation patterns
|
||||
- Only change what was requested — don't rewrite untouched sections
|
||||
- Don't rewrite entire files for small changes
|
||||
- Preserve timing of unrelated clips
|
||||
|
||||
## Typography and Assets
|
||||
|
||||
- Every composition loads its own fonts (`@import` or `@font-face` in `<style>`)
|
||||
- Use `font-display: block` for local fonts — renderer needs fonts loaded before capturing
|
||||
- Add `crossorigin="anonymous"` to media loaded from external URLs
|
||||
- Minimum readable text: 20px landscape, 18px portrait
|
||||
- All files (video, audio, fonts, images) live at the project root alongside `index.html`
|
||||
- From sub-compositions, use `../` to reference root files
|
||||
|
||||
For PiP, title cards, and slide show patterns, see [patterns.md](./patterns.md).
|
||||
For data, stats, and infographics, see [data-in-motion.md](./data-in-motion.md).
|
||||
|
||||
## Output Checklist
|
||||
|
||||
- [ ] Every top-level container has `data-composition-id`
|
||||
- [ ] Every composition has `data-width`, `data-height`, `data-duration`
|
||||
- [ ] Compositions in own HTML files, loaded via `data-composition-src`
|
||||
- [ ] `<template>` wrapper on sub-compositions
|
||||
- [ ] `window.__timelines` registered for every composition
|
||||
- [ ] 100% deterministic — no randomness
|
||||
- [ ] Each composition includes GSAP: `<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>`
|
||||
Reference in New Issue
Block a user