CSS 和 JS 与 GSAP 的转换

CSS and JS Transitions with GSAP

https://codepen.io/thatfemicode/pen/MWpwaRQ

https://twitter.com/P_h_l_i_x/status/1353659923834544128

晚上,经过大量的实践,我想出了一个解决方案,但我仍然不满意我所拥有的,我正在努力做到这一点,正如 TWITTER 的影响者部分所示 link 下面的页面看看每个循环如何在离开视口之前将 class 更改为前一个元素的 class,我该如何实现?谢谢,任何建议将不胜感激

<div id="container">
      <div class="fakeImages" id="fake1"></div>
      <div class="fakeImages" id="fake2"></div>
      <div class="fakeImages" id="fake3"></div>
      <img
        src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c3VucmlzZXxlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80"
        alt="view"
        id="img1"
        class="images"
      />
      <img
        src="https://media.istockphoto.com/photos/colored-powder-explosion-abstract-closeup-dust-on-backdrop-colorful-picture-id1072093690?k=6&m=1072093690&s=612x612&w=0&h=Eyk67XBt4sr3Bk1MubM6dHpvEVNICX4L7FumWhcTwuY="
        alt="powder"
        id="img2"
        class="images"
      />
      <img
        src="https://media3.s-nbcnews.com/j/newscms/2019_41/3047866/191010-japan-stalker-mc-1121_06b4c20bbf96a51dc8663f334404a899.fit-760w.JPG"
        alt="powder"
        id="img3"
        class="images"
      />
      <img
        src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg"
        alt="bird"
        id="img4"
        class="images"
      />
    </div>

CSS

#container {
  .images {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 300px;
    height: 300px;
    transform: translate(-50%, -50%);
  }
  #img4 {
    z-index: -5;
  }
  .fakeImages {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 300px;
    height: 300px;
    z-index: -9;
  }
  #fake1 {
    background: lightgrey;
    transform: translate(-50%, -50%) rotate(20deg);
  }
  #fake2 {
    background: grey;
    transform: translate(-50%, -50%) rotate(-10deg);
  }
  #fake3 {
    background: darkgrey;
    transform: translate(-50%, -50%) rotate(-15deg);
  }
}

Javascript

 function play() {
      let images = gsap.utils.toArray('.images');
      let fakes = gsap.utils.toArray('.fakeImages');
      let tl = gsap.timeline({ repeat: -1, repeatDelay: 1 });
      let tl2 = gsap.timeline({ repeat: -1, repeatDelay: 0 });
      tl.set(images, {
        zIndex: (i) => i * -1,
        rotation: (i) => Math.random() * 30 - 15,
      });
      tl.to(images, {
        duration: 1,
        rotation: 0,
        delay: (i) => i * 1 + 1,
        x: 2000,
        // scale: 0,
        // css: { className: '+=active' },
      });
    }
    play();

在 GSAP 的某人对代码进行了改进并且我也添加了我的修改后,可以在 codepen.io 上找到解决方案。

https://codepen.io/thatfemicode/pen/OJpNXEr

HTML

<div id="container">
<!--       <div class="fakeImages" id="fake1"></div>
      <div class="fakeImages" id="fake2"></div>
      <div class="fakeImages" id="fake3"></div> -->
      <img
        src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c3VucmlzZXxlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80"
        alt="view"
        id="img1"
        class="images"
      />
      <img
        src="https://media.istockphoto.com/photos/colored-powder-explosion-abstract-closeup-dust-on-backdrop-colorful-picture-id1072093690?k=6&m=1072093690&s=612x612&w=0&h=Eyk67XBt4sr3Bk1MubM6dHpvEVNICX4L7FumWhcTwuY="
        alt="powder"
        id="img2"
        class="images"
      />
      <img
        src="https://media3.s-nbcnews.com/j/newscms/2019_41/3047866/191010-japan-stalker-mc-1121_06b4c20bbf96a51dc8663f334404a899.fit-760w.JPG"
        alt="powder"
        id="img3"
        class="images"
      />
      <img
        src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg"
        alt="bird"
        id="img4"
        class="images"
      />
    </div>

CSS

body {
  overflow-x: hidden;
}

.active {
  border: 1px solid red;
}

#container {
  .images {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 300px;
    height: 300px;
    transform: translate(-50%, -50%);
  }
  #img4 {
    z-index: -5;
  }
  .fakeImages {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 300px;
    height: 300px;
    z-index: -9;
  }
  #fake1 {
    background: lightgrey;
    transform: translate(-50%, -50%) rotate(20deg);
  }
  #fake2 {
    background: grey;
    transform: translate(-50%, -50%) rotate(-10deg);
  }
  #fake3 {
    background: darkgrey;
    transform: translate(-50%, -50%) rotate(-15deg);
  }
}

使用 GSAP 的 Javsscript

function play() {
  let images = gsap.utils.toArray('.images');
  let fakes = gsap.utils.toArray('.fakeImages');
  let all = images.concat(fakes);
  let tl = gsap.timeline({ delay: 1, repeat: -1, repeatDelay: 1 });
  gsap.set(images, {
    zIndex: (i) => i * -1,
    // rotation: "random(-15,15)",
  });
  // make sure the "top" image is exactly 8 degrees
  gsap.set(images[0], {rotation: 8});
  gsap.set(images[1], {rotation: -8})
  gsap.set(images[2], {rotation: 8})
  gsap.set(images[3], {rotation: -8})
  // at the start, remove all "active" classes
  tl.call(() => images.forEach(el => el.classList.remove("active")));
  tl.to(images, {
    x: 2000,
    duration: 1,
    ease: "power2.in",
    stagger: {
      each: 1.5,
      onStart() {
        let leavingEl = this.targets()[0],
            enteringEl = all[all.indexOf(leavingEl) + 1];
        // console.log(leavingEl)
        console.log(this.targets())
        //leavingEl.classList.add("active"); // if you want to set a class on the one animating out, you could do it like this.       
        gsap.to(all, {
          ease: "power2.inOut",
          duration: 0.6,
          // rotation: 0
          // function-based value - if it's the entering element, make it exactly 8 degrees. Otherwise, randomize it between -15 and 15 degrees.
          // rotation: (i, target) => target === enteringEl ? 8 : gsap.utils.random(-15, 15)
           rotation: (i, target) => target === enteringEl ? 8 : gsap.utils.random([4, -4,])
        // });
        })
      }
    }
  });
}
play();