EdilEdilozioziwillwillelevateelevateyouryourdesigndesignexperience.experience.
Installation
Copy and paste the following code into your project.
components/edil-ozi/text-reveal.tsx
"use client";
import { cn } from "@/lib/utils";
import { MotionValue, motion, useScroll, useTransform } from "framer-motion";
import { FC, ReactNode, useRef } from "react";
interface Props {
paragraph: string;
className?: string;
}
const TextRevealByWord: FC<Props> = ({ paragraph, className }) => {
const targetRef = useRef<HTMLDivElement | null>(null);
const { scrollYProgress } = useScroll({
target: targetRef,
});
const words = paragraph.split(" ");
return (
<div
ref={targetRef}
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-[1rem] py-[5rem]">
<p
ref={targetRef}
className="flex flex-wrap p-5 text-2xl font-bold text-black/20 dark:text-white/20 md:p-8 md:text-3xl lg:p-10 lg:text-4xl xl:text-5xl"
>
{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>
);
})}
</p>
</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-2.5">
<span className={"absolute opacity-30"}>{children}</span>
<motion.span
style={{ opacity: opacity }}
className="text-black dark:text-white"
>
{children}
</motion.span>
</span>
);
};
export default TextRevealByWord;
Props
Prop | Type | Description | Default |
---|---|---|---|
className | string | The class name to be applied to the shimmer. | |
text | string | The text to do the animation for | "" |