Fancy Text
scrollxui/fancy-textFreeComponent
A refined text reveal animation with smooth character motion and a clean, modern visual flow.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/fancy-text.jsonSource
1'use client';23import React, { useLayoutEffect, useRef, useState } from 'react';4import { motion } from 'motion/react';5import { cn } from '@/lib/utils';67interface FancyTextProps {8 children: string;9 className?: string;10 fillClassName?: string;11 stagger?: number;12 duration?: number;13 delay?: number;14}1516const FancyText = React.forwardRef<HTMLSpanElement, FancyTextProps>(17 (18 {19 children,20 className = 'text-5xl font-black leading-none text-black/10 dark:text-white/10',21 fillClassName = 'text-black dark:text-white',22 stagger = 0.08,23 duration = 1.4,24 delay = 0,25 },26 ref,27 ) => {28 const spanRef = useRef<HTMLSpanElement>(null);29 const finalRef = (ref ?? spanRef) as React.RefObject<HTMLSpanElement>;3031 const chars = children.split('');32 const [hideBase, setHideBase] = useState(false);33 const [isSmall, setIsSmall] = useState(false);3435 useLayoutEffect(() => {36 if (!finalRef.current) return;37 const size = parseFloat(getComputedStyle(finalRef.current).fontSize);38 setIsSmall(size < 28);39 }, [finalRef]);4041 return (42 <span ref={finalRef} className='relative inline-block'>43 <span44 className={cn(className)}45 style={{ opacity: hideBase && isSmall ? 0 : 1 }}46 >47 {children}48 </span>4950 <span className='absolute inset-0 flex overflow-hidden'>51 {chars.map((char, i) => (52 <motion.span53 key={i}54 className={cn(className, fillClassName)}55 initial={{ clipPath: 'inset(100% 0% 0% 0%)' }}56 animate={{ clipPath: 'inset(0% 0% 0% 0%)' }}57 transition={{58 duration,59 delay: delay + i * stagger,60 ease: [0.25, 0.1, 0.25, 1],61 }}62 onAnimationComplete={() => {63 if (i === chars.length - 1 && isSmall) setHideBase(true);64 }}65 style={{66 display: 'inline-block',67 whiteSpace: char === ' ' ? 'pre' : 'normal',68 }}69 >70 {char === ' ' ? '\u00A0' : char}71 </motion.span>72 ))}73 </span>74 </span>75 );76 },77);7879FancyText.displayName = 'FancyText';80export { FancyText };
What it pulls in
npm packages
Other registry items
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | scrollxui | Components | Free | 2 deps | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Announcementannouncement | scrollxui | Components | Free | 5 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep |
