Scroll trigger image

JS
				
					<p>gsap.registerPlugin(ScrollTrigger);</p>
<p>// Initialize Lenis smooth scrolling<br />
const lenis = new Lenis();<br />
lenis.on(“scroll”, ScrollTrigger.update);<br />
gsap.ticker.add((time) =&gt; {<br />
lenis.raf(time * 1000);<br />
});<br />
gsap.ticker.lagSmoothing(0);</p>
<p>const pinnedSection = document.querySelector(“.pinned”);<br />
const pinnedHeight = window.innerHeight * 10; // Adjust based on your layout<br />
const images = gsap.utils.toArray(“.img”);</p>
<p>function animateImageEntry(img) {<br />
gsap.fromTo(<br />
img,<br />
{<br />
scale: 1.25,<br />
clipPath: “polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%)”,<br />
opacity: 0,<br />
},<br />
{<br />
scale: 1,<br />
clipPath: “polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)”,<br />
opacity: 1,<br />
duration: 1,<br />
ease: “power2.inOut”,<br />
}<br />
);</p>
<p>gsap.fromTo(<br />
img.querySelector(“img”),<br />
{<br />
filter: “contrast(2) brightness(10)”,<br />
},<br />
{<br />
filter: “contrast(1) brightness(1)”,<br />
duration: 1,<br />
ease: “power2.inOut”,<br />
}<br />
);<br />
}</p>
<p>function animateImageExitForward(img) {<br />
gsap.to(img, {<br />
scale: 0.5,<br />
opacity: 0,<br />
duration: 1,<br />
ease: “power2.inOut”,<br />
});<br />
}</p>
<p>function animateImageExitReverse(img) {<br />
gsap.to(img, {<br />
scale: 1.25,<br />
clipPath: “polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%)”,<br />
duration: 1,<br />
ease: “power2.inOut”,<br />
});</p>
<p>gsap.to(img.querySelector(“img”), {<br />
filter: “contrast(2) brightness(10)”,<br />
duration: 1,<br />
ease: “power2.inOut”,<br />
});<br />
}</p>
<p>// Start by animating the first image if it exists<br />
if (images.length &gt; 0) {<br />
animateImageEntry(images[0]);<br />
}</p>
<p>let lastCycle = 0;</p>
<p>ScrollTrigger.create({<br />
trigger: pinnedSection,<br />
start: “top top”,<br />
end: `+=${pinnedHeight} * 2`,<br />
pin: true,<br />
pinSpacing: true,<br />
scrub: 0.1,<br />
onUpdate: (self) =&gt; {<br />
const totalProgress = self.progress * images.length; // Adjust for the number of images<br />
const currentCycle = Math.floor(totalProgress);<br />
const cycleProgress = (totalProgress % 1) * 100;</p>
<p>if (currentCycle 0) {<br />
if (lastCycle &lt; images.length) animateImageExitForward(images[lastCycle]);<br />
if (currentCycle &lt; images.length) {<br />
animateImageEntry(images[currentCycle]);<br />
}<br />
} else {<br />
if (currentCycle &lt; images.length) {<br />
animateImageEntry(images[currentCycle]);<br />
}<br />
if (lastCycle &lt; images.length) animateImageExitReverse(images[lastCycle]);<br />
}<br />
lastCycle = currentCycle;<br />
}<br />
}<br />
},<br />
});</p>

				
			
CSS
Live Preview
Trigger Class: