Inline Word Roll

Switch words beside a fixed prefix with an accelerating vertical roll

Installation
$ pnpm dlx shadcn@latest add @remocn/inline-word-roll

Usage

The prefix remains on the baseline while the changing word rolls upward through a softly masked slot. The next word arrives from below. The whole line smoothly recenters as the word width changes, and successive switches get closer together. The first word starts readable and the final word stays on screen.

import { AbsoluteFill } from "remotion";
import { InlineWordRoll } from "@/components/remocn/inline-word-roll";
 
export const Headline = () => (
  <AbsoluteFill style={{ background: "#000" }}>
    <InlineWordRoll
      prefix="Looking for"
      text="leads | customers | subscribers | appointments | demos | quotes | registrants | trials | conversions"
      suffix="?"
    />
  </AbsoluteFill>
);

The default sequence finishes moving at frame 75. The demo adds a 30-frame final hold. All durations use composition frames; at 30 fps the movement takes about 2.5 seconds. Set acceleration={1} for a steady pace. Faster intervals never become shorter than the roll itself, so transitions cannot overlap.

Words and phrases are separated by | or newlines. Spaces inside a phrase are preserved. Empty entries are ignored. The component has a transparent background; add your own scene or texture behind it.

Props

PropTypeDefaultDescription
prefix
string"Looking for"Text that stays on the baseline. Its horizontal position follows the changing total width.
text
string"leads | customers | … | conversions"Words or phrases separated by | or newlines.
suffix
string"?"Appended to every changing word and rolls with it.
fontSize
number60Font size in composition pixels. The whole line scales down to fit the longest phrase within 84% of frame width.
fontFamily
string"Arial, Helvetica, sans-serif"Font family. Load custom font faces in your composition; measurement waits for the selected face.
fontWeight
number400Font weight.
color
string"#f5f5f5"Text color.
interval
number12Initial frames between switch starts. Also the first-word hold; never shorter than transitionFrames.
acceleration
number0.9Multiplier for each following interval, clamped to 0.5–1. Lower values accelerate faster; 1 gives constant timing.
transitionFrames
number6Duration of each upward roll, clamped to at least 1 frame.

For custom sequences, getInlineWordRollDuration({ text, interval, acceleration, transitionFrames }) returns the number of frames until the last word settles. Add your desired hold when choosing the composition or Sequence duration. A single phrase needs no transition and returns 0.

Widths are measured in unscaled composition pixels after fonts load and again when the text or font changes, preserving layout inside resized Players. The same scale is used for every word, preventing font-size jumps. All movement comes from Remotion frames; seeking directly to a switch reproduces the same layout. No CSS animation clock or WebGL context is required.