Text Reveal
Reveal text line by line with blur, opacity, and a character wave. Scroll through the pinned preview to control its progress.
You love them so much it hurts, but you keep loving them. They come back after getting bored with other people, just enough to keep you hooked. And you hold on to that as hope, that they will be yours one day.
How it works
Text reveals one line and character at a time with opacity, blur, and a small vertical wave. By default the sequence begins when it enters the viewport. Pass a Motion scroll progress value to pin a preview, scrub the reveal forward and backward, and release the page when it completes.
Accessibility
The complete text is available as one screen-reader string while the animated glyphs are hidden from assistive technology. Reduced-motion preferences show the text without the entrance animation or scroll pinning.
Limitations
Pass plain text and use newline characters to define line breaks. Scroll-linked mode requires a MotionValue from useScroll and a parent with enough scroll distance to complete the reveal.
Features
- Reveals plain text line by line and character by character.
- Keeps words together when lines wrap naturally.
- Configure character stagger, line spacing, duration, blur, opacity, scale, vertical wave, and horizontal drift.
- Use viewport-triggered animation by default, or supply Motion scroll progress for reversible scroll-linked control.
- Tune the viewport trigger threshold and whether it runs once or again on re-entry.
- Provides a single accessible text string and respects reduced-motion preferences.
Installation
Choose the CLI command or install the component manually.
$ npx @istmx/ui add text-revealCopies the install command for your selected package manager.
Dependencies
Usage
Import the component from the file you copied it to, then use it like any other React component.
import TextReveal from '@/components/ui/text-reveal' <TextReveal text={'Every word arrives softly,\none character at a time.'} characterStagger={0.028} lineStagger={0.2} duration={0.65} waveDistance={8} waveOvershoot={6} sidewaysDistance={1.5} blurAmount={6} opacityFrom={0.08} opacityPeak={0.72} scaleFrom={0.96} scalePeak={1.025} once/>Composition
TextReveal├── Screen-reader text└── Line wrappers └── Word-safe animated charactersAPI reference
textstringPlain text to reveal. Use newline characters to set explicit line breaks.
characterStagger?numberIn viewport mode, seconds between character starts. In scroll mode, relative scroll weight per character. Defaults to 0.024.
lineStagger?numberIn viewport mode, seconds between lines. In scroll mode, relative scroll weight between lines. Defaults to 0.24.
duration?numberCharacter transition duration in seconds for viewport mode. Defaults to 0.7.
waveDistance?numberVertical travel distance in pixels for the character wave. Defaults to 5.
waveOvershoot?numberDistance in pixels each character rises above its resting baseline before settling. Defaults to 75% of waveDistance.
sidewaysDistance?numberHorizontal drift in pixels during the character wave. Defaults to 12% of waveDistance.
blurAmount?numberStarting blur in pixels, which resolves as each character settles. Defaults to 7.
opacityFrom?numberStarting character opacity from 0 to 1. Defaults to 0.08.
opacityPeak?numberIntermediate character opacity from 0 to 1 during the wave. Defaults to 0.72.
scaleFrom?numberStarting character scale. Defaults to 0.96.
scalePeak?numberIntermediate character scale during the wave. Defaults to 1.025.
scrollProgress?MotionValue<number>Optional 0–1 Motion value, usually from useScroll. When provided, scroll controls the reveal and scrolling backward reverses it.
once?booleanIn viewport mode, reveal once or replay after leaving and re-entering. Defaults to true.
viewportAmount?numberFraction of the component that must enter the viewport before revealing, from 0 to 1. Defaults to 0.4.
className?stringAdditional classes for the paragraph wrapper.
The listed props match the current component implementation.
Data attributes
Text Reveal does not expose custom data attributes.
Examples
Use scrollProgress from Motion useScroll to make a pinned story reveal scrub forward and backward with the page. Without it, the component starts when it enters the viewport.
Credits & inspiration
Created by Aryan (istmX) for ISTMX. The source-first, copy-and-own philosophy is inspired by shadcn/ui. About the creator