Saturday, 13 August 2022

Using GSAP / ScrollTrigger to create card stacking effect on scroll

I'm trying to mimic the an effect where cards unstack on scroll. For visuals, please click here to view a GIF of the effect.

The website the above GIF is from is this website.

Now, I've tried to mimic the above using GSAP / ScrollTrigger. However, my effect differs in the following aspects:

  1. The cards stack on top of each other in my demo, but reveal themselves in the demo I'm trying to mimic (see image of the design I'm trying to achieve below). I've tried z-indexing but this didn't do the trick.
  2. The cards pin to the top of the page, whereas I'm looking for it to be centered.
  3. It doesn't unpin when you've passed .cardStacking (carries on until the end of the page)

enter image description here

Demo (view on 1200px +)

$(function() {

  const cards = gsap.utils.toArray(".stackCard");

  cards.forEach((card, index) => {
    const tween = gsap.to(card, {
      scrollTrigger: {
        trigger: card,
        start: () => `top bottom-=100`,
        end: () => `top top+=40`,
        scrub: true,
        markers: true,
        invalidateOnRefresh: true
      },
      ease: "none",
      scale: () => 1 - (cards.length - index) * 0.025
    });

    ScrollTrigger.create({
      trigger: card,
      start: "top top",
      pin: true,
      pinSpacing: false,
      markers: true,
      id: 'pin',
      end: 'max',
      //end: '.cardStacking',
      invalidateOnRefresh: true,
    });

  });

});
:root {
  --navy: #0E185F;
  --white: #FFFFFF;
}

.background--navy {
  background-color: var(--navy);
}

.color--white {
  color: var(--white);
}

.spacer {
  height: 2000px;
}

.cardStacking {
  padding: 120px 0 141px 0;
  /*********/
}
.cardStacking__intro {
  margin-bottom: 100px;
}
.cardStacking .stackCard {
  border-radius: 40px;
  background: linear-gradient(90deg, #c7defe 0%, #e7e7f2 100%);
  margin-bottom: 50px;
  padding: 106px 135px 126px 77px;
  /* CONTENT */
}
.cardStacking .stackCard:first-child {
  box-shadow: 0px 10px 30px 0px rgba(0, 0, 0, 0.16);
}
.cardStacking .stackCard__content-header {
  margin-bottom: 10px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js"></script>

<div class="spacer"></div>

<section class="cardStacking background--navy">
  <div class="container">

    <div class="row justify-content-center">
      <div class="col-12 col-md-10 col-lg-7">
        <div class="cardStacking__intro text-center">
          <h2 class="cardStacking__intro-header color--white">LOREM IPSUM DOLOR SIT AMET CONSETETUR SADIPSCING</h2>
          <div class="cardStacking__intro-copy color--white">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.</div>
        </div>
      </div>
    </div>

    <div class="row justify-content-center">
      <div class="col-12 col-md-10">
        <div class="cardStacking__cards">
  
            <!------------>
            <!-- CARD 1 -->
            <!------------>
          
            <div class="stackCard">
              <div class="stackCard__content">
                <span class="stackCard__content-header d-block">Header</span>
                <div class="stackCard__content-copy">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.</div>
              </div>
            </div>
          
            <!------------>
            <!-- CARD 2 -->
            <!------------>
            <div class="stackCard">
              <div class="stackCard__content">
                <span class="stackCard__content-header d-block">Header 2</span>
                <div class="stackCard__content-copy">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.</div>
              </div>
            </div>
          
            <!------------>
            <!-- CARD 3 -->
            <!------------>
            <div class="stackCard">
              <div class="stackCard__content">
                <span class="stackCard__content-header d-block">Header 3</span>
                <div class="stackCard__content-copy">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.</div>
              </div>
            </div>

        </div>
      </div>
    </div>

  </div>
</section>

<div class="spacer"></div>

Edit:

I have managed to somewhat resolve items 1 and 3 in my above list.

However, the functionality for item 1 isn't quite there yet. I do not know why the cards are not stacked upon each other and are not centered.

See updated demo here:

$(function() {

   const container = document.querySelector(".cardStacking__cards");
  const card = document.querySelector(".stackCard");
  const cards = document.querySelectorAll(".stackCard");
  const height = 500;

  const timeline = gsap.timeline({
    scrollTrigger: {
      trigger: container,
      pin: true,
      markers: true,
      scrub: 1,
      start: "bottom-=10% center",
      end: "bottom top"
    }
  });

  timeline.from(card, {
    y: (index) => height * (cards.length - (index + 1)),
    duration: (index) => 0.6 / (index + 1),
    ease: "none",
    stagger: (index) => 0.3 * (index),
  });

});
:root {
  --navy: #0E185F;
  --white: #FFFFFF;
}

.background--navy {
  background-color: var(--navy);
}

.color--white {
  color: var(--white);
}

.spacer {
  height: 2000px;
}

.cardStacking {
  padding: 120px 0 141px 0;
  /*********/
}
.cardStacking__intro {
  margin-bottom: 100px;
}
.cardStacking .stackCard {
  border-radius: 40px;
  background: linear-gradient(90deg, #c7defe 0%, #e7e7f2 100%);
  margin-bottom: 50px;
  padding: 106px 135px 126px 77px;
  /* CONTENT */
}
.cardStacking .stackCard:first-child {
  box-shadow: 0px 10px 30px 0px rgba(0, 0, 0, 0.16);
}
.cardStacking .stackCard__content-header {
  margin-bottom: 10px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollTrigger.min.js"></script>

<div class="spacer"></div>

<section class="cardStacking background--navy">
  <div class="container">

    <div class="row justify-content-center">
      <div class="col-12 col-md-10 col-lg-7">
        <div class="cardStacking__intro text-center">
          <h2 class="cardStacking__intro-header color--white">LOREM IPSUM DOLOR SIT AMET CONSETETUR SADIPSCING</h2>
          <div class="cardStacking__intro-copy color--white">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.</div>
        </div>
      </div>
    </div>

    <div class="row justify-content-center">
      <div class="col-12 col-md-10">
        <div class="cardStacking__cards">
  
            <!------------>
            <!-- CARD 1 -->
            <!------------>
          
            <div class="stackCard" style="z-index: 0;">
              <div class="stackCard__content">
                <span class="stackCard__content-header d-block">Header</span>
                <div class="stackCard__content-copy">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.</div>
              </div>
            </div>
          
            <!------------>
            <!-- CARD 2 -->
            <!------------>
            <div class="stackCard" style="z-index: -1;">
              <div class="stackCard__content">
                <span class="stackCard__content-header d-block">Header 2</span>
                <div class="stackCard__content-copy">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.</div>
              </div>
            </div>
          
            <!------------>
            <!-- CARD 3 -->
            <!------------>
            <div class="stackCard" style="z-index: -2;">
              <div class="stackCard__content">
                <span class="stackCard__content-header d-block">Header 3</span>
                <div class="stackCard__content-copy">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.</div>
              </div>
            </div>

        </div>
      </div>
    </div>

  </div>
</section>

<div class="spacer"></div>


from Using GSAP / ScrollTrigger to create card stacking effect on scroll

No comments:

Post a Comment