Captions that move with the voice, in fifteen ready-made styles.

Draws <HandCaptions> <Captions> <BoilStack>

$npm install @kinetographdev/kinetic-typography

What it does

Captions sets a voiceover on screen. Each word arrives as it is said and the line leaves all together. A line with a big word is a hook: that word is set huge and the small words sit round it. HandCaptions writes the other way, one letter at a time in mixed handwriting.

Fifteen caption styles

Highlighter, typewriter, a text-selection sweep, a shine, a difference-blend prism and more. Pick one by name, then change its fonts, motion and colours. The accent colour and a readable shadow can come from your footage.

Hand captions

Each word writes itself across the time it is spoken, one letter at a time, every letter in a different handwritten face. Key words break out in a fat serif or a heavy italic, each with its own colour if you like. A dark halo keeps the letters readable over bright footage.

A line written centred low on archive film.

Follows a tracked subject

The text hangs beside the subject, on the side with room. A reticle frames the subject and a bracket marks the letter being written. Give it the subject's box and the text stays clear of it.

A line written beside a tracked anvil.

Demos

Caption styles and hand captions

The caption styles over a talking head and over wide shots, the hand-drawn boiling lettering, the fonts, and a line written beside a tracked anvil in archive film, then centred low. Captions also change layout (over, centre, left, beside, one line, plain), treatment (box first, typewriter, select, highlight, underline, boil), finish (flat, shine, glow), and how each word comes in and the line goes out.

Compositions Tracked Centred BoilStack PosterBoil BoilStackTall

The styles in turn. All fifteen: clean-hook, red-headline, lime-serif, prism, editorial-serif, shine-headline, selected-text, highlighter, typewriter, box-first, bold-captions, soft-minimal, cinematic-caps, side-note, poster-boil.
Wide shots: cinematic-caps, then side-note.
poster-boil: a word to a row, drawn by hand and boiling, painted into bands as the line holds.
The same boiling lettering in a tall stack.
The fonts the styles can use: Switzer, Kineta, Figtree, Geist Serif, Poppins, Barlow Condensed, Inter, Anton, Archivo Black, Bebas Neue, Montserrat, Oswald, Playfair Display, Bodoni Moda, Instrument Serif, DM Serif Display, Space Grotesk, JetBrains Mono.
Tracked: the line beside an anvil.
Centred: the same line, low in the frame.

Studio panels

Ready-made scenes for the Hexed, Paper, VJ and caption panels in Studio. Edit a value and the preview redraws.

Compositions HexedLook PaperMatchCut PaperCutOut PaperScrapline PaperFoldOut TypeCaptions VjLook

Reference

Exports, props and examples, for wiring it into a project.

Ships with

Studio panelSkill

What it exports

Components

Drawn as JSX inside a composition.

<HandCaptions />

Captions written on in many hands, hanging off a tracked subject or centred low.

PropWhat it does
wordsThe spoken words with their frames (wordsFrom turns timestamps in seconds into these).
split?Words per page. Default 3 a page.
hot?Words that break out in a display face: a word, or { word, color, face } to give it its own colour and face (serif or heavy; without one the faces take turns).
hotColor?The colour of every hot word without its own. Default color.
anchor?The tracked subject on a frame, in canvas pixels, or null where nothing is tracked: its centre, and its box (w, h) when known, which the reticle then frames and the text sits clear of. Without it the captions sit centred low in the frame, with no reticle or lines.
place?Where the text hangs, when it should not follow the subject (a subject that jumps about, or a place kept clear of the picture): the lines still run to the subject. A box here keeps the text clear of it as anchor's does.
size?Letter size, px. Default 124 at 1080 high, scaled with the canvas.
color?string
glow?A CSS text-shadow for the glow, or '' for none.
halo?A dark halo under the glow, so the letters read over bright footage and white flashes: true (strength 1) or a strength, 0..1.5. Default off.
fringe?The pink and cyan fringe as letters land. Default true.
hands?The hands mixed a letter at a time, and the two display faces.
serif?string
heavy?string
doodle?The doodle's colour beside a serif key word, or false for none.
reticle?The reticle's label, or false for no reticle. Default TRK 01.
lines?Lines from the subject to the text and off the frame. Default true.
top?Highest the text block may reach, px from the top.
width?number
height?number

<Captions />

Sets a voiceover on screen in one of fifteen ready-made styles. Each word arrives as it is said and the line leaves all together. A line with a big word is a hook.

PropWhat it does
wordsThe spoken words with their frames (wordsFrom turns timestamps in seconds into these).
split?Words per line. Default 3 a line.
big?Words set big (matched without case or punctuation): a line with one is a hook.
marks?Caption words marked out (heavier, coloured or boxed, by the look's mark). Default: each caption line's first word.
preset?A style by name (STYLE_NAMES).
look?Changes to the style, every line.
lines?Changes for single lines, by line index from 0: { 2: { bigIn: 'left', big: { color: '#fff' } } }.
footage?The video under the captions, timed as its <Video> is.
subject?The subject (a face) on a frame, in canvas pixels: beside puts the block in the open side of it, at its eye level. A point track from plugins/vj/tools/track.mjs read with pointAt, or a fixed point. Read once a line.
hold?Frames a line stays after its last word when the next does not start sooner. Default 12.
width?number
height?number

<BoilStack />

PropWhat it does
lines?Three lines, top to bottom. Short words read best (the reference's are 5, 3 and 5 letters).
colors?The three colours, in the order they land on the lines at the end: top, middle, bottom.
ground?The ground.
knockout?The colour letters turn when their band is painted over; empty takes a near-black of each band's own hue.
marks?The white marks round the block.
from?The film's frame the animation starts on.
Functions (12)

haloOf()

The dark halo, as text-shadows listed after the glow so they paint under it: a tight black edge round each letter, then darker and wider shadows, so whatever is behind a word falls to grey near it. k scales the opacities.

pagesOf()

The pages: split word counts per page (default 3 a page).

A page stays up until the next starts, or hold frames after its last word. hot words (compared without case or punctuation) break out, numbered by their place in hot.

wordsFrom()

Words from timestamps in seconds (an ASR or TTS word list), starting on frame at.

captionLines()

The lines of a caption track: when each starts and ends and whether it is a hook (has a big word).

checkFrames()

Frames worth a still: a hook's big word and a caption line, each settled, to check that both read.

resolveLook()

BASE, then a style, then patches in order; caption and big merge field by field.

styleLook()

A look by style name, with overrides.

accentFrom()

An accent colour taken from the footage: the strongest hue across a few moments of it (each cell weighted by how saturated and lit it is, so a lamp or a shirt wins over a grey wall), lifted to a colour that reads behind or as white-on text. fallback when the footage has no colour (black and white film).

brightness()

Mean brightness 0..1 of the picture in a box given as fractions of the frame [x0, y0, x1, y1].

openSide()

The side of the frame with less going on (less contrast between neighbouring cells), between y0 and y1.

subjectFrom()

The subject's head from a matte (white subject on black, timed like the footage): the middle of the matte's top band across, and eye level a little under its top.

For <Captions subject>, so beside stays clear of a subject who moves. Null where the matte is empty.

timeAt()

Seconds into the file at composition frame frame.

Constants (22)

HANDS

The default hands, mixed a letter at a time (OFL Google Fonts).

SERIF

The display faces a key word breaks out in, taken in turn: a soft fat serif, and a heavy italic that streaks.

wordSpans

When each word is written: across its spoken time for a plain word, at once for one that breaks out.

ABOUT

One line on what each look is for, for the panel and for an agent choosing one.

BASE

What every look starts from.

FINISHES

The big word's surface: flat, a shine that sweeps across it, or a glow in its own colour.

INS

How each word arrives. focus comes up from a blur; pop grows past its size and settles; typewriter and box-first are the moving styles used as an entrance for every word.

LAYOUTS

Where the lines sit. over: the small words over and under the big word, upper middle. centre: the same block in the middle of the frame. left: flush left, upper left. beside: in the open side of the frame, at eye level (the side is read off the footage, or set). one-line: small and big words on one line. plain: captions only, the big word just marked.

MARKS

How a caption word marks itself out (the line's marked word: marks, or its first word).

OUTS

How a line leaves, all its words together.

STYLES

The fifteen ready-made styles, by name.

Each is a patch on BASE.

TREATMENTS

How the big word is dressed as it arrives. box-first: a box grows, then the word lands in it. typewriter: typed a letter at a time with a cursor. select: a blue text selection sweeps across it. highlight: a colour sweeps in behind it, like a highlighter pen. underline: a bar draws under it. boil: the whole line drawn by hand a word to a row, boiling on twelves, painted into knocked-out bands as it holds (the poster-boil style; see boil-captions.tsx).

captionLookSchema

A caption look: style names a ready-made look, the rest change it.

Every field is optional.

captionsSchema

<Captions>'s props, for a composition whose schema is the component's.

textLookSchema

One kind of text, the caption or the big text.

BOIL_FRAMES

The length of the animation in reference frames (12 fps).

HEAVY FONTS FONT_NAMES STYLE_NAMES CAPTION_PRESETS BOIL_DEFAULTS

Faces

Handwritten, mixed a letter at a time

Caveat Shadows Into Light Indie Flower Gloria Hallelujah Patrick Hand Gochi Hand

Display, for key words

Abril Fatface Archivo Black

Examples

Captions in a ready-made style
import { Captions, wordsFrom } from '@kinetographdev/kinetic-typography';

const words = wordsFrom(asr.words, 30);
const footage = { src: staticFile('me.mp4') };

<Video src={footage.src} />
<Captions words={words} split={[3, 3]} big={['premium']} preset="highlighter" footage={footage} />
Hand captions from word timestamps
import { HandCaptions, wordsFrom } from '@kinetographdev/kinetic-typography';

const words = wordsFrom(asr.words, 30, 12); // seconds to frames, starting on frame 12

<HandCaptions words={words} split={[2, 2, 3]} hot={['1891', 'kinetograph', 'move']} />
Hung off a tracked subject
import { HandCaptions, wordsFrom } from '@kinetographdev/kinetic-typography';
import { pointAt } from '@kinetographdev/vj';

// track the subject once:
//   node plugins/vj/tools/track.mjs --in <clip> --box x,y,w,h --out <json>

<HandCaptions words={words} hot={['move']} anchor={(f) => pointAt(track, f, 30)} />

In Studio

Panel

Studio gets a Captions panel: a card for each style drawn in its own type, a Caption or Big text switch for font, case, weight, size, tracking and colour, layout cards, motion controls with an In and Out switch, and an accent colour you can take from the footage. Hook and Caption pins sit on the preview and you drag them up or down. HandCaptions has no panel.

There are no agent tools. The skill tells an agent to take word timestamps from your speech-to-text or voice-over tool instead of placing frames by hand, choose the lines and the big words, and render a settled hook frame and caption frame to check that both read. For tracked text it tracks the subject with the VJ plugin.

It is a package in the source repository. Its skill comes with it, so an agent can use it without being taught.