javascript - 使用GSAP/ScrollTrigger创建滚动时的卡片堆叠效果

标签 javascript jquery css gsap scrolltrigger

我正在尝试模仿卡片在滚动时堆叠的效果。对于视觉效果,please click here to view a GIF of the effect .

上面的GIF来自的网站是this website .

现在,我尝试使用 GSAP/ScrollTrigger 来模拟上述内容。但我的效果在以下几个方面有所不同:

  1. 在我的演示中,卡片彼此堆叠在一起,但在我试图模仿的演示中却显示出它们自己(请参阅下面我试图实现的设计图像)。我尝试过 z-indexing 但这并没有成功。
  2. 卡片固定在页面顶部,而我希望它居中。
  3. 当您传递 .cardStacking 时,它不会取消固定(一直持续到页面末尾)

enter image description here

演示(在 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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f99b96968d8a8d8b9889b9ccd7c9d7cb" rel="noreferrer noopener nofollow">[email protected]</a>/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>

编辑:

我已经设法在一定程度上解决了上面列表中的第 1 项和第 3 项。

但是,第 1 项的功能尚未完全实现。我不知道为什么这些卡片没有相互堆叠并且没有居中。

在此处查看更新的演示:

$(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/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfbdb0b0abacabadbeaf9feaf1eff1ed" rel="noreferrer noopener nofollow">[email protected]</a>/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>

最佳答案

当你可以只使用 css 时为什么还要使用 GASP

/*QuickReset*/

*,
*::before,
*::after {
  margin: 0;
  box-sizing: border-box;
}

html,
body {
  scroll-behavior: smooth;
}

body {
  font: clamp(11px, 2.5vmin, 18px)/1.4 sans-serif;
  color: #252525;
}

article {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  font-size: 1.2em;
}

.holder {}


/* Whatever you like */

.holder__head {
  padding: 0.4em 2em;
  position: sticky;
  z-index: 1;
  bottom: calc(var(--b) * 2em);
  top: calc(var(--t) * 2em);
}

.holder__item {
  padding: 2rem;
  position: sticky;
  height: 100vh;
  top: calc((var(--t) + 1) * 1.6em);
  padding-bottom: 8em;
}


/* Just some colors... */

.bg-0 {
  background: #000000;
  color: #b3ab9d;
}

.bg-1 {
  background: #817466;
}

.bg-2 {
  background: #a2a093;
}

.bg-3 {
  background: #a5882a;
}

.bg-4 {
  background: #b29d73;
}
<article class="bg-0">
  <h1>How We Work</h1>
</article>
<article>
  <h2>Welcome</h2>
  <p>Scroll down to find out more</p>
</article>

<section class="holder">

  <header class="holder__head bg-3" style="--t:0; --b:3;">1 STEP &mdash; IDENTIFYING STRENGTHS AND WEAKNESSES</header>
  <article class="holder__item bg-3" style="--t:0;">
    <h2>IDENTIFYING STRENGTHS AND WEAKNESSES</h2>
    <p>OUR MULTIDISCIPLINARY TEAM IS HERE TO IDENTIFY BOTH YOUR STRENGTHS AND WEAKNESSES, WITH THE AMBITION TO UNDERSTAND HOW TO BEST ASSIST IN GROWING YOUR BRAND AND REACHING YOUR COMMUNITY.</p>
  </article>

  <header class="holder__head bg-0" style=" --t:1; --b:2;">2 STEP &mdash; PUTTING THE PIECESTOGETHER</header>
  <article class="holder__item bg-0" style="--t:1;">
    <h2>PUTTING THE PIECESTOGETHER</h2>
    <p>BASED ON RESEARCH AND DISCUSSIONS, WE WILL SINGLE OUT THE BEST MEDIUM OR MEDIUMS TO TRANSLATE YOUR BRAND.</p>
  </article>

  <header class="holder__head bg-2" style="--t:2; --b:1;">3 STEP &mdash; FINE-TUNING YOUR CONTENT</header>
  <article class="holder__item bg-2" style="--t:2;">
    <h2>FINE-TUNING YOUR CONTENT</h2>
    <p>BY PRESENTING OUR WORK TO YOU THROUGH OPEN DIALOGUE, WE WILL FINE-TUNE YOUR CONTENT BASED ON FEEDBACK AND OUR COLLECTIVE EXPERTISE.</p>
  </article>

  <header class="holder__head bg-1" style="--t:3; --b:0;">4 STEP &mdash; COMPLETING THE PICTURE</header>
  <article class="holder__item bg-1" style="--t:3;">
    <h2>COMPLETING THE PICTURE</h2>
    <p>WHETHER PRODUCING PHOTOGRAPHY, FILM, CURATING YOUR DIGITAL PLATFORMS OR CREATING A COHESIVE BRAND IDENTITY AND STRATEGY, WE WILL PACKAGE UP ALL OUR WORK AND ASSETS INTO AN ORGANISED LIBRARY A PACKAGE THAT IS SIMPLE FOR YOU TO ENGAGE WITH.</p>
  </article>

</section>

<article class="bg-4">
  <h2>First footer</h2>
</article>
<article class="bg-0">
  <h2>Second footer</h2>
</article>

记入:Jquery translate elements based on scroll

关于javascript - 使用GSAP/ScrollTrigger创建滚动时的卡片堆叠效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73304993/

相关文章:

javascript - 将字符串转换为正则表达式时如何保留\

javascript - 将 2D 方向应用于粒子 - three.js

jquery使用数组值作为id创建新的div

javascript - 悬停时更改背景图像,但也可以使用 jQuery 单击

javascript - 如何将浏览器用作离线应用程序的 GUI?

javascript - 悬停时放大图像但不放大容器

javascript - 悬停时图像发光

javascript - 带 babel 的 NPM 7 工作区 - 在工作区之间导入

javascript - 如何从字符串中删除最后一个 '[]'?

html - 如何使一个简单的 HTML 表格看起来像 "Handsontable"