Jump to content
Search Community

GSAP ScrollTrigger positioning wrong when component mounts

eggroll test
Moderator Tag

Recommended Posts

Hi there. I recently came across a problem and I can't seem to figure out what is causing the issue. My animations do not work unless a hard reload occurs and the component of the page is mounted. For whatever reason, this particular animation does not work but my other animations do.  One animation contains ScrollTrigger and it works completely fine unlike the one I am having issues with. I've posted a snippet of my code below and would appreciate any help given. The positioning of the markers are wrong when the component has mounted and when the window resizes it snaps to the right location. Although, when this occurs, the animation does not function. All my animations go into one single component file and are initialized with an import and a call function. Thanks so much. No codepen because this problem seems hard to replicate without having set up multiple pages with unmounting and remounting.

export const SplitWord = () => {
  useEffect(() => {
    const ctx = gsap.context(() => {
      const animateIn = (element) => {
        const textsplit = new SplitType(element, { types: 'words' });
        const words = textsplit.words;
        const staggerValue = element.classList.contains('long') ? 0.04 : 0.02;

        gsap.set(words, { opacity: 0 });

        return gsap.fromTo(
          words,
          { x: -10, rotationX: 45, opacity: 0 },
          {
            x: 0,
            rotationX: 0,
            opacity: 1,
            duration: 2,
            stagger: staggerValue,
            ease: 'power3.out',
            overwrite: true,
          }
        );
      };

      gsap.utils.toArray('.splitword').forEach((element) => {
        let animation;

        ScrollTrigger.create({
          trigger: element,
          start: 'top top',
          onEnter: () => {
            if (!animation || !animation.isActive()) {
              animation = animateIn(element);
            }
          },
          scrub: true,
          markers: true,
        });
      });
    });

    return () => ctx.revert();
  }, []);
};

 

Link to comment
Share on other sites

Hi,

 

Besides echoing @Toso's request for a demo, I had to add that this looks a bit odd IMHO:

gsap.utils.toArray('.splitword').forEach((element) => {
  let animation;

  ScrollTrigger.create({
    trigger: element,
    start: 'top top',
    onEnter: () => {
      if (!animation || !animation.isActive()) {
        animation = animateIn(element);
      }
    },
    scrub: true,
    markers: true,
  });
});

Why creating the SplitText instances and the animations of the splited words once the user reaches a specific scroll position? I think creating the animations just once and using ScrollTrigger's toggle actions should be enough to get the results you're after:

https://stackblitz.com/edit/stackblitz-starters-pspxpg?description=A create-react-app project based on react and react-dom&file=src%2FApp.js&title=React Starter

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hi there! Thanks for the replies. I have gone ahead and created a small demo here. The code has changed a little since writing this post. This is how I currently have my ScrollTrigger set up with my components. Do you see any problems with my code? Unfortunately it's difficult to replicate the same issue on StackBlitz since I am not able to hard reload and load into the components with ScrollTrigger. Thanks in advance!

Link to comment
Share on other sites

Yeah, we really need a minimal demo that clearly shows the issue if you'd like some help. Can you explain exactly how to reproduce the problem in that demo you provided? 

 

Also, it looks like you're using a 3rd party library named SplitType (rather than GSAP's SplitText), so be careful to do proper cleanup with that. I assume you'd have to unsplit that in the cleanup function to return it to its normal state. Remember that React 18+ double-invokes useEffect()/useLayoutEffect() in strict mode. 

 

If you eliminate SplitType from the equation completely, do all your animations work properly? We can't really support SplitType here since it's not a GreenSock product. 🤷‍♂️

Link to comment
Share on other sites

Hey Gsap Helper,

I appreciate your thoughtful message, and I want to express my understanding and respect for your decision. It's essential to acknowledge that the animations perform seamlessly when the page is reloaded in the specific location where they are intended to play. However, I've noticed that in the scenario where a hard reload takes place on a different page, and the user navigates to the page with animations afterward, the animations do not function as expected. It appears that the ScrollTrigger line position may be incorrect, causing this issue. I've tested this without the SplitType library and the problem persists. I can try and get a running demo of the problem up soon.

Link to comment
Share on other sites

Hm, that sounds like maybe you're doing some lazy loading of images or something that's shifting the DOM layout around after the initial load? That would explain it, but it's impossible to troubleshoot without knowing exactly how to reproduce the problem.

 

Are you doing anything that might shift the layout? Are you lazy loading images? Did you make sure you call ScrollTrigger.refresh() after you're done shifting the layout around (like after all images finish loading and take up the space they need)?  

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