"use client";
import {
useScroll,
motion,
useTransform,
useMotionTemplate,
} from "framer-motion";
import Lenis from "lenis";
import { useEffect, useRef } from "react";
type CardProps = {
text?: string;
};
export default function TextReveal({ text }: CardProps) {
useEffect(() => {
const lenis = new Lenis();
function raf(time: any) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
}, []);
const containerRef = useRef(null);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start start", "end end"],
});
// Reveal progress (0 → 100%)
const reveal = useTransform(scrollYProgress, [0, 1], [100, 0]);
// Smooth gradient mask
const mask = useMotionTemplate`
linear-gradient(
to right,
black 0%,
black ${reveal}%,
transparent calc(${reveal}% + 0%)
)
`;
const barPosition = useTransform(scrollYProgress, [0, 1], ["100%", "0%"]);
return (
<div ref={containerRef} className="relative h-[50vh] w-full cursor-default">
<div className="sticky top-0 h-full flex items-center justify-center">
<div className="relative">
<p className="absolute top-0 left-0 text-[#9c8e8e] uppercase font-bold text-[8vw] opacity-10 leading-[7.5vw] m-0 z-[1]">
{text || "HELLO"}
</p>
<motion.div
style={{
WebkitMaskImage: mask,
maskImage: mask,
}}
className="relative z-[2]"
>
<p className="text-[#b7ab98] uppercase font-bold text-[8vw] leading-[7.5vw] m-0">
{text || "HELLO"}
</p>
</motion.div>
<motion.div
style={{ left: barPosition }}
className="absolute top-0 h-full w-[3px] bg-[#b7ab98] z-[3] shadow-[0_0_20px_#b7ab98]"
/>
</div>
</div>
</div>
);
}