Overview
Hyperframes uses HTML as the source of truth for describing a video:- HTML clips = video, image, audio, composition
- Data attributes = timing, metadata, styling
- CSS = positioning and appearance
- GSAP timeline = animations and playback sync (see GSAP Animation)
Framework-Managed Behavior
The framework reads data attributes and automatically manages:- Primitive clip timeline entries — reads
data-start,data-duration, anddata-track-indexfrom clips and adds them to the GSAP timeline - Media playback (play, pause, seek) for
<video>and<audio> - Clip lifecycle — clips are mounted/unmounted based on
data-startanddata-duration - Timeline synchronization — keeps media in sync with the GSAP master timeline
- Media loading — waits for all media to load before resolving timing
Viewport
Every composition must includedata-width and data-height on the root element:
- Landscape:
data-width="1920" data-height="1080" - Portrait:
data-width="1080" data-height="1920"
All Clip Attributes
| Attribute | Applies To | Required | Description |
|---|---|---|---|
id | All | Yes | Unique identifier (e.g., "el-1"). Used for relative timing references and CSS targeting. |
class="clip" | Visible elements | Yes | Enables runtime visibility management. Omit for audio-only clips. |
data-start | All | Yes | Start time in seconds (e.g., "0", "5.5"), or a clip ID reference for relative timing (e.g., "intro"). |
data-duration | video, img, audio | See below | Duration in seconds. Required for images. Optional for video/audio (defaults to source duration). Not used on compositions. |
data-track-index | All | Yes | Timeline track number. Controls z-ordering (higher = in front). Clips on the same track cannot overlap. |
data-media-start | video, audio | No | Playback offset / trim point in source file (seconds). Default: 0. See Data Attributes. |
data-volume | audio, video | No | Volume level from 0 to 1. Default: 1. |
data-composition-id | div | On compositions | Unique composition ID. Must match the key used in window.__timelines. |
data-composition-src | div | No | Path to external composition HTML file (for nested compositions). |
data-width | div | On compositions | Composition width in pixels. |
data-height | div | On compositions | Composition height in pixels. |
Clip Types
Video Clips
Video Clips
Video clips embed Key behavior:
<video> elements with timing and playback attributes.data-durationis optional — defaults to the remaining duration of the source file fromdata-media-start- If source media runs out before
data-duration, the clip shows the last frame (freeze frame) data-media-starttrims the beginning of the source video —data-media-start="5"starts playback 5 seconds into the source filedata-volumecontrols the audio volume of the video — set to"0"for silent video- Do not add
class="clip"to video elements — the framework manages their visibility directly
Image Clips
Image Clips
Image clips display static images with controlled timing.Key behavior:
data-durationis required for images (unlike video/audio, there is no source duration to default to)class="clip"is required — this enables the runtime to show/hide the image based on timing- Supported formats: PNG, JPG, WebP, SVG, GIF (first frame only)
- Position and size with CSS — the image renders at its natural size unless styled otherwise
Audio Clips
Audio Clips
Audio clips add sound to the composition without any visual element.Key behavior:
data-durationis optional — defaults to the remaining duration of the source file fromdata-media-start- Audio clips are invisible — do not add
class="clip"(there is nothing to show/hide) data-volumecontrols volume — use"0.5"for background music at 50% volumedata-media-starttrims the beginning of the audio source, just like video- Multiple audio clips can overlap on different tracks for layered sound design
Composition Clips (Nested)
Composition Clips (Nested)
Composition clips embed one composition inside another, enabling modular, reusable video building blocks.Key behavior:
- Compositions do not use
data-duration— duration is determined by the composition’s GSAP timeline (tl.duration()) - External compositions are loaded from
data-composition-srcand wrapped in<template>tags - Each nested composition has its own
window.__timelinesentry, registered by its own<script>block - The framework automatically nests sub-timelines — do not manually add them to the parent timeline
- Any composition can be nested inside any other — there is no special “root” type
Relative Timing
Reference another clip’s ID indata-start to mean “start when that clip ends”:
main starts at second 10 (when intro ends).
Offsets let you add gaps or overlaps:
Timeline Contract
The framework initializeswindow.__timelines = {} before any scripts run. Every composition must register a GSAP timeline at the key matching its data-composition-id:
Rules
- Every composition needs a
<script>block that creates and registers its timeline - All timelines must start paused (
{ paused: true }) - The framework auto-nests sub-timelines into the parent — do not manually add them
- Duration comes from
tl.duration()— do not adddata-durationon composition elements - Timelines must be finite (no infinite loops or repeats)
- The timeline ID must exactly match the
data-composition-idattribute on the root element
Caption Discoverability
For caption compositions, add these attributes to the root node so the framework can identify and special-case caption rendering:Output Checklist
Before rendering, verify your composition meets these requirements:
- Every composition has
data-widthanddata-heighton the root element - Each reusable composition is in its own HTML file
- External compositions are loaded via
data-composition-src - Each external composition file uses a
<template>wrapper - All GSAP timelines are registered in
window.__timelineswith the correct ID - Timed visible elements (images, divs) have
class="clip" - Video elements do not have
class="clip"(framework manages them directly) - All
data-startreferences point to existing clip IDs - Run
npx hyperframes lintto catch structural issues automatically