Jump to content
Search Community

Using scrolltrigger to control lottie file AND fade in text blocks?

Mrcs test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

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

  • Mrcs changed the title to Using scrolltrigger to control lottie file AND fade in text blocks?
  • Solution

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

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 by Mrcs
spelling mistake
Link to comment
Share on other sites

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

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