Outline Trace

Every glyph contour draws itself as a stroke, letter by letter, then the fill wipes up inside each letter and the stroke fades into it

Installation
$ pnpm dlx shadcn@latest add @remocn/outline-trace

Usage

// src/Root.tsx
import { AbsoluteFill, Composition } from "remotion";
import { OutlineTrace } from "@/components/remocn/outline-trace";
 
const Title = () => (
  <AbsoluteFill style={{ backgroundColor: "#ff4d1a" }}>
    <OutlineTrace text="Outline" color="#111111" />
  </AbsoluteFill>
);
 
export const RemotionRoot = () => (
  <Composition
    id="OutlineTrace"
    component={Title}
    durationInFrames={75}
    fps={30}
    width={1280}
    height={720}
  />
);

The letters are geometry parsed out of the font file with opentype.js, so the stroke runs along the actual contours. Each letter starts stagger frames after the previous one. Its outer contours draw over 18 frames; counters, such as the hole in an a or an e, start four frames later. When the outline has closed, the fill rises from the bottom of the letter and the stroke fades into it, so the resting word is exactly the glyphs. keepStroke leaves the stroke on top of the fill, and fill={false} keeps the drawn outline only.

Static instances of variable fonts, including the default Inter, keep overlapping contours inside some letters (the bar of a t crosses its stem). A mask hides the part of the stroke that runs inside the letter's filled shape, so those overlaps never draw.

fontUrl defaults to Inter ExtraBold from Google Fonts' static CDN. Point it at any .ttf, .otf or .woff file; .woff2 is not supported. The render is held until the font has loaded. The word centers in its parent and sizes scale with height / 720.

Props
PropTypeDefaultDescription
text
string"Outline"The text to draw
fontUrl
stringInter ExtraBold (gstatic ttf)URL of a .ttf, .otf or .woff file the outlines are parsed from
fontSize
number150Font size in reference px at 720p
color
string"#fafafa"Fill color
strokeColor
stringsame as colorStroke color
strokeWidth
number2.5Stroke width in reference px
stagger
number3Frames between letters
fill
booleantrueFill the letters after the outline draws
keepStroke
booleanfalseKeep the stroke on top of the fill
speed
number1Timeline speed multiplier
className
string—Optional className passed to the wrapper