Skip to content

Word Wheel Cylinder

A rotating word wheel built on a real cylinder — derived radius, accumulated rotation, no backwards spin on the wrap.

DOM + CSS0 deps1 file · 7 KB TSXreduced-motion aware

ProSpatial 3Dplayfuleditorialminimal
Preview

Props

2000
100

The source is part of Pro

$27/month or $179 once. See Pro

No runtime dependencies
"use client";

import { useEffect, useRef, useState } from "react";

export function WordWheelCylinder({
  prefix = "Built for",
  words = ["barbers", "studios", "kitchens", "galleries", "makers"],
  interval = 2000,
  height = 100,
  tint = "#d6ff00",
}: {
  prefix?: string;
  words?: string[];
  interval?: number;
  /** Face height in px. The cylinder radius is derived from it. */
  height?: number;
  tint?: string;
}) {

  // ---------------------------------------------------------------
  // Full source available with a viberdy Pro subscription.
  // https://viberdy.dev/pricing
  // ---------------------------------------------------------------
}
Details

About this text effect

The rotating-word headline is everywhere and is usually a crossfade wearing a 3D costume. Building it as an actual cylinder takes two pieces of arithmetic and one piece of CSS plumbing. The radius is derived rather than chosen: for n faces of height h, the faces of a regular n-gon sit on a circle of radius h over two, divided by the tangent of pi over n — pick a number by eye instead and the faces overlap or leave gaps at the seams, and it breaks differently every time the word count changes. The rotation is accumulated rather than derived from the index, which is the subtler of the two: setting the angle to index times step makes the wheel spin backwards through every intermediate face at the moment the list wraps, so it looks wrong exactly once per cycle — just infrequent enough that it ships. Keeping a running total and always adding one step means it only ever turns one way, like a physical wheel. The plumbing is easy to get half right: perspective belongs on the parent of the 3D container while preserve-3d belongs on the container, and missing either flattens the children into the plane so the rotation still runs but reads as a fade. Every face needs its backface hidden, or the words on the far side show through the front ones as mirrored ghosts. The failure that costs the most time, though, is none of these: because every face is absolutely positioned, nothing inside the clipping box is in flow, so the box shrink-to-fits to zero width and hides the cylinder completely. There is no error and nothing in the console — the word simply never appears. An invisible sizing layer carrying all the words at zero height gives the box the max-content width of the widest, measured in the real font rather than guessed from a character count.

Curator’s note

Derive the angle from the index and the wheel spins backwards through every word once per cycle — rare enough to ship, obvious once seen.

Pairs well with

Pro
Pro
Trending
Pro