<div class="stacked-cards-container">
<div class="card-container">
<div class="card" style="background-color: #f8f9fa;">
<h2>Panel 1</h2>
</div>
</div>
<div class="card-container">
<div class="card" style="background-color: #e9ecef;">
<h2>Panel 2</h2>
</div>
</div>
<div class="card-container">
<div class="card" style="background-color: #dee2e6;">
<h2>Panel 3</h2>
</div>
</div>
<div class="card-container">
<div class="card" style="background-color: #ced4da;">
<h2>Panel 4</h2>
</div>
</div>
</div>
.blocks-3-2 {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.stacked-cards-container {
height: 400vh; // 4 cards × 100vh donc 5 cards = 500vh
position: relative;
}
.card-container {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
position: sticky;
top: 0px;
.card {
display: flex;
align-items: center;
justify-content: center;
position: relative;
top: 0;
height: 500px;
width: 1000px;
border-radius: 0;
padding: 0;
transform-origin: center;
h2 {
text-align: center;
margin: 0;
font-size: 48px;
color: #333;
font-weight: 300;
letter-spacing: 2px;
}
}
}
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
export function initializeHorizontalScroll() {
const container = document.querySelector(".stacked-cards-container");
const cards = gsap.utils.toArray(".card");
if (!container || cards.length === 0) {
console.log("Éléments de cartes empilées introuvables");
return;
}
console.log("Trouvé", cards.length, "cartes");
ScrollTrigger.getAll().forEach(t => t.kill());
// progress scroll
const scrollProgress = ScrollTrigger.create({
trigger: container,
start: "top top",
end: "bottom bottom",
scrub: 1,
onUpdate: (self) => {
const progress = self.progress;
cards.forEach((card, index) => {
const cardContainer = card.closest('.card-container');
const cardIndex = cards.indexOf(card);
const baseScale = 0.85 + (cardIndex * 0.05);
const targetScale = baseScale + 0.15;
const startRange = cardIndex * 0.25;
const endRange = Math.min(startRange + 0.25, 1);
// mapping
const cardProgress = Math.max(0, Math.min(1, (progress - startRange) / (endRange - startRange)));
// le scale effect
const currentScale = gsap.utils.interpolate(baseScale, targetScale, cardProgress);
const yOffset = cardIndex * 25;
gsap.set(card, {
scale: currentScale,
y: yOffset,
zIndex: cards.length - cardIndex
});
});
}
});
// refresh
ScrollTrigger.refresh();
}