Weight

The word being spoken swells from a light weight to a heavy one and relaxes as the voice moves on, with no layout shift

Installation
$ pnpm dlx shadcn@latest add @remocn/caption-weight

Usage

CaptionWeight takes a timed transcript and renders only the text block, so place it inside your own AbsoluteFill. See Positioning for safe placements and Get a transcript for producing captions.json.

Each word reserves the width of its heaviest weight, so the line never moves while a word gains weight. The ramp is only as smooth as the weights your font has: a variable font interpolates every step, a static family snaps to the nearest loaded weight. With @remotion/google-fonts, load the variable version of the family so every weight in between exists.

import { loadVariableFont } from "@remotion/google-fonts/Inter";
import { AbsoluteFill } from "remotion";
import { CaptionWeight } from "@/components/remocn/caption-weight";
import captions from "./captions.json";
 
const { fontFamily } = loadVariableFont("normal", { subsets: ["latin"] });
 
export const MyScene = () => (
  <AbsoluteFill
    style={{
      justifyContent: "flex-end",
      alignItems: "center",
      paddingBottom: 108,
      paddingInline: 192,
    }}
  >
    <div style={{ fontFamily }}>
      <CaptionWeight captions={captions} />
    </div>
  </AbsoluteFill>
);
Props
PropTypeDefaultDescription
captions
Caption[]—The timed transcript, in the `Caption` shape from `@remotion/captions`. Times are relative to the start of the surrounding `Sequence`.
combineTokensWithinMilliseconds
number1200How much speech one page may span before the next word starts a new page. Pages also break at the end of a sentence and on any pause of at least `holdMs` (300 ms minimum).
holdMs
number600How long a page stays after its last word when the next page is not already due. It fades out at the end of the hold.
fontSize
number64Font size in pixels.
fontWeight
number400Resting weight of every word that is not being spoken.
activeWeight
number900Weight the spoken word ramps to over about 150ms, then relaxes from when the next word starts.
color
string"#ffffff"Text colour.
shadow
booleantrueA tight text shadow that keeps the caption legible over bright footage.
className
string—Classes for the text block — width, font family, `uppercase`.