Docs
Scroll Based Character Reveal
Scroll Based Character Reveal
A text reveal effect which progressively reveals text character by character as you scroll.
AAttllaassUUIIiissaannooppeenn--ssoouurrcceelliibbrraarryyooffffeerriinnggaassuuiitteeooffpprreebbuuiillttaanniimmaatteeddccoommppoonneennttssffoorrRReeaacctt,,NNeexxtt..jjss,,aannddVVaanniillllaaJJSS..
Installation
Install the following dependencies:
npm install motion
Copy and paste the following code into your project.
components/atlas_ui/scroll-based-character-reveal.tsx
"use client";
import { useRef } from "react";
import { motion, MotionValue, useScroll, useTransform } from "motion/react";
interface ScrollBasedCharacterRevealProps {
text: string;
}
interface WordProps {
children: string;
scrollYProgress: MotionValue<number>;
range: [number, number];
}
interface CharacterProps {
children: string;
scrollYProgress: MotionValue<number>;
range: [number, number];
}
export const ScrollBasedCharacterReveal = ({
text,
}: ScrollBasedCharacterRevealProps) => {
const container = useRef(null);
const { scrollYProgress } = useScroll({
target: container,
offset: ["start 0.8", "start 0.3"],
});
const words = text.split(" ");
return (
<div className="flex flex-col items-center justify-center ">
<div className="h-[50vh]" />
<p
ref={container}
className="text-5xl font-bold max-w-5xl text-center flex flex-wrap"
>
{words.map((word, i) => {
const start = i / words.length;
const end = (start + i) / words.length;
return (
<Word
key={i}
range={[start, end]}
scrollYProgress={scrollYProgress}
>
{word}
</Word>
);
})}
</p>
<div className="h-[50vh]" />
</div>
);
};
const Word = ({ children, scrollYProgress, range }: WordProps) => {
const characters = children.split("");
const amount = range[1] - range[0];
const step = amount / children.length;
return (
<span className="mr-2 mt-1 relative">
{characters.map((character, i) => {
const start = range[0] + step * i;
const end = range[0] + step * (i + 1);
return (
<Character
key={i}
range={[start, end]}
scrollYProgress={scrollYProgress}
>
{character}
</Character>
);
})}
</span>
);
};
const Character = ({ children, scrollYProgress, range }: CharacterProps) => {
const opacity = useTransform(scrollYProgress, range, [0, 1]);
return (
<span className="relative">
<span className="absolute opacity-10">{children}</span>
<motion.span style={{ opacity }}>{children}</motion.span>
</span>
);
};
Update the import paths to match your project setup.
Usage
import { ScrollBasedCharacterReveal } from "@/components/atlas_ui/scroll-based-character-reveal";
<ScrollBasedCharacterReveal text="AtlasUI is an open-source library offering a suite of prebuilt animated components for React, Next.js, and Vanilla JS." />