05 Video in code
A video is a function of the frame number. Scrub it frame by frame.
- Floor
- 05 of 09
- Demos
- Frame-accurate timeline
- Skills
- RemotionHyperFrames
A video is a function
In a video editor you move clips and keyframes by hand. In code, a video is a function: frame number in, picture out. Frame 42 always looks the same, no matter what came before it or how fast your machine is.
That one property unlocks everything else on this floor. You can scrub to any frame instantly, render frames in parallel across many machines, change one line of copy and re-render without re-animating, and check a specific frame in review (“at frame 84 the logo overlaps the caption”).
Frame-accurate timeline
A three-second title sequence where every property is computed from the frame number. Drag the playhead, step one frame at a time, and watch the values change.
- Frame
- 021 / 89
- Timecode
- 00:00:00:21
- Seconds
- 0.700
| Layer | Property | Value |
|---|---|---|
| Background | opacity | 1.000 |
| Title | y | 0.0px |
| Title | opacity | 1.000 |
| Accent bar | scaleX | 0.019 |
| Accent bar | opacity | 1.000 |
| Subtitle | y | 12.0px |
| Subtitle | opacity | 0.000 |
| Logo | scale | 0.000 |
Red values changed since the previous frame.
Same three seconds, 90 frames. Changing the frame rate keeps the moment; only the frame number changes.
export const Title = () => {
const frame = useCurrentFrame(); // 21
const { fps } = useVideoConfig(); // 30
const y = interpolate(frame, [6, 24], [40, 0], {
easing: Easing.bezier(0.16, 1, 0.3, 1),
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
// At frame 21: y = 0.0px, opacity = 1.00
return <h1 style={{ transform: `translateY(${y}px)` }}>Motion, on brand.</h1>;
};Frames, not seconds
Video runs at a fixed frame rate, so every timing decision eventually becomes a whole number of frames. At 30 fps a 0.6-second move is 18 frames; at 24 fps it is 14.4, which has to round to 14 or 15. Plan in seconds if you like, but review in frames, because that is what renders.
Remotion gives you the frame directly: useCurrentFrame() inside React components, with interpolate() and spring() to turn it into values. HyperFrames works from HTML: you write a paused GSAP timeline, and the renderer seeks it to each frame’s time. Different authoring styles, same deterministic model.
Rules of thumb
- Never read the clock (
Date.now(), timers) inside a composition. Everything derives from the frame. - Name keyframes by frame in reviews and briefs: “f18 title settled”, not “around half a second”.
- Pick the frame rate first. Changing it later shifts every rounded keyframe.
- Clamp interpolations so values hold steady before and after their range.
- Step frame by frame through every transition before you render. Problems hide between frames.