Scroll-driven text for React that moves as you scroll, creating a bold animated backdrop. Built with GSAP.
41Moodisa86trip
Between61Tangible
and5621inconscious
Cross25conflicting
emotionsand47reveals
08blissin13innermost
"use client";
import { useGSAP } from "@gsap/react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { Montserrat, Source_Serif_4 } from "next/font/google";
import GsapLenisProvider from "@/providers/gsap-lenis-provider";
gsap.registerPlugin(ScrollTrigger);
const sourceSerif = Source_Serif_4({
subsets: ["latin"],
weight: ["200"],
});
const montserrat = Montserrat({
subsets: ["latin"],
weight: ["600"],
});
const sourceSerifFont = sourceSerif.className;
const montserratFont = montserrat.className;
const MoodTextBackgroundDemo: React.FC = () => {
useGSAP(() => {
const lines = gsap.utils.toArray(".bg-text p") as HTMLElement[];
lines.forEach((line, index) => {
gsap.set(line, {
xPercent: index % 2 === 0 ? -20 : 20,
});
gsap.to(line, {
duration: 0.1,
scrollTrigger: {
end: "bottom top",
scrub: true,
start: "top bottom",
trigger: "#scroll-text-background",
},
xPercent: index % 2 === 0 ? 10 : -10,
});
});
});
return (
<div className="bg-[#101010] w-full">
<GsapLenisProvider className="h-full w-full">
<div className="grid h-svh w-full place-items-center">
<span className="font-medium font-serif text-background text-sm md:text-2xl">
Scroll to see the animation
</span>
</div>
<section
className="relative flex h-svh w-full items-center justify-center overflow-hidden bg-[#101010]"
id="scroll-text-background"
>
<div
className={`pointer-events-none absolute top-1/2 left-1/2 z-1 flex h-fit w-fit -translate-x-1/2 -translate-y-1/2 flex-col gap-4 bg-text font-extralight text-muted text-xl sm:text-3xl md:text-5xl uppercase opacity-40 lg:text-6xl lg:opacity-20 xl:text-7xl 2xl:text-8xl ${sourceSerifFont}`}
>
<p className="flex items-center">
<span className="relative">
<span
className={`absolute top-1/2 right-14 -translate-y-1/2 font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
41
</span>
Mood
</span>
<span className="flex-1 text-center">is</span>
<span className="flex-1 text-center">a</span>
<span
className={`mr-4 font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
86
</span>
<span>trip</span>
</p>
<p className="flex items-center">
<span>Between</span>
<span
className={`flex-1 text-center font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
61
</span>
<span>Tangible</span>
</p>
<p className="flex items-center">
<span>and</span>
<span
className={`flex-1 text-center font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
56
</span>
<span className="relative">
<span
className={`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
21
</span>
inconscious
</span>
</p>
<p className="flex items-center justify-between">
<span>Cross</span>
<span
className={`mr-4 flex-1 text-center font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
25
</span>
<span>conflicting</span>
</p>
<p className="flex items-center gap-8">
<span>emotions</span>
<span>and</span>
<span className="relative">
<span
className={`absolute top-1/2 right-28 -translate-y-1/2 font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
47
</span>
reveals
</span>
</p>
<p className="flex items-center">
<span className="relative flex-1 text-center">
<span
className={`absolute top-1/2 right-14 -translate-y-1/2 font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
08
</span>
bliss
</span>
<span className="flex-1 text-center">in</span>
<span
className={`mr-8 ml-12 font-bold text-red-500 text-xs lg:text-lg xl:text-xl ${montserratFont}`}
>
13
</span>
<span>innermost</span>
</p>
</div>
</section>
<div className="grid h-svh w-full place-items-center">
<span className="font-medium font-serif text-background text-sm md:text-2xl">
Back to very top to repeat
</span>
</div>
</GsapLenisProvider>
</div>
);
};
export { MoodTextBackgroundDemo };Install the following dependencies:
npm install gsap @gsap/react lenisbun add gsap @gsap/react lenisdeno add gsap @gsap/react lenispnpm add gsap @gsap/react lenisyarn add gsap @gsap/react lenisThis section uses the GsapLenisProvider.