<div class="container">
<h2 class="title">Lorem ipsum dolor sit amet consectetur, adipisicing elit</h2>
<ul class="cards">
<li class="cards__item">
<div class="cards__content">1</div>
</li>
<li class="cards__item">
<div class="cards__content">2</div>
</li>
<li class="cards__item">
<div class="cards__content">3</div>
</li>
<li class="cards__item">
<div class="cards__content">4</div>
</li>
<li class="cards__item">
<div class="cards__content">5</div>
</li>
</ul>
</div>
body {
margin: 0;
min-height: 5000px;
}
.container {
width: 75%;
margin: 0 auto;
margin-top: 35vh;
}
.cards {
margin: 0;
list-style: none;
padding: 0;
}
.cards__content {
display: flex;
justify-content: center;
align-items: center;
font-size: 3rem;
color: #fff;
border-radius: 15px;
height: 40vh;
min-height: 300px;
margin-bottom: 25px;
transform: translate(0, 0);
will-change: transform;
}
.cards__item:nth-child(1) .cards__content {
background-color: #f44336;
}
.cards__item:nth-child(2) .cards__content {
background-color: #e91e63;
}
.cards__item:nth-child(3) .cards__content {
background-color: #9c27b0;
}
.cards__item:nth-child(4) .cards__content {
background-color: #673ab7;
}
.cards__item:nth-child(5) .cards__content {
background-color: #2196f3;
}
const container = document.querySelector(".container");
const title = document.querySelector(".title");
const cards = document.querySelector(".cards");
const items = [document.querySelectorAll(".cards__item")];
const controller = new ScrollMagic.Controller();
new ScrollMagic.Scene({
offset: 0,
triggerHook: 0,
triggerElement: container,
duration: () =>
container.offsetHeight -
cards.querySelector(".cards__item:last-child").offsetHeight -
title.offsetHeight
})
// .addIndicators() // add indicators (requires plugin)
.setPin(title, { pushFollowers: false })
.addTo(controller);
items.forEach((item, idx) => {
const isLast = idx === items.length - 1;
const content = item.querySelector(".cards__content");
new ScrollMagic.Scene({
offset: item.offsetHeight - title.offsetHeight,
triggerHook: 0.5,
triggerElement: item,
duration: () => (isLast ? 0 : item.offsetHeight)
})
// .addIndicators() // add indicators (requires plugin)
.addTo(controller)
.on("progress", (e) => {
const p = isLast ? 0 : e.progress;
const ty = item.offsetHeight * p;
const scale = (1 - p) * 1 + p * 0.7;
const opacity = 1 - p;
content.style.transform = `translateY(${ty}px) scale(${scale})`;
content.style.opacity = opacity;
});
});
This Pen doesn't use any external CSS resources.