Jump to content
Search Community

ScrollTrigger - pinning left section adds space on bottom

Damian Balas test
Moderator Tag

Recommended Posts

Hi, my pinned left section is adding space on bottom. 
It's only if I start scrolling before the page still loads.

I'm using react, so the DOM is rendered before I use GSAP. 

I think the issue here is that there are <img /> elements that change the height after they are loaded.
 

 const animation = gsap.to(container, {
    ease: 'none',
    scrollTrigger: {
      trigger: container,
      start: 'top top',
      end: 'bottom bottom',
      pin: '#sustainability-left-section',
      pinSpacing: false,
      invalidateOnRefresh: true,
    },
  });

invalidateOnRefresh didn't help.


container is a div with grid columns 50% 50%. I'm pinning the left div which has 100vh set.

Any ideas? 

  • Like 1
Link to comment
Share on other sites

Hey @Damian Balas,

Would it be possible to put together a minimal demo on codePen or codesandbox? It's pretty hard for us to debug blind.

 

This sounds likely to be either confusion around pinSpacing or a DOM loading issue though 👀
 

3 hours ago, Damian Balas said:

I'm using react, so the DOM is rendered before I use GSAP. 

(If you're using React it's reasonably likely the DOM isn't rendered before using GSAP.)

 

  • Like 2
Link to comment
Share on other sites

Hi @Cassie, there is a pretty complicated setup that I'm using. I can't provide you with a demo at the moment:(
 
Maybe you can just guess some solutions and I will try them out?

I'll try to provide you a demo ASAP, but I need to work on the project because of a deadline and I don't want to drop gsap just because of that issue.


I really appreciate your help!
Thanks for your feedback.

I use the gsap functions inside the useEffect hook, so the DOM is 100% rendered.
I think that the images are messing with the gsap calculations. Without any images, everything is fine.

For a temporary solution, I have made a setInterval that goes every 1s for 10 times.
The setInterval function then calls ScrollTrigger.refresh()

Link to comment
Share on other sites

1 minute ago, Damian Balas said:

I think that the images are messing with the gsap calculations. Without any images, everything is fine.

 

Yeah, that sounds like you forgot to set widths/heights on those lazy-loading images so that they don't shift the layout around after they load? The other option is to just make sure you call ScrollTrigger.refresh() AFTER you're done making changes to the layout. 

 

ScrollTrigger automatically does a refresh() after the page loads (as well as when there's a resize) but if you're lazy-loading things, it can't sense that. So if you load things that shift the layout around (like pushing things down to make room for the new images that loaded), that would obviously throw off those calculations. 

 

Does that clear things up? 

  • Like 2
Link to comment
Share on other sites

@GreenSock Yeah, but the problem is that this are normal <img /> elements and they aren't Lazy loaded.
 

10 hours ago, GreenSock said:

ScrollTrigger automatically does a refresh() after the page loads

React pages render after the page loads. So with normal JS you can't tell if the DOM is rendered already. That's the functionality of useEffect().

I think I have an edge case and it cannot be resolved without changing the layout.

I'd like to know if refresh() in an interval can cause performance issues if there are only 2 scroll triggers on a page? If not I will leave it like that :)

Link to comment
Share on other sites

15 hours ago, Damian Balas said:

I've found out that refresh() is causing rerender of my react components, so the hover animations are blinking 😕 
Is there a way to fix that?

 

Impossible to say without a minimal demo.

 

On 8/7/2021 at 2:39 PM, Damian Balas said:

I think the issue here is that there are <img /> elements that change the height after they are loaded

 

Refresh after an image loads. Images have a load event listener.

 

19 hours ago, Damian Balas said:

I'd like to know if refresh() in an interval can cause performance issues

 

Of course. It has do a bunch of layout calculations.

 

  • Like 3
Link to comment
Share on other sites

9 hours ago, OSUblake said:

Refresh after an image loads. Images have a load event listener.


@OSUblake thanks, I have fixed it like this:

 

//! ScrollTrigger fix for react - the calculations were off because images resize the container
  useEffect(() => {
    ScrollTrigger.refresh(true); //! call it once to be sure everything is calculated

    const foundImages = document.querySelectorAll('img');
    if (!foundImages) return () => null;

    const interval = setInterval(() => {
      const areImagesLoaded = Array.from(foundImages).every(
        (image) => image.complete,
      );
      if (areImagesLoaded) {
        ScrollTrigger.refresh();
        clearInterval(interval);
      }
    }, 200);

    return () => {
      if (interval) {
        clearInterval(interval);
      }
    };
  }, []);

 

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