Reference
Runtime API
A scene is a pure function of time. Given the same time it draws the same frame, which is what makes scrubbing, previews and exports agree.
Writing a scene
A scene receives a context and draws one frame. Orbit writes scenes like this for every film. The example scenes are written exactly this way, so they are the best place to see the API in use.
import { fit, upper } from "../canvas"
import { settle } from "../ease"
import type { Scene } from "../types"
/** A headline that rises in, then holds. */
export const hello: Scene = (c) => {
const { ctx, W, H, P, m, seg, headline } = c
const enter = settle(seg(0, 0.2))
const out = seg(0.93, 1)
const size = fit(c, headline, m * 0.12, W * 0.86)
ctx.fillStyle = P.fg
ctx.globalAlpha = 1 - out
ctx.fillText(upper(P, headline), W * 0.07, H / 2 + (1 - enter) * size)
}Scene context
| Field | Type | Description |
|---|---|---|
ctx | CanvasRenderingContext2D | The canvas to draw into. |
W, H | number | Frame size in device pixels. |
t | number | Normalized time, 0 to 1, across the scene. |
seg(a, b) | (a, b) => number | Progress of t through [a, b], clamped to 0..1. |
m | number | min(W, H). Size everything from this so every format scales. |
port | boolean | True for tall frames such as 9:16. |
P | Pack | The style pack: colors, typeface, weight, spacing, case, corners. |
ac | string | Resolved accent color. |
F(size, weight?) | (n, w?) => string | Font shorthand in the pack's typeface. |
ls(px) | (px) => void | Sets letter-spacing. |
headline, o | string, DrawOptions | Copy and options from the template. |
Easing
Every film moves with the same small set of curves, so different scenes still feel like one brand.
settle(x): things arriving. Fast in, soft landing, no overshoot.morph(x): one thing changing size or position. Even in and out.clamp01(x): limits any value to 0..1.
Drawing helpers
fit(c, text, size, maxWidth): shrinks a font size until the text fits.wrap(ctx, text, maxWidth): greedy word wrap with the current font.upper(P, text): applies the pack's uppercase rule.roundRect(ctx, x, y, w, h, r): rounded rectangle path; useP.sqfor square packs.
Templates
A template picks a scene, a style pack and starter copy, and carries a version:
export default defineTemplate({
slug: "release-notes",
name: "Release notes",
description: "Version number, then the highlights tick in.",
category: "Changelog",
version: "1.0.0",
scenes: 3,
duration: 45,
film: { scene: "changelog", pack: "mono", headline: "v2.4 is out.", num: "v2.4" },
})Bump the patch version for copy and timing changes, the minor version for new optional props, and the major version when existing films would render differently.