Text Highlight on Scroll
Words progressively fill with color as you scroll through the text
animationtextscrollhighlightreading
Install dependencies
$npm install framer-motionPreview
Source Code
"use client";
import { useRef } from "react";
import { motion, useScroll, useTransform } from "framer-motion";
interface TextHighlightScrollProps {
text: string;
highlightColor?: string;
baseColor?: string;
className?: string;
}
function Word({
word,
progress,
start,
end,
highlightColor,
baseColor,
}: {
word: string;
progress: import("framer-motion").MotionValue<number>;
start: number;
end: number;
highlightColor: string;
baseColor: string;
}) {
const color = useTransform(progress, [start, end], [baseColor, highlightColor]);
return (
<motion.span style={{ color }} className="inline-block transition-colors">
{word}
</motion.span>
);
}
export default function TextHighlightScroll({
text,
highlightColor = "#fff",
baseColor = "rgba(255,255,255,0.2)",
className = "",
}: TextHighlightScrollProps) {
const containerRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start 0.8", "end 0.3"],
});
const words = text.split(" ");
const totalWords = words.length;
return (
<div ref={containerRef} className={`${className}`}>
<p className="flex flex-wrap text-2xl font-medium leading-relaxed md:text-3xl lg:text-4xl">
{words.map((word, i) => {
const start = i / totalWords;
const end = (i + 1) / totalWords;
return (
<Word
key={i}
word={word}
progress={scrollYProgress}
start={start}
end={end}
highlightColor={highlightColor}
baseColor={baseColor}
/>
);
})}
</p>
</div>
);
}