3D Rolling Text
Scroll-driven 3D cylinder of text — lines are mounted on an invisible drum and rotate into view one after another as you scroll.
This is a WebberUI Pro component
Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.
npx shadcn@latest add "https://webberui.com/r/3d-rolling-text.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<3dRollingText />
Installation
npx shadcn@latest add "https://webberui.com/r/3d-rolling-text.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/3d-rolling-text.
Usage
import { RollingText3D } from "@/components/ui/3d-rolling-text";
<RollingText3D
lines={["Design", "Animate", "Prototype", "Ship"]}
lineClassName="text-5xl font-bold tracking-tight"
/>The component itself is a scrollable track (total height = stageHeight + (number of lines - 1) * stepHeight) with a sticky stage pinning the visuals in place. Drop it into a page, and scrolling past the track completes one full rotation of the drum.
Nested scroll container
If the animation happens inside an overflow-y: auto container rather than the whole page, pass the container's ref to container:
const scrollerRef = React.useRef<HTMLDivElement>(null);
<div ref={scrollerRef} className="h-[300px] overflow-y-auto">
<RollingText3D lines={words} container={scrollerRef} />
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
lines | string[] | — | The lines of text on the cylinder's faces, rotating into view in order as you scroll |
stepHeight | number | 160 | Scroll distance allotted to each line (px); larger turns more slowly |
stageHeight | number | 200 | Height of the sticky stage (px) |
lineHeight | number | 56 | Line height (px), which also determines the cylinder radius |
perspective | number | 900 | 3D perspective distance (px); smaller exaggerates the perspective |
direction | "up" | "down" | "up" | up rolls new lines in from below toward the front face, down rolls them in from above |
minFaces | number | 6 | Minimum number of faces the cylinder is divided into, so the drum keeps its curvature even with few lines |
container | React.RefObject<HTMLElement | null> | — | Ref of the nested scroll container; defaults to the window as the scroll container |
className | string | — | Class applied to the whole scroll track |
lineClassName | string | — | Class applied to each line of text (font size, weight, color) |
How it works
- Cylinder geometry: the radius is derived as
lineHeight / 2 / tan(π / faces), so adjacent faces meet exactly on the drum with no gap and no overlap as it turns - Scroll mapping:
useScrolltakes the track's progress, and traversing the whole track rotates exactly the last line to the front ((number of lines - 1) × angle per face). Stopping partway holds the corresponding angle, and it can be reversed - Angular fade: each line's opacity comes from its angular distance from the front — fully lit at the front, half-transparent on the adjacent faces, and gone beyond that, with
backface-visibility: hiddenas a backstop against mirrored glyphs - With few lines:
minFacessets a floor on the number of faces, so three or four lines still keep the drum's curvature instead of degenerating into a flat page flip
Accessibility
- When the user has "reduce motion" enabled at the system level, the 3D and sticky behavior are dropped and all lines are rendered as a static vertical list
- The complete text is exposed
sr-onlyto assistive technology and the entire 3D visual layer isaria-hidden, so what is announced is continuous, complete content - Purely scroll-driven, never autoplaying: animation progress follows the user's scrolling exactly and can be stopped or reversed at any time
Handwriting Text
Handwriting animation drawn stroke by stroke with SVG pathLength, with a built-in single-line font and support for custom signature paths.
Typewriter Text
The classic typewriter effect — text typed out character by character with a blinking cursor, with looping and deletion across multiple strings.