Text that morphs from one string to the next, letters gliding to their new place.
Installation
Usage
import { MorphingText } from '@animate-ui/react/primitives/texts/morphing';
export function Tagline() {
return <MorphingText text={['Fast', 'Accessible', 'Animated']} loop />;
}Letters are animated one by one, so a line can break inside a word. Prefer texts short enough not to wrap.
Animation
- Each text holds for
holdDelay, then morphs into the next: letters both texts share glide to their new place (a shared layout animation), the others fade, blur (10px) and scale (0.8) in and out. Everything moves on a soft spring (stiffness: 125, damping: 25, mass: 0.4) without overshoot. - Emoji and accented letters stay whole.
- The cycle pauses off screen and in a hidden tab.
<AnimateUIProvider tempo>paces the default spring.- Under reduced motion, the texts keep cycling as a plain crossfade.
- Screen readers read the current text whole, not letter by letter. It is not a live region.
API Reference
MorphingText
| Prop | Type | Default |
|---|---|---|
text | string | string[] | - |
loop? | boolean | false |
holdDelay? | number | 2500 |
delay? | number | 0 |
initial? | TargetAndTransition | VariantLabels | boolean | { opacity: 0, scale: 0.8, filter: 'blur(10px)' } |
animate? | TargetAndTransition | VariantLabels | boolean | { opacity: 1, scale: 1, filter: 'blur(0px)' } |
exit? | TargetAndTransition | VariantLabels | { opacity: 0, scale: 0.8, filter: 'blur(10px)' } |
variants? | Variants | - |
transition? | Transition | { type: 'spring', stiffness: 125, damping: 25, mass: 0.4 } |
inView? | boolean | false |
inViewMargin? | string | '0px' |
inViewOnce? | boolean | true |
...props? | Omit<HTMLMotionProps<'span'>, 'children'> | - |