Jump to content
Search Community

ScrollTriggers break if initialized before ScrollSmoother

RJWadley test
Moderator Tag

Recommended Posts

If you initialize ScrollSmoother after you create a tween or timeline with a ScrollTrigger, the tween doesn't work correctly. It will either get stuck at the beginning or snap to the end. Plus, if the page is not at the top when initialized, onEnter and onLeave are sometimes fired instantly.

 

In React, effects in components higher in the tree are run later, and since ScrollSmoother is usually in one of the highest components it will always be initialized last, which causes this issue.

See the Pen yLjQjBo by RJWadley (@RJWadley) on CodePen

Link to comment
Share on other sites

Hi,

 

Right now I'm on my phone so I can't take a deep look into this.

 

There are a couple of options you could try. One is to create a state property in the component where ScrollSmoother is being initialized. Una use effect hook with no dependencies toggle that state and pass it down to the child components in order to either conditionally render them or instantiate scrolltrigger in a use effect hook with that prop as a dependency.

 

You could also wrap your app in a context provider and toggle some state in the context and listen to that in the components where the scrolltrigger instances are created and go the use effect route.

 

Another option is to refresh the scrolltrigger instances after ScrollSmoother has been initialized.

 

Happy Tweening!

Link to comment
Share on other sites

Thanks for the reply, Rodrigo.

 

Refreshing ScrollTrigger after the smoother is initialized does not fix the issue. This would be the preferred solution for me if it worked.

 

Relying on some React state to recreate everything if the smoother changes seems like it would work until the underlying issue is fixed, although I don't anticipate that being very nice to performance.

 

Something else I found that works is adding a reverse and a play to the enter trigger, although this will still break if the page isn't at the top when everything's initialized.

onEnter: () => {
  console.log("onEnter TRIGGERED");
  timeline.reverse();
  timeline.play();
},

 

Link to comment
Share on other sites

Hi regarding this statement:

3 hours ago, RJWadley said:

Relying on some React state to recreate everything if the smoother changes seems like it would work until the underlying issue is fixed, although I don't anticipate that being very nice to performance.

 

The idea of the state update is something that will change only once in the app's life-cycle, not a state property that will change regularly. There is a difference between one setup and another. ScrollSmoother doesn't change regularly, just once:

const main = () => {
  const [smootherStarted, setSmootherStarted] = useState(false);
  
  useLayoutEffect(() => {
    const ctx = gsap.context(() => {
      ScrollSmoother.create({
        smooth: 1,
        effects: true,
      });
      setSmootherStarted(true);
    });
    return () => ctx.revert();
  }, []);
  return (
    <main>
      <MyComponent init={smootherStarted} />
    </main>
  );
};

export default main;

Then:

const MyComponent = ({ smootherStarted }) => {
  useLayoutEffect(() => {
    if (smootherStarted) {
      /* Create ScrollTrigger instances now */
      /* This should happen only once */
    }
  }, [smootherStarted]);
  return (
    /* Content Here */
  );
};

export default MyComponent;

Also I don't know about performance issues in a case like this, I think the best way is to test, profile and see the behaviour of the app.

 

Finally in your codepen example you have this:

<div id="smooth-content">
  <h1 class="title">Testing Ground</h1>
  <div class="filler"></div>
  <div class="anim"></div>
  <div class="filler"></div>
  <br />
</div>

Keep in mind that you need an extra wrapper for ScrollSmoother to work properly:

<div id="smooth-wrapper">
  <div id="smooth-content">
    <!--- ALL YOUR CONTENT HERE --->
  </div>
</div>

Please take a good look at the documentation:

https://greensock.com/docs/v3/Plugins/ScrollSmoother

 

Happy Tweening!

Link to comment
Share on other sites

  • 1 month later...

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