Mrcs Posted July 21, 2023 Share Posted July 21, 2023 Hey all, What I'm trying to do: Use scrolltrigger to control the progress of the lottie file Use scroll trigger to fade in text blocks sequentially, then fade the text block up and out at defined times on the timeline What's happening: Even though I set the text to not be visible initially it still all appears. Can't properly link the animation of the lottie and text. Can't seem to get the text to fade out using stackblitz (but it fades out one by one locally ?) Any assistance greatly appreciated Minimal demo: https://stackblitz.com/edit/react-fra2qi?embed=1&file=src%2FApp.js Link to comment Share on other sites More sharing options...
Solution Rodrigo Posted July 21, 2023 Solution Share Posted July 21, 2023 Hi @Mrcs and welcome to the GreenSock forums! This is yet another round of the gift that keeps on giving: React's double call on the useEffect hooks, introduced on Strict Mode since version 18 ? The issue: since the use effect is called twice, the ScrollTrigger/Lottie helper function is created twice which totally messes every calculation in the second call. The possible solution for now is to store the lottie instance returned by the helper function in a ref and check if that exists in order to not create it again: useLayoutEffect(() => { const ctx = gsap.context(() => { if (!lottieTween.current) { lottieTween.current = LottieScrollTrigger({ trigger: '.wrapper', target: '.lottie-container', path: 'https://assets-v2.lottiefiles.com/a/940e9c48-118b-11ee-91bd-379eb366d204/RJaC0UUtyE.json', speed: 'medium', start: 'top top', end: '+=200%', pin: '.wrapper', scrub: 1, markers: true, }); } }); return () => ctx.revert(); }, []); Here is a live example of that in place: https://stackblitz.com/edit/vitejs-vite-emmptw Hopefully this helps. Happy Tweening! Link to comment Share on other sites More sharing options...
Mrcs Posted July 22, 2023 Author Share Posted July 22, 2023 (edited) Thanks @Rodrigo that helped with the doubling up, thank you! My other question would be how do I now link the text I want to fade in/out to the same timeline that the lottie animation is using? I've looked at other examples that do something similar, but then the lottie file doesn't load but the text animation works. Edited July 22, 2023 by Mrcs spelling mistake Link to comment Share on other sites More sharing options...
Rodrigo Posted July 25, 2023 Share Posted July 25, 2023 Hi, Your example is not using the solution I provided correctly, you are using the conditional check on the entire layout effect hook, plus you're not setting the ref as the lottie animation returned from the helper function, so the helper function is still running twice: useLayoutEffect(() => { const ctx = gsap.context((self) => { if (!lottieTween.current) { // YOU'RE NOT SETTING lottieTween.current to be the lottie instance // THIS WILL RUN AGAIN AND CREATE THE SAME ERROR //Animate lottie on scroll LottieScrollTrigger({ target: LottieRef.current, path: 'https://assets-v2.lottiefiles.com/a/940e9c48-118b-11ee-91bd-379eb366d204/RJaC0UUtyE.json', speed: 'medium', start: 'top top', end: 'bottom -100%', pin: ScrollRef.current, scrub: 1, }); } }); // <- Scope! return () => ctx && ctx.revert(); // <- Cleanup! }, []); Finally it seems that pinning the Lottie-ScrollTrigger instance is creating some sort of hiccup with the text instances, so is better to pin the same container with the ScrollTrigger instance for the texts: useLayoutEffect(() => { const ctx = gsap.context((self) => { if (!lottieTween.current) { //Animate lottie on scroll lottieTween.current = LottieScrollTrigger({ target: LottieRef.current, path: 'https://assets-v2.lottiefiles.com/a/940e9c48-118b-11ee-91bd-379eb366d204/RJaC0UUtyE.json', speed: 'medium', start: 'top top', end: '+=200%', scrub: 1, id: 'lt', markers: true, }); } //Animate text const texts = gsap.utils.toArray('.animated-text'); const textTl = gsap.timeline({ scrollTrigger: { trigger: ScrollRef.current, start: 'top top', end: '+=200%', scrub: 1, pin: true, markers: { indent: 250 }, id: 'txt', }, }); }); // <- Scope! return () => ctx && ctx.revert(); // <- Cleanup! }, []); Here is a fork of your example: https://stackblitz.com/edit/react-pfgj43?file=src%2FApp.js Hopefully this helps. Happy Tweening! 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