katokalen Posted February 26, 2021 Share Posted February 26, 2021 Hi there, I'm running into weirdness with scrollTrigger and marker positioning. I have a page with 2 components built in Next.js, one is using scrollTrigger to pin an element for a duration (AnimationScrollBlock), and another component fades in some images when the user scrolls to it (ImagesBlock). When I click between navigation pages and then back to the "Case" page, sometimes the markers seem to be in the correct position, sometimes they aren't. The same thing appears to happen when I do a hard refresh on the page. Sometimes they are correct, other times they aren't. When they aren't in the correct position the animation for the fading images has already completed before I actually get to that section of the screen. Here is a url to see the issue in action: https://3qfnr.sse.codesandbox.io/case Try doing a hard refresh on the page and see if the marker position for images-1 and images-2 move around. Click to another page and then back to see if the markers move. Screenshot below as well showing what I see when the position is calculated incorrectly and correctly. And here is the codesandbox link to see the code: https://codesandbox.io/s/eager-banach-3qfnr (click on the Case Study link in the nav) As a test, when I move the AnimationScrollBlock component to be underneath the ImagesBlock component, things work as expected. I'm sure it's something dumb but I'm stumped, would really appreciate any insight you might have! Thank you! Link to comment Share on other sites More sharing options...
ZachSaucier Posted February 27, 2021 Share Posted February 27, 2021 Hey katokalen and welcome to the GreenSock forums. Thanks for supporting GreenSock with a Club GreenSock membership! I haven't looked at the code yet. Have you read through the most common ScrollTrigger mistakes article? Link to comment Share on other sites More sharing options...
katokalen Posted February 27, 2021 Author Share Posted February 27, 2021 Yes I have. I also have been scouring the greensock forums for tips & tricks with React hooks and making sure to register my scroll trigger instances, kill them on unmount, and also try to refresh them to get the correct values. The forum has been a great help but now wondering if it’s something in my actual pinning animation or a missing CSS spacer that might be the problem? Looking forward to your insight once you’ve looked at my minimal demo. Link to comment Share on other sites More sharing options...
ZachSaucier Posted March 1, 2021 Share Posted March 1, 2021 Sorry for the delayed response - the weekend This mis-position is due to the components in the AnimationScrollBlock not being loaded before the ScrollTriggers are set up. It's one of the most common ScrollTrigger mistakes that I linked to. You can see that this is the issue by resizing the window after the page has loaded incorrectly - that forces ScrollTrigger to refresh and the position is corrected. So if you call ScrollTrigger.refresh() after the components have been switched out after the page change the issue will go away. Side notes: toggleActions don't do anything if you have a scrub applied so you can remove that when applicable. ease: "power4.inout" should be ease: "power4.inOut". Since you already have a variable reference to your timeline, you could use that to kill off the ScrollTrigger instead of .getById(). You have multiple gsap.registerPlugin(ScrollTrigger); per file. It's better to just include it once if the window exists. It's best to stick to .to() and .from() if you don't need the functionality of .fromTo(). It might make more sense to use ScrollTrigger's .batch() functionality for your images so that you can do some staggering reveals. 1 Link to comment Share on other sites More sharing options...
katokalen Posted March 1, 2021 Author Share Posted March 1, 2021 Quote So if you call ScrollTrigger.refresh() after the components have been switched out after the page change the issue will go away. Thanks Zach, so just to be clear, I should be calling ScrollTrigger.refresh() on unMount inside of my UseEffect for each component? Or where do I add this exactly? So like this? useEffect(() => { let c1 = gsap.timeline({ scrollTrigger: { id: "screen", trigger: trigger.current, pin: wrapper.current, scrub: 1, markers: true, start: "top top" } }); c1.to(img1.current, { duration: 2, yPercent: -70, ease: "power4.inOut" }); // Need to unmount these return () => { ScrollTrigger.refresh(); // New Line c1.kill(); }; }, []); I can make these other adjustments, should the gsap.registerPlugin(ScrollTrigger);be inside of _app.js, or the parent page where the components are imported (like case.js)? Link to comment Share on other sites More sharing options...
ZachSaucier Posted March 1, 2021 Share Posted March 1, 2021 8 minutes ago, katokalen said: just to be clear, I should be calling ScrollTrigger.refresh() on unMount inside of my UseEffect for each component? Or where do I add this exactly? That's a React question and I don't know the answer to it. The goal is to have ScrollTrigger refresh once all of your components have mounted. Maybe @Rodrigo has some time to provide some insight at some point. Link to comment Share on other sites More sharing options...
katokalen Posted March 1, 2021 Author Share Posted March 1, 2021 Ok on my side I've made the quick adjustments you recommended in your first comment to my minimal demo (I will refactor the imagesBlock animation to use .batch() at a later date, thank you for that). I've moved the registering ScrollTrigger check to the parent page (case.js) and removed it from the components. Not sure if you saw my question above about whether this needs to live inside _app.js or is this is fine in the parent page? I'll leave it in the parent page for now as it appears to be working. I've added ScrollTrigger.refresh() to the parent page (case.js) inside its UseEffect instead of the components and this appears to have fixed the issue! Thanks for the help, if Rodrigo has any feedback would love to hear it, otherwise I think this is working. 1 Link to comment Share on other sites More sharing options...
Solution katokalen Posted June 18, 2021 Author Solution Share Posted June 18, 2021 Hi all - looping back on this. I pulled this back into my next.js app (using Contentful as the CMS) and I determined that the issue I was seeing was that my component would initialize, THEN the content from Contentful would pop in, and then the heights of my animations would be incorrect as they had already initialized. I couldn't find a good fix for this aside from reinitializing my animations after the content came in using setTimeout. But definitely seems to be more of a Next.js configuration issue then anything with GSAP. Link to comment Share on other sites More sharing options...
OSUblake Posted June 18, 2021 Share Posted June 18, 2021 6 hours ago, katokalen said: I couldn't find a good fix for this aside from reinitializing my animations after the content came in using setTimeout. But definitely seems to be more of a Next.js configuration issue then anything with GSAP. You definitely should not have to use setTimeout. I'm assuming that that there must be some type of event/callback when your contentful stuff is loaded. You should definitely be hooking into that somehow. 2 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now