Scroll Text Scrub

Scroll
Text Animation
GSAP
ScrollTrigger
Split Text
JS
Last Updated: Nov 10, 2025
  • Adjust colors from css embed
<style>
:root {
	--scroll-4-color-1: grey;
	--scroll-4-color-2: blue;
}
.scroll-4_text .word {
	--progress: 0%;
	padding-top: 0.6em;
	margin-top: -0.6em;
	padding-bottom: 0.6em;
	margin-bottom: -0.6em;
	color: transparent;
	background-color: var(--scroll-4-color-1);
	background-image: linear-gradient(90deg, var(--scroll-4-color-2), var(--scroll-4-color-2) var(--progress), transparent var(--progress));
	background-clip: text;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/SplitText.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
	gsap.registerPlugin(ScrollTrigger);
	document.querySelectorAll(".scroll-4_text").forEach(function (component) {
		if (component.hasAttribute("data-scroll-4")) return;
		component.setAttribute("data-scroll-4", "");
    
		const split = SplitText.create(component, { type: "words", wordsClass: "word" });
    
		const tl = gsap.timeline({
			scrollTrigger: {
				trigger: component,
				start: "clamp(top center)",
				end: "clamp(bottom center)",
				scrub: 1,
			},
		});
		tl.fromTo(split.words, { "--progress": "0%" }, { "--progress": "100%", stagger: 0.5, ease: "none" });
	});
});
</script>