Zoom Words

Huge words fade into a long line while the camera rides the write head

Installation
$ pnpm dlx shadcn@latest add @remocn/zoom-words

Usage

The first word fades in centered and the camera holds still. The whole phrase then reveals on one clock with a short gentle ramp-up settling into constant speed — the measured profile of the reference — with each word sliding in on a small diagonal, lightly softened but always readable, while the camera rides the growing line and stops with the last word centered. The shot starts blur em out of focus and sharpens over blurFrames. Meant to be hard-cut into the next scene (in the reference, a typewriter scene follows the cut).

tsx
// src/Root.tsx
import { Composition } from "remotion";
import { ZoomWords } from "@/components/remocn/zoom-words";
 
const ZoomWordsScene = () => (
  <ZoomWords text="Still piecing together tools" />
);
 
export const RemotionRoot = () => (
  <Composition
    id="ZoomWords"
    component={ZoomWordsScene}
    durationInFrames={75}
    fps={30}
    width={1280}
    height={720}
  />
);

With Backdrop

The component renders transparent — supply the background via Backdrop. The reference pairs it with a dark-to-violet vertical gradient.

tsx
import { Composition } from "remotion";
import { ZoomWords } from "@/components/remocn/zoom-words";
import { Backdrop } from "@/components/remocn/backdrop";
 
const ZoomWordsScene = () => (
  <Backdrop
    fill={{
      type: "gradient",
      value: "linear-gradient(180deg, #0a0612 25%, #6a3fd6 100%)",
    }}
  >
    <ZoomWords text="Still piecing together tools" />
  </Backdrop>
);
 
export const RemotionRoot = () => (
  <Composition
    id="ZoomWords"
    component={ZoomWordsScene}
    durationInFrames={75}
    fps={30}
    width={1280}
    height={720}
  />
);

Syncing

The exported zoomWordsLength(text, wordGap) helper returns the frame on which the camera settles after the last word — cut to the next scene at or shortly after it.

Props10

PropTypeDefault
textrequired
string—

The phrase to reveal; it may be arbitrarily long

wordGap
number12

Frames between word reveals

fontSize
number64

Base font size in pixels before the camera zoom

zoom
number2.2

Camera scale applied to the whole shot

anchor
number0.5

Horizontal fraction of the frame the camera holds — the first word appears centered on it

blur
number0.04

Starting defocus in em, sharpening to zero over blurFrames

blurFrames
number60

Frames the focus pull takes

color
string"#cfc2ff"

Text color (any valid CSS color)

fontWeight
number400

CSS font-weight

className
string—

Optional className passed to the underlying span

  • textrequiredstring

    The phrase to reveal; it may be arbitrarily long

  • wordGapnumber

    Frames between word reveals

    Default12

  • fontSizenumber

    Base font size in pixels before the camera zoom

    Default64

  • zoomnumber

    Camera scale applied to the whole shot

    Default2.2

  • anchornumber

    Horizontal fraction of the frame the camera holds — the first word appears centered on it

    Default0.5

  • blurnumber

    Starting defocus in em, sharpening to zero over blurFrames

    Default0.04

  • blurFramesnumber

    Frames the focus pull takes

    Default60

  • colorstring

    Text color (any valid CSS color)

    Default"#cfc2ff"

  • fontWeightnumber

    CSS font-weight

    Default400

  • classNamestring

    Optional className passed to the underlying span