One function per scene
Section titled “One function per scene”Each scene returns a full-frame box. Children key from the scene’s own frame 0.
import { Layer, LayerAnimation } from "framefields";import { H, PAPER, SANS, W } from "../theme.js";
export function hero() { return Layer.box({ id: "hero", position: "absolute", x: 0, y: 0, width: W, height: H, background: "#000", children: [ Layer.text("Every frame is a function of its number.", { position: "absolute", x: 140, y: 420, width: W - 280, fontFamily: SANS, fontSize: 120, fontWeight: 800, fill: PAPER, }).animate(LayerAnimation.create().fadeIn(0, 18)), ], });}Join them: Layer.sequence
Section titled “Join them: Layer.sequence”Layer.sequence places scenes end to end, overlaps each pair by its transition, and sets every scene’s startFrame / durationFrames for you.
import { Composition, Layer, Transition } from "framefields";import { beats, FPS, H, W } from "./theme.js";import { features, hero, outro, proof } from "./scenes/index.js";
const film = Layer.sequence( [ { scene: hero(), duration: beats(8) }, { scene: features(), duration: beats(12), transition: Transition.push("left", 18) }, { scene: proof(), duration: beats(8), transition: Transition.wipe("right", 16) }, { scene: outro(), duration: beats(6), transition: Transition.iris(20) }, ], { width: W, height: H },);
const comp = new Composition({ width: W, height: H, fps: FPS, durationMs: (film.totalFrames / FPS) * 1000, // the sequence knows its length});comp.add(film);duration includes the transition. A missing transition is a cut.
Transitions
Section titled “Transitions”| Call | Look | Defaults |
|---|---|---|
Transition.cut() |
hard cut | — |
Transition.crossfade(frames, ease) |
new scene fades in over the old | 15, sine.inOut |
Transition.fadeThrough(frames, ease) |
dip to background and back | 20, sine.inOut |
Transition.push(dir, frames, ease) |
new pushes old out | left, 18, power3.inOut |
Transition.slide(dir, frames, ease) |
new slides over old, which dims | left, 18, power3.out |
Transition.zoom(frames, ease) |
old grows and fades, new settles | 18, power2.inOut |
Transition.whip(dir, frames) |
fast motion-blurred push | left, 10 |
Transition.wipe(dir, frames, ease) |
hard edge sweeps across (matte) | left, 18, power2.inOut |
Transition.iris(frames, { at, ease }) |
circle opens from a point (matte) | 20, centre |
dir is "left" | "right" | "up" | "down". at is [x, y] as fractions of the frame.
Carry elements across cuts
Section titled “Carry elements across cuts”A badge, card or cursor that crosses a scene boundary with continuous position and velocity hides the cut. Put the carrier outside the sequence, on the composition, with its own keyframes spanning both scenes.