Jump to content
Search Community

Nesting animations inside a single useLayoutEffect hook

ARNM test
Moderator Tag

Go to solution Solved by OSUblake,

Recommended Posts

Hey, I'm new to GSAP and absolutely loving it!

 

I'm currently working on my first commercial Gatsby React site and while experimenting with the useLayoutEffect hook I came across an issue. managed to rectify it and now I was just wondering if I could get a little context.

 

When I started setting up my animations I was nesting each animation into a separate useLayoutEffect hook like so:

 

  const h2Ref = useRef(null);
  const contentRef = useRef(null);

  useLayoutEffect(() => {

    const el = h2Ref.current;

    gsap.set(el, { y: -30, opacity: 0 });
    gsap.to(el, { y:0, opacity:1, delay:.25 });

    gsap.to(el, 
    {
      y: -50,
      opacity: 0,
      immediateRender: false,
      overwrite: 'auto',
      scrollTrigger: {
        trigger: el,
        start: "top+=100px center", 
        scrub: .5,
      }
    });
  }, [])

 useLayoutEffect(() => {
    const el2 = contentRef.current;

    gsap.set(el2, { y: -30, opacity: 0 });
    gsap.to(el2, { y:0, opacity:1, delay:.25 });

    gsap.to(el2, 
    {
      y: -30,
      opacity: 0,
      immediateRender: false,
      overwrite: 'auto',
      scrollTrigger: {
        trigger: el2,
        start: "top+=100px center", 
        scrub: .5,
      }
    });
  }, [])

Everything works fine just like this.

 

As an experiment, I had a shift around and dropped several animations into a single useLayoutEffect hook to see if I could clean up my code a little bit. Like this:

 

  const h2Ref = useRef(null);
  const contentRef = useRef(null);

  useLayoutEffect(() => {

    const el = h2Ref.current;

    gsap.set(el, { y: -30, opacity: 0 });
    gsap.to(el, { y:0, opacity:1, delay:.25 });

    gsap.to(el, 
    {
      y: -50,
      opacity: 0,
      immediateRender: false,
      overwrite: 'auto',
      scrollTrigger: {
        trigger: el,
        start: "top+=100px center", 
        scrub: .5,
      }
    });

    const el2 = contentRef.current;

    gsap.set(el2, { y: -30, opacity: 0 });
    gsap.to(el2, { y:0, opacity:1, delay:.25 });

    gsap.to(el2, 
    {
      y: -30,
      opacity: 0,
      immediateRender: false,
      overwrite: 'auto',
      scrollTrigger: {
        trigger: el2,
        start: "top+=100px center", 
        scrub: .5,
      }
    });

  }, [])

When I did that, I was ending up with masses of white space appearing at the bottom of the page whenever I changed to a new route. 

 

So really my question is more out of curiosity, why did this happen? Is this something to do with how hooks work or how GSAP works? Just hoping to get a little enlightened :)

 

Many thanks, and thanks for such an awesome animation tool!

Link to comment
Share on other sites

  • Solution

Welcome to the forums @ARNM

 

There should be no difference between those, but if you're changing routes, you need to kill those ScrollTriggers. Also, I would recommend not animating the position of your triggers. Use a wrapper instead.

 

useLayoutEffect(() => {

  ...
  
  return () => ScrollTrigger.getAll().forEach(t => t.kill());
}, []);

 

If you need more help, please provide a minimal demo. You can use CodeSandbox for React.

 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

Hi @OSUblake, sorry for the delay in responding, the past two weeks have been hectic.

 

I took what you suggested on board and spent some more time re-reading the docs, I have a habit of trying to run before I can walk...

 

The whitespace bug has been resolved by killing the scrollTrigger and I've set up a wrapper element. Everything is working as intended.

 

  let el = useRef();

  useLayoutEffect(() => {

    const q = gsap.utils.selector(el);
    const wrapper = el.current;

    gsap.set(q(".fancy-text"), { 
      opacity: .2
    });

    gsap.to(q(".fancy-text"), {
      y: -50,
      opacity: 0,
      immediateRender: false,
      overwrite: 'auto',
      scrollTrigger: {
        trigger: wrapper,
        start: "top+=100px center", 
        scrub: .5,
       markers:true
      }
    });

    return () => ScrollTrigger.getAll().forEach(t => t.kill());

  }, [])

Thanks for your help, much appreciated :)

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