All components
Text Reveal
textFade in text as you scroll down the page.
responsive · 640px
Install
Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:
$
npx shadcn@latest add https://your-domain/r/text-reveal.jsonUsage
"use client";
import { TextReveal } from "@/registry/magic-ui/text-reveal";
export default function Demo() {
return (
<div className="w-full max-w-4xl">
<TextReveal>
Magic UI is a collection of re-usable components that you can copy and paste into your web apps.
</TextReveal>
</div>
);
}Component source
"use client"
import {
useRef,
type ComponentPropsWithoutRef,
type FC,
type ReactNode,
} from "react"
import { motion, MotionValue, useScroll, useTransform } from "motion/react"
import { cn } from "@/lib/utils"
export interface TextRevealProps extends ComponentPropsWithoutRef<"div"> {
children: string
}
export const TextReveal: FC<TextRevealProps> = ({ children, className }) => {
const sectionRef = useRef<HTMLDivElement | null>(null)
const { scrollYProgress } = useScroll({
target: sectionRef,
})
if (typeof children !== "string") {
throw new Error("TextReveal: children must be a string")
}
const words = children.split(" ")
return (
<div ref={sectionRef} className={cn("relative z-0 h-[200vh]", className)}>
<div
className={
"sticky top-0 mx-auto flex h-[50%] max-w-4xl items-center bg-transparent px-4 py-20"
}
>
<span
className={
"flex flex-wrap p-5 text-2xl font-bold text-black/20 md:p-8 md:text-3xl lg:p-10 lg:text-4xl xl:text-5xl dark:text-white/20"
}
>
{words.map((word, i) => {
const start = i / words.length
const end = start + 1 / words.length
return (
<Word key={i} progress={scrollYProgress} range={[start, end]}>
{word}
</Word>
)
})}
</span>
</div>
</div>
)
}
interface WordProps {
children: ReactNode
progress: MotionValue<number>
range: [number, number]
}
const Word: FC<WordProps> = ({ children, progress, range }) => {
const opacity = useTransform(progress, range, [0, 1])
return (
<span className="xl:lg-3 relative mx-1 lg:mx-1.5">
<span className="absolute opacity-30">{children}</span>
<motion.span
style={{ opacity: opacity }}
className={"text-black dark:text-white"}
>
{children}
</motion.span>
</span>
)
}Dependencies
motion
Source: Magic UI