Jump to content
Search Community

ScrollTrigger pin issue

zjebinsky test
Moderator Tag

Go to solution Solved by akrdesign,

Recommended Posts

Hey Folks, I'm a relatively new GSAP user and Club Greensock member and I've encountered on issue with the scrolltrigger plugin. I tried to recreated the problem in the stackblitz with react provided by some1 from GSAP team in a different thread i read (i hope it's not an issue since I'm mainly a react developer). 

 

https://stackblitz.com/edit/react-ynqg27?file=src/App.js

 

I also made a quick video of the issue in on my dev server to make sure i explain the issue as much as i can (don't mind the birds in the background :D)

 

And also here is my component code

 

import {gsap} from "gsap";
import {ScrollTrigger} from "gsap/all";
import {useEffect} from "react";
import {Link} from "react-router-dom";
import {cursorEnterAnimation, cursorLeaveAnimation} from "../../utils/animations";
import {SplitText} from "gsap/all";

const Work = () => {
  useEffect(() => {
    gsap.registerPlugin(ScrollTrigger);
    gsap.registerPlugin(SplitText);

    ScrollTrigger.create({
      trigger: "#project-container",
      start: "top 40%",
      end: "bottom 40%",
      scrub: 1,
      markers: true,
      pin: "#text-container",
    });
  }, []);

  return (
    <div className="flex w-full flex-col items-center justify-between text-white">
      <div id="project-container" className="relative flex h-[170vh] items-center justify-center">
        <div className="mr-[20vw] h-[60vh] w-[600px] bg-red-400"></div>
        <div
          id="text-container"
          className="absolute top-0 flex flex-col items-center justify-center text-primary"
        >
          <h1 className="text-center text-8xl font-bold">TITLE</h1>
          <h2 className="mt-5 text-center font-grandslang text-xl font-medium">
            Project & Development
          </h2>
          <button className="mt-12 text-center font-medium tracking-widest underline">
            VIEW PROJECT
          </button>
        </div>
      </div>
      <div className="flex h-[170vh] items-center justify-center">
        <div className="mr-[20vw] h-[60vh] w-[600px] bg-red-400"></div>
      </div>
    </div>
  );
};
export default Work;

It seem's like the title dissapears when the starter markers meet and appears back after end markers meet at the end of the page. Then it appears in the center again on the way back and stays there untill the start markers again. 

 

Can you please tell me what I'm missing?

Link to comment
Share on other sites

  • Solution

Actually I'm away from my laptop, so that's why I am give you one example of ScrollTrigger pin problem in react through link 😜 and the link is https://codesandbox.io/embed/pin-using-gsap-in-react-forked-m5ku4c?file=/src/App.js&codemirror=1

 

So basically you need to create ScrollTrigger inside the gsap context api. I hope this is helpful for you. And if you want know more about gsap context just read the doc.

  • Like 3
Link to comment
Share on other sites

15 minutes ago, akrdesign said:

Actually I'm away from my laptop, so that's why I am give you one example of ScrollTrigger pin problem in react through link 😜 and the link is https://codesandbox.io/embed/pin-using-gsap-in-react-forked-m5ku4c?file=/src/App.js&codemirror=1

 

So basically you need to create ScrollTrigger inside the gsap context api. I hope this is helpful for you. And if you want know more about gsap context just read the doc.

Thank you so much for such a fast and friendly response! I did not realize that context is such an important thing when using GSAP with React! I havent seen the post about it earlier. I'll dive deep into that now.

 

Here is the updated code that works just like i wanted to (for anyone that encounters the same issue!)

 

import {gsap} from "gsap";
import {ScrollTrigger} from "gsap/all";
import {useEffect, useRef} from "react";
//import {Link} from "react-router-dom";
//import {cursorEnterAnimation, cursorLeaveAnimation} from "../../utils/animations";
import {SplitText} from "gsap/all";

gsap.registerPlugin(ScrollTrigger);
gsap.registerPlugin(SplitText);

const Work = () => {
  let component = useRef(null);

  useEffect(() => {
    let ctx = gsap.context(() => {
      gsap.to("#text-container", {
        scrollTrigger: {
          trigger: "#project-container",
          start: "top 40%",
          end: "bottom 40%",
          pin: "#text-container",
          pinSpacing: false,
          markers: true,
        },
      });
    }, component);
    return () => ctx.revert();
  }, []);

  return (
    <div ref={component} className="flex w-full flex-col items-center justify-between text-white">
      <div id="project-container" className="relative flex h-[170vh] items-center justify-center">
        <div className="mr-[20vw] h-[60vh] w-[600px] bg-red-400"></div>
        <div
          id="text-container"
          className="absolute top-0 flex flex-col items-center justify-center text-primary"
        >
          <h1 className="text-center text-8xl font-bold">TITLE</h1>
          <h2 className="mt-5 text-center font-grandslang text-xl font-medium">
            Project & Development
          </h2>
          <button className="mt-12 text-center font-medium tracking-widest underline">
            VIEW PROJECT
          </button>
        </div>
      </div>
      <div className="flex h-[170vh] items-center justify-center">
        <div className="mr-[20vw] h-[60vh] w-[600px] bg-red-400"></div>
      </div>
    </div>
  );
};
export default Work;

 

Link to comment
Share on other sites

4 hours ago, zjebinsky said:

I did not realize that context is such an important thing when using GSAP with React!

It isn't so much that context() is critical - the fundamental problem is that React 18+ invokes useEffect()/useLayoutEffect() TWICE in strict mode which causes a lot of people to inadvertently create multiple (duplicate) competing/conflicting animations/ScrollTriggers that are fighting for control of the same element. That's why cleanup is so important. gsap.context() just makes cleanup super easy, that's all. 

 

Glad you got it figured out. And thanks for chiming in, @akrdesign 🙌

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...