<div id="parallax-zoom-wrapper" class="images-2-3__sticky-container">
<div id="parallax-zoom-container" class="images-2-3__zoom-container">
<div class="images-2-3__image-overlay images-2-3__image-overlay--right">
<img class="images-2-3__image" src="public/images/parallax-image-3.png" />
</div>
<div class="images-2-3__image-overlay images-2-3__image-overlay--left">
<img class="images-2-3__image" src="public/images/parallax-image-3.png" />
</div>
<div class="images-2-3__main-image-container">
<img class="images-2-3__main-image parallax-zoom-image" src="public/images/parallax-image-3.png" alt="Parallax Image Example" />
</div>
</div>
</div>
.images-2-3 {
width: 100%;
display: flex;
justify-content: center;
height: 200vh;
&__sticky-container {
position: sticky;
top: 0;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
&__zoom-container {
position: relative;
width: 100%;
}
&__image-overlay {
position: absolute;
width: 12vw;
height: 16vw;
overflow: hidden;
transform-origin: center;
background-color: #94a3b8;
&--right {
right: 40vw;
bottom: 20vh;
}
&--left {
left: 40vw;
top: 20vh;
}
.block-2-3__image {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
}
}
&__main-image-container {
position: relative;
width: 34vw;
height: 34vh;
overflow: hidden;
transform-origin: center;
.block-2-3__main-image {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}
}
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
export function initializeZoomParallax() {
// GSAP Zoom-Parallax
const wrapper = document.getElementById('parallax-zoom-wrapper');
const container = document.getElementById('parallax-zoom-container');
const image = document.getElementsByClassName('parallax-zoom-image');
if (container && image) {
gsap.to(
container,
{
scale: 2.5,
ease: 'power1.out',
scrollTrigger: {
trigger: wrapper,
start: 'bottom bottom',
end: 'bottom top',
scrub: true
}
}
);
gsap.fromTo(
image,
{
scale: 1.3
},
{
scale: 1,
ease: 'power3.out',
scrollTrigger: {
trigger: wrapper,
start: 'bottom-=2% bottom',
end: 'bottom top',
markers: {startColor: "blue", endColor: "blue"},
toggleActions: "play none none reverse",
invalidateOnRefresh: true,
scrub: true
}
}
);
}
}