Jump to content
Search Community

ScrollTrigger.refresh doesn't do anything after pinned sections are dynamically loaded

Vilas test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi guys,

 

I created this super basic codepen file to illustrate the issue.

So the problem is that the middle section is waiting for some data before initializing the scrollTrigger+pinning.

Once the data is loaded and the pinning happens, it throws off the position of all the scrollTriggers below it.

 

Running scrollTrigger.refresh() doesn't seem to do anything in this case.

 

How can i re-calculate the position of all the scroll triggers once the data finishes loading?

 

See the Pen MWRxXZW by omikron1989 (@omikron1989) on CodePen

Link to comment
Share on other sites

Hi,

 

You also posted in this other thread:

Where Jack suggested using ScrollTrigger's sort() method for solving this:

https://gsap.com/docs/v3/Plugins/ScrollTrigger/static.sort()/

 

This works as expected:

sectionB.forEach((section) => {
  
   const textElement = section.querySelector("span");
  //   Load some data, then initialize animation
  later(3000).then(() => {
    console.log("Loaded!!");

    const tl = gsap.timeline({
      scrollTrigger: {
        trigger: section,
        start: "top top",
        end: `+=2000`,
        markers: true,
        scrub: true,
        pin: true
      }
    });

    tl.to(textElement, {
      scale: 1.2,
      ease: "power1.inOut"
    });
    // Sort the ScrollTrigger instances
    ScrollTrigger.sort();
  });
});

This happens because the ScrollTrigger are not created in the order they appear on the screen, if that is not possible we recommend using the refreshPriority configuration in combination with the sort() method, from the ScrollTrigger docs:

refreshPriority
number - it's VERY unlikely that you'd need to define a refreshPriority as long as you create your ScrollTriggers in the order they'd happen on the page (top-to-bottom or left-to-right)...which we strongly recommend doing. Otherwise, use refreshPriority to influence the order in which ScrollTriggers get refreshed to ensure that the pinning distance gets added to the start/end values of subsequent ScrollTriggers further down the page (that's why order matters). See the sort() method for details. A ScrollTrigger with refreshPriority: 1 will get refreshed earlier than one with refreshPriority: 0 (the default). You're welcome to use negative numbers too, and you can assign the same number to multiple ScrollTriggers.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

  • Solution

Yes, like @Rodrigo said, you're creating your ScrollTriggers out-of-order. You're supposed to create them in the order they would be encountered (top to bottom). You're creating the top and bottom first, then the middle, so the refreshing order goes: 1, 3, 2 instead of 1, 2, 3. 

 

For relatively simple setups, it could be adequate to just call ScrollTrigger.sort() which will order them by whatever their "start" is calculated to be. But you can explicitly control the order of things by setting a refreshPriority on each one so you have total control of the order. 

See the Pen PogLyGO?editors=1010 by GreenSock (@GreenSock) on CodePen

 

And here's a verticalSort() helper function that'll sort them by their proximity to the very top of the viewport: 

See the Pen ExJMdXj?editors=0010 by GreenSock (@GreenSock) on CodePen

  • Like 1
Link to comment
Share on other sites

Thank you guys! I have a rather long page with 3-4 sections in between which are dynamic and slow.

Simply using the .sort() method didn't work

 

But using the verticalSort() helper function you suggested did the trick.

I just had to include ScrollTrigger.refresh() after the sorting to make it work properly:

 

function verticalSort() {
    let scroll = window.scrollY;
    ScrollTrigger.getAll().forEach(t => t._sortY = t.trigger ? scroll + t.trigger.getBoundingClientRect().top : t.start + window.innerHeight);
    ScrollTrigger.sort((a, b) => a._sortY - b._sortY);
    ScrollTrigger.refresh();
}
  • Like 1
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...