Style Library
Text Loop
AnimationanimationText animation that transitions between multiple items, creating an engaging looping effect.
Prompt
Paste into any AI assistant before describing what to build — or attach it to a project below.
# Animation pattern — Text Loop
Text animation that transitions between multiple items, creating an engaging looping effect.
Build it in React with `motion` (motion/react) and Tailwind CSS. Respect `prefers-reduced-motion` (render the final state without movement), keep it under ~400 ms for UI feedback, and animate only transform and opacity where possible.
Reference implementation (Motion-Primitives, MIT):
```tsx
'use client';
import { cn } from '@/lib/utils';
import {
motion,
AnimatePresence,
Transition,
Variants,
AnimatePresenceProps,
} from 'motion/react';
import { useState, useEffect, Children } from 'react';
export type TextLoopProps = {
children: React.ReactNode[];
className?: string;
interval?: number;
transition?: Transition;
variants?: Variants;
onIndexChange?: (index: number) => void;
trigger?: boolean;
mode?: AnimatePresenceProps['mode'];
};
export function TextLoop({
children,
className,
interval = 2,
transition = { duration: 0.3 },
variants,
onIndexChange,
trigger = true,
mode = 'popLayout',
}: TextLoopProps) {
const [currentIndex, setCurrentIndex] = useState(0);
const items = Children.toArray(children);
useEffect(() => {
if (!trigger) return;
const intervalMs = interval * 1000;
const timer = setInterval(() => {
setCurrentIndex((current) => {
const next = (current + 1) % items.length;
onIndexChange?.(next);
return next;
});
}, intervalMs);
return () => clearInterval(timer);
}, [items.length, interval, onIndexChange, trigger]);
const motionVariants: Variants = {
initial: { y: 20, opacity: 0 },
animate: { y: 0, opacity: 1 },
exit: { y: -20, opacity: 0 },
};
return (
<div className={cn('relative inline-block whitespace-nowrap', className)}>
<AnimatePresence mode={mode} initial={false}>
<motion.div
key={currentIndex}
initial='initial'
animate='animate'
exit='exit'
transition={transition}
variants={variants || motionVariants}
>
{items[currentIndex]}
</motion.div>
</AnimatePresence>
</div>
);
}
```Use it in an app
Create a free account to attach this style to a project: the hub adds it to the prompt your AI assistant gets, so it builds every page in this look.
From Motion-Primitives (MIT, commit 120f64f).View source