data-* timing attributes, and the framework turns them into frames.
index.html is the top-level composition. It can hold other compositions
inside it. There is no special “root” type — any composition can be imported
into any other.
How an HTML file becomes frames
Here is a whole video: a logo, then a video clip.index.html
data-composition-id, and
every timed element needs class="clip" so the runtime can hide it outside its
own window of time.
The clips add up to five seconds. At 30 frames per second — the default — that
is 150 frames, numbered 0 to 149:
Nothing plays in real time during a render. The renderer asks for frame 0, then
frame 1, and each answer is a single still picture. That is what makes
rendering deterministic.
What can go on the timeline
A clip is any element with timing attributes on it:<video>— video clips, B-roll, A-roll<img>— stills and overlays<audio>— music and sound effects<div data-composition-id="...">— another composition nested inside this one
Put one composition inside another
You can either point at a separate file or write the nested composition inline. Use a separate file when you want to reuse it.- External file
- Inline
data-composition-src names the file. The framework fetches it, pulls the
content out of its <template> tag, mounts it, runs its scripts, and
registers its timeline.Paths resolve from the project root, not from the file doing the
referencing. So a composition nested one level deep still writes
compositions/foo.html, never ../compositions/foo.html.index.html
<template>:compositions/intro-anim.html
data-playback-start picks which moment of the child timeline shows first.
It defaults to 0. Trimming or splitting from the left pushes this offset
forward by the time elapsed multiplied by data-playback-rate, so the
nested animation keeps going instead of jumping back to its beginning.Where the files live
project
index.html
compositions
intro-anim.html
caption-overlay.html
outro-title.html
assets
HTML sets the timing, scripts do the motion
Your HTML says what plays, when, and on which track, all through data attributes. Your scripts handle the creative part: effects, transitions, canvas, SVG, GSAP animation.Reuse one composition with different content
One source file can appear several times in the same video, each copy carrying its own text and colors. HyperFrames does not wiredata-var-* attributes into
your DOM or CSS for you — you do it in three steps:
- Declare each variable — id, type, default — on the sub-composition’s root
with
data-composition-variables. That root is the<html>element in a full-document composition, or the[data-composition-id]element in a template or fragment. - Pass each copy’s values on its host element with
data-variable-values. - Read them inside the composition with
window.__hyperframes.getVariables(), which layers the host’s values over the declared defaults, one copy at a time.
index.html
data-start="card-pro" means “start when that one ends”.
And the source file both cards share:
compositions/card.html
@hyperframes/core, extractCompositionMetadata() reads the same
data-composition-variables array — that is how Studio builds its editing UI.