Jump to content
Search Community

ScrollTrigger kill() not working properly

Sacha test
Moderator Tag

Recommended Posts

Hello, first thank you for this amazing and powerful toolset! You're doing an amazing job and helping a lot of people.

 

I'm using GSAP scrolltrigger on my React Gatsby page. One of the uses is setting the background color of my navigation bar to a different color, when scrolled past specific sections. This all works great. Because of the rooting system of a react app, the triggers and timelines don't get killed automatically when a page is changed. So I have to kill them manually. Yesterday it worked if the scrolltrigger wasn't active. So if I changed pages without activating a scrollTrigger, they would get killed, otherwise if they were active, the wouldn't.

Now it somehow doesn't kill anything anymore at all. Also I'm having a really weird bug when setting markers to "true". When "false", everything is fine, but on "true", the site is buggy and creates markers on the bottom of the page and adds a second scrollbar and everything. Really weird behaviour. But that shouldn't be the focus of this post.

I tried setting up a codepen, but couldn't figure out how to import React.. Maybe someone can give me a quick tip to set one up, so I could try to replicate the behaviour there. Here's the code I'm using if that helps.

 

useEffect(() => {

    gsap.set(navRef.current, {
        backgroundColor: "rgb(255, 255 255)",
    });

    let gsapNav = [];

    // nav background color adapt to section color
    gsap.utils.toArray(sectionRef.current).forEach((section, i) => {
    
        let bgcolor = section.current.dataset.bgcolor;

        gsapNav[i] = gsap.to(navRef.current, {
            scrollTrigger: {
                markers: false,
                trigger: section.current,
                start: "top 102px",
                end: "bottom 102px",
                toggleActions: "play reverse play reverse",
            },
            backgroundColor: `rgb(${bgcolor})`,
            duration: 0.3,
        })
    });

  	 // cleanup function when page is changed
     return () => {
       // prints both scrolltriggers
        console.log(gsapNav);
        gsap.utils.toArray(sectionRef.current).forEach((section, i) => {
            gsapNav[i].kill();
            console.log("kill " + i)
        })
       // still prints both scrolltriggers / tweens
        console.log(gsapNav);
    }

  }, []);

And here the JSX ()

 

return (
  <section>
	<div>Some content</div>
  </section>
  <section ref={sectionRef.current[0]} data-bgcolor="239, 244, 248">
	<div>Some content and color change</div>
  </section>
  <section>
	<div>Some content</div>
  </section>
  <section ref={sectionRef.current[1]} data-bgcolor="239, 244, 248">
	<div>Some content and color change</div>
  </section>
)

 

Link to comment
Share on other sites

Hey there Sacha, welcome to the GSAP forums!

You can use codesandbox to put together a demo. Here's a starter template -
https://codesandbox.io/s/gsap-react-starter-ut42t

 

I would suggest using useLayoutEffect as scrollTrigger needs to do layout calculations.
https://kentcdodds.com/blog/useeffect-vs-uselayouteffect

 Also, have you checked out our react articles?

Link to comment
Share on other sites

Hey Cassie, first thank you for the additional links! The article states we should use refs to define timelines, so they wont get rerendered every time. That's something I didn't do yet, maybe it fixes my problem. Is this only the case for animations / timelines that are used on multiple pages or also for a scrollTrigger animation that I only run on my index page?

 

EDIT

I used this approach for my problematic code, and it didn't resolve it. Now it's back to working when no scrolltrigger was activated, and breaking when some trigger was activated.. I will try to reproduce it in a sandbox.

Link to comment
Share on other sites

1 hour ago, Sacha said:

The article states we should use refs to define timelines, so they wont get rerendered every time. That's something I didn't do yet, maybe it fixes my problem. Is this only the case for animations / timelines that are used on multiple pages or also for a scrollTrigger animation that I only run on my index page?

 

Putting a timeline in a ref is only for when you need to access that timeline outside of an effect.

 

But a making a minimal demo on CodeSandbox will help with troubleshooting your issue.

 

Link to comment
Share on other sites

In React you can do cleanup functions after the useEffect. So like I did in the sandbox. If you look at the console, you see that the console logs are being fired, but the tweens are not being killed.

useEffect(() => {
  //code
  
  //cleanup
  return () => {
      console.log(gsapNav);
      gsap.utils.toArray(sectionRef.current).forEach((section, i) => {
        gsapNav[i].kill();
        console.log("kill " + i);
      });
      console.log(gsapNav);
    };
  }, []);

And the bug did actually replicate just like on my page. If you don't scroll to the first scrolltrigger and click on the link, the scrolltrigger doesn't appear on the second page. But if you scroll to the blue section and trigger the scrolltrigger and click on the link, the markers are still visible on the second page and it creates blank scrollable content.

Link to comment
Share on other sites

I know about the cleanup function, but it fires too late. I think need to kill the ScrollTriggers when the route changes, and not when the cleanup functions fires. But again, I don't know how to do that in react router.

 

And your console log statement just shows the instances, not whether or not it has been killed, so it will always show 2 tweens.

 

Another option, just refresh ScrollTrigger after the page changes... assuming you killed your ScrollTriggers in the other page.

function Page2(props) {
  const id = props.match.params.id;
  useEffect(() => {
    ScrollTrigger.refresh();
  }, [])
  return (
    <div className="page page2">
      <h1>Page 2</h1>
      <p>Sent id: {id}</p>
    </div>
  );
}

 

 

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...