0

I'm using gsap (version 3.11.5) in reactjs project. Basically, I want to hide shapes when scroll to end of the first page. When scroll back to top, it will also tag along again (using scrub: true). For now, it still appear even though it ends of first page.Is there any way to implmenet by using gsap scroll trigger?

import { useLayoutEffect, useRef } from "react";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import "./App.css";

gsap.registerPlugin(ScrollTrigger);

function App() {
const app = useRef(null);
const tl = useRef();

function random(min, max) {
const delta = max - min;
return (direction = 1) => (min + delta * Math.random()) * direction;
}
const randomX = random(5, 10);
const randomY = random(5, 10);

const randomTime = random(3, 5);
const randomTime2 = random(5, 10);
const randomAngle = random(1, 1.5);

useLayoutEffect(() => {
let ctx = gsap.context(() => {
  let proxy = { skew: 1 },
    skewSetter = gsap.quickSetter(".shape", "skewY", "deg"),
    clamp = gsap.utils.clamp(-200, 200);
  // first page scroll skew animation
  ScrollTrigger.create({
    onUpdate: (self) => {
      let skew = clamp(self.getVelocity() / 200);
      if (Math.abs(skew) > Math.abs(proxy.skew)) {
        proxy.skew = skew;
        gsap.to(proxy, {
          skew: 0,
          duration: 0.8,
          ease: "power3",
          overwrite: true,
          onUpdate: () => skewSetter(proxy.skew),
        });
      }
    },
  });
  gsap.set(".shape", { transformOrigin: "right center", force3D: true });

  function moveX(target, direction) {
    gsap.to(target, randomTime(), {
      x: randomX(direction),
      ease: "Sine.easeInOut",
      onComplete: moveX,
      onCompleteParams: [target, direction * -1],
    });
  }

  function moveY(target, direction) {
    gsap.to(target, randomTime(), {
      y: randomY(direction),
      ease: "Sine.easeInOut",
      onComplete: moveY,
      onCompleteParams: [target, direction * -1],
    });
  }

  function rotate(target, direction) {
    gsap.to(target, randomTime2(), {
      rotation: randomAngle(direction),
      // delay: randomDelay(),
      ease: "Sine.easeInOut",
      onComplete: rotate,
      onCompleteParams: [target, direction * -1],
    });
  }
  gsap.utils.toArray(".shape").forEach((star) => {
    moveX(star, 1);
    moveY(star, -1);
    rotate(star, -1);
  });

  // shapes fixed
  tl.current = gsap.to(".shapes", {
    scrollTrigger: {
      trigger: ".first-page",
      scrub: true,
      markers: true,
      pin: true,
      start: "0%",
      end: "100%",
      onComplete:function() {
        console.log('end')
      }
    },
  });

  // second page
  // scale text when scroll
  tl.current = gsap.timeline({
    scrollTrigger: {
      trigger: ".second-page",
      start: "0%",
      end: "200%",
      scrub: true,
      pin: true,
    },
  });
  tl.current.fromTo(".text", { scale: 0.5 }, { scale: 1.2 });
}, app);

return () => ctx.revert();
}, []);

return (
<div ref={app}>
  <nav>
    <a href="#">Logo</a>
    {/* <div className="hamburgers">Icon</div> */}
  </nav>
  <div className="shapes">
      {[1, 2, 3, 4].map((index) => {
        return (
          <div
            className={`shape item-${index}`}
            data-test={index}
            key={index}
          ></div>
        );
      })}
    </div>
  <section className="first-page">

  </section>
  <section className="second-page">
    <h1 className="text">Second Page</h1>
  </section>
  <section className="third-page">
    <h1 className="">Third Page</h1>
  </section>
</div>
);
}

export default App;

App.css

  nav {
  position: fixed;
  width: 100%;
  padding: 0px 50px;
  min-height: 8vh;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.first-page {
  min-height: 300vh;
  background-color: white;
  color: #000;
}
.second-page {
  height: 100vh;
  background-color: green;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
}
.third-page {
  height: 100vh;
  background-color: yellow;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
}
.shapes {
  position: fixed;
  width: 100%;
  height: 100vh;
  z-index: 1;
}
.shape {
  width: 100px;
  height: 300px;
  background-color: red;
  /* background: rgb(9,9,121); */
  /* background: linear-gradient(180deg, rgba(9,9,121,1) 2%, rgba(0,212,255,0.28895308123249297) 89%); */
}
.shape.item-1 {
  position: absolute;
  top: 0;
  left: 0;
}
.shape.item-2 {
  position: absolute;
  top: 50px;
  left: 40%;
}
.shape.item-3 {
  position: absolute;
  right: 50px;
  bottom: 0;
}
.shape.item-4 {
  position: absolute;
  left: 0;
  bottom: 0;
}
Denny
  • 167
  • 4
  • 8

0 Answers0