<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;
    });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/debug.addIndicators.min.js