Animate Item Based On Position Within Parent

Utility
GSAP
JS
  • Animate item based on its horizontal position within parent
  • When .item is horizontally centered within .your-section, it will be at the middle of the GSAP Timeline
  • Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or horizontal scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
	document.querySelectorAll(".your-section").forEach((component) => {
  
		component.querySelectorAll(".item").forEach((item) => {
			gsap.context(() => {
				let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
				tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
				tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
        
				tl.to(item, { opacity: 0.1, scale: 0.5 });
				tl.to(".item-image", { scale: 1.2 }, "<");
        
				function animate() {
					const rect = item.getBoundingClientRect();
					const compRect = component.getBoundingClientRect();
					let progress = Math.max(0, Math.min(1, (compRect.right - rect.left) / (rect.width + compRect.width)));
					tl.progress(progress);
					requestAnimationFrame(animate);
				}
				requestAnimationFrame(animate);
			}, item);
		});
	});
});
</script>
  • Animate item based on its vertical position within parent
  • When .item is vertically centered within .your-section, it will be at the middle of the GSAP Timeline
  • Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
	document.querySelectorAll(".your-section").forEach((component) => {
  
		component.querySelectorAll(".item").forEach((item) => {
			gsap.context(() => {
				let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
				tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
				tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
        
				tl.to(item, { opacity: 0.1, scale: 0.5 });
				tl.to(".item-image", { scale: 1.2 }, "<");
        
				function animate() {
					const rect = item.getBoundingClientRect();
					const compRect = component.getBoundingClientRect();
					let progress = Math.max(0, Math.min(1, (compRect.bottom - rect.top) / (rect.height + compRect.height)));
					tl.progress(progress);
					requestAnimationFrame(animate);
				}
				requestAnimationFrame(animate);
			}, item);
		});
	});
});
</script>
Last Updated: Dec 3, 2025
  • Animate item based on its horizontal position within parent
  • When .item is horizontally centered within .your-section, it will be at the middle of the GSAP Timeline
  • Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or horizontal scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
	document.querySelectorAll(".your-section").forEach((component) => {
  
		component.querySelectorAll(".item").forEach((item) => {
			gsap.context(() => {
				let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
				tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
				tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
        
				tl.to(item, { opacity: 0.1, scale: 0.5 });
				tl.to(".item-image", { scale: 1.2 }, "<");
        
				function animate() {
					const rect = item.getBoundingClientRect();
					const compRect = component.getBoundingClientRect();
					let progress = Math.max(0, Math.min(1, (compRect.right - rect.left) / (rect.width + compRect.width)));
					tl.progress(progress);
					requestAnimationFrame(animate);
				}
				requestAnimationFrame(animate);
			}, item);
		});
	});
});
</script>
  • Animate item based on its vertical position within parent
  • When .item is vertically centered within .your-section, it will be at the middle of the GSAP Timeline
  • Animate the item's transforms or its parent's transform by placing it in a slider, marquee, or scroll
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", () => {
	document.querySelectorAll(".your-section").forEach((component) => {
  
		component.querySelectorAll(".item").forEach((item) => {
			gsap.context(() => {
				let tl = gsap.timeline({ paused: true, defaults: { ease: "none" } });
				tl.fromTo(item, { opacity: 0.1, scale: 0.5 }, { opacity: 1, scale: 1 });
				tl.fromTo(".item-image", { scale: 1.2 }, { scale: 1 }, "<");
        
				tl.to(item, { opacity: 0.1, scale: 0.5 });
				tl.to(".item-image", { scale: 1.2 }, "<");
        
				function animate() {
					const rect = item.getBoundingClientRect();
					const compRect = component.getBoundingClientRect();
					let progress = Math.max(0, Math.min(1, (compRect.bottom - rect.top) / (rect.height + compRect.height)));
					tl.progress(progress);
					requestAnimationFrame(animate);
				}
				requestAnimationFrame(animate);
			}, item);
		});
	});
});
</script>