Give it the cue of each framing (from the voice's word times) and the point and scale
it frames; get the moves for a camera group that eases to each framing just before its
cue and creeps in slowly while it holds. The group's mechanics are hn4a-compositor
(references/spec-format.md, A camera over a group) and the keys are written by
camera(id, start, moves) in hn4a-compositor-in-scene-titles
(references/titles-fx.md). Choose this pace when inspection, calm or a deliberate
reveal serves the brief, including a restrained ad. The faster treatment
(hn4a-compositor-fast-ad-camera) served one presenter ad after its calm version was
judged sleepy; that result does not prescribe the pace of every ad. To zoom into
footage rather than layers, render the move in ffmpeg (ffmpeg-eased-punch-in).
Inputs
- The framings: one per thing being explained, each with its cue (the phrase that
names it,
python-read-word-timings,cues), a point and a scale. - The layers in the camera group (a board, a slide, a screen, a recording's frame),
and their box in group px for
within.
Run it
Write references/explainer_camera.md's module into the job's scripts/ folder as
scripts/explainer_camera.py, beside scripts/titles_fx.py, and call it from the build
script there:
moves = drift_and_push(2.0, [(2.0, (960, 540), 1.0), (6.4, P["chart"], 1.3)], end=12.0)
layers.append(camera("cam", 2.0, moves, end=12.0, within=SCREEN))
| Helper | Does | Defaults |
|---|---|---|
drift_and_push(start, framings, end) | Holds the first framing; eases to each next one starting start_before its cue; on every hold creeps creep further in, linearly, until the next move | ease 0.65 s, start_before 0.3 s, creep 0.03 |
drift(start, end, from, to, scale) | One slow, even pan across a wide group | linear |
within=(x, y, w, h) on camera() keeps every framing inside the layers' box.
Numbers that worked
| Piece | Moves | Settings |
|---|---|---|
| Narrated summary of a board, slides | One drift and one push per screen | ease 0.65 (smoothstep), start_before 0.3, creep 0.03 |
| Walkthrough of a screen recording | A framing per thing shown, held, eased to the next | framings 1.15–1.6×, ease 0.7, start_before 0.85 (lands 0.15 s before the phrase), creep 0.04 |
- Leave time to read. A slow creep can keep a hold alive; a completely held screen is useful when movement would distract from inspection. The helper defaults to creep, which can be set to zero.
- Land before the word on a walkthrough: the viewer is already looking at the control when it is named.
- Frame a region where several cues land, as with any camera.
Tips and traps
- The creep is 3–4% over the whole hold, so it never reads as a move of its own.
- A framing near the layers' edge shows past them without
within. - A part that builds on a calm piece lands as the camera settles
(
hn4a-compositor-make-product-ui-exciting).
Check it
- A still at every landing and one just before each next move: the point centred, the scale up by the creep, nothing past the edge.
- The live spec with the voice (
hn4a-compositor, Live spec, then render).


