Spiral Text
Text set on a responsive spiral that tightens under pressure and ripples on release.
Demo
Press and hold to draw the coils closer. Release to send a wave past its resting shape.
Installation
pnpm dlx shadcn@latest add https://ui.arjayby1.xyz/r/spiral-text.jsonCode
import { SpiralText } from "@/components/ui/spiral-text";
export function Poster() {
return (
<SpiralText
text="THE CONTENT ARCHITECTURE · "
density={1}
tightenStrength={0.35}
rippleDuration={1800}
rotationSpeed={2}
className="max-w-2xl"
/>
);
}API reference
| Prop | Type | Default | Purpose |
|---|---|---|---|
text | string | Required | Repeats along the spiral path and names the graphic for assistive technology. |
density | number | 1 | Adjusts the number of resting turns between 0.65 and 1.6. |
tightenStrength | number | 0.35 | Controls how closely the coils draw together, clamped from 0.08 to 0.7. |
rippleDuration | number | 1800 | Sets the outward wave duration in milliseconds, with a 300ms minimum. |
rotating | boolean | true | Rotates the text clockwise. Set to false to pause at the current angle. |
rotationSpeed | number | 1 | Rotations per minute. Higher values spin faster. Non-positive or non-finite values use the default. |
className | string | None | Sets layout constraints such as width or placement. |
The text follows concentric circular rings. Pressing starts gathering the rings immediately, reaching full tension after 450ms. On release, a circular wave travels outward, swelling and fading each ring before it settles. Outer rings stay gathered until the wave reaches them. Repeated presses carry each ring's current position and velocity into the next motion, so you can interrupt a wave without abruptly stopping it. The interaction responds to mouse, touch, and pen input and stays still when the user requests reduced motion.
The text rotates by default while the dotted background stays fixed. Holding pauses rotation; releasing resumes it. Set rotating={false} to pause it independently. Rotation is disabled when the user requests reduced motion.
Use rotationSpeed to control the speed. For example, rotationSpeed={2} completes two turns per minute, while rotationSpeed={0.5} completes one turn every two minutes.
Glyph positions are calculated once per text or density change. Each interactive ring is drawn into a canvas cache after fonts load. The cache refreshes when its size, pixel density, font, or color changes. The Web Animations API transforms and fades these cached pixels without redrawing the text on every frame or press. SVG provides the initial rendering and the static homepage preview. Motion stops while the component is offscreen or the page is hidden.