Handwrite

Handwritten text laid down letter by letter on a quantized stop-motion clock

Installation
$ pnpm dlx shadcn@latest add @remocn/handwrite

Usage

tsx
// src/Root.tsx
import { AbsoluteFill, Composition } from "remotion";
import { Handwrite } from "@/components/remocn/handwrite";
 
const HandwriteScene = () => (
  <AbsoluteFill style={{ background: "#f1eee7" }}>
    <Handwrite text="Made by hand" fontSize={72} />
  </AbsoluteFill>
);
 
export const RemotionRoot = () => (
  <Composition
    id="Handwrite"
    component={HandwriteScene}
    durationInFrames={120}
    fps={30}
    width={1280}
    height={720}
  />
);

The component is transparent — put the paper colour on the layer behind it.

handwriteDuration returns how many frames a string needs, so a <Sequence> can be sized to the writing instead of guessed:

tsx
import { Sequence } from "remotion";
import { Handwrite, handwriteDuration } from "@/components/remocn/handwrite";
 
const title = "Made by hand";
const subtitle = "one pose at a time";
 
const Titles = () => (
  <>
    <Sequence durationInFrames={handwriteDuration(title)}>
      <Handwrite text={title} fontSize={72} />
    </Sequence>
    <Sequence from={handwriteDuration(title)}>
      <Handwrite text={subtitle} fontSize={44} />
    </Sequence>
  </>
);

Letters arrive on the stop-motion clock, so step is the tempo control: 3 frames per pose is ten poses a second at 30fps. Raise it for a slower, more deliberate hand. The component holds still between poses — wrap it in paper-wobble if the whole sheet should breathe.

Props9

PropTypeDefault
textrequired
string—

The text to write out; newlines are honoured

fontSize
number54

Font size in pixels

color
string"#26242c"

Ink colour (any valid CSS color)

delay
number0

Frames on the local clock before writing begins

perStep
number1.6

Letters laid down per stop-motion pose

weight
400 | 500 | 600 | 700600

Pen weight

align
"left" | "center""center"

Horizontal alignment of the written block

fontFamily
string—

Overrides the bundled Caveat family; falls back to cursive

step
number3

Frames per stop-motion pose — the tempo control

  • textrequiredstring

    The text to write out; newlines are honoured

  • fontSizenumber

    Font size in pixels

    Default54

  • colorstring

    Ink colour (any valid CSS color)

    Default"#26242c"

  • delaynumber

    Frames on the local clock before writing begins

    Default0

  • perStepnumber

    Letters laid down per stop-motion pose

    Default1.6

  • weight400 | 500 | 600 | 700

    Pen weight

    Default600

  • align"left" | "center"

    Horizontal alignment of the written block

    Default"center"

  • fontFamilystring

    Overrides the bundled Caveat family; falls back to cursive

  • stepnumber

    Frames per stop-motion pose — the tempo control

    Default3