Jump to content
Search Community

Nested animation using useGSAP 'undefined (reading "x")' error

modulareverything test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Hey everyone,

 

I recently started using `useGSAP` and I'm really enjoying it so far, it's taking all of the headache out of GSAP for me which previously turned me away, so firstly I just wanted to say — fantastic work!

 

On to my issue, then (CodeSandbox linked at the bottom).

 

I have two components, a parent `CardMarquee` component and a mapped out array of `Card` components. The `Card` components have an `onMouseMove` animation which follows the principles laid out in the React guide on this website, using `contextSafe` and `quickTo`, and is essentially just a `div` element that follows the mouse whilst you hover over the card. The parent `CardMarquee` has some fade in effects as the page loads.

 

So essentially I'm trying to get the cards to animate in, and to have this interactive mouse effect on them when the user interacts.

 

I was getting this repeated error, however;

 

> TypeError: Cannot read properties of undefined (reading 'x')

 

I tried a bunch of different approaches, using `state` instead of `refs`, amongst other things, but nothing seemed to work. I couldn't get the `quickTo` function to work even though if I was to `console.log(xTo.current)` in the `moveOverlay()` function, I'd see the function that `quickTo` was creating. Weird.

 

Eventually I had a theory of disabling any other animations on the cards, and it works absolutely fine, which is what I currently have set up in the CodeSandbox below.

 

However if you open `src/components/CardMarquee/index.tsx` you'll see a commented-out `useGSAP` hook on line 29 — if you uncomment this line, you'll see the animation, but if you hover your mouse over a card you'll see the error in the console.

 

So I guess my question is, am I doing something wrong with nesting these useGSAP hooks?

 

Here's the CodeSandbox. I'm not particularly good with these minimal demos, so hopefully this works. You need to run `yarn dev` in the terminal to start the dev server.

 

https://codesandbox.io/p/devbox/g5mt9h?file=%2Fsrc%2Fcomponents%2FCardMarquee%2Findex.tsx%3A4%2C16

Link to comment
Share on other sites

Hi,

 

Unfortunately I can't get your demo to run so I couldn't really tell you.

 

If possible create an even smaller demo (again if possible) on Stackblitz which normally works better than codesandbox.

 

The only thing I could tell you based on a quick glance of your code is to not return the gsap.defaults() in your method, no need for that since that is not a GSAP instance, just a method to set some global defaults.

export function animateMediumCards(card: string) {
  gsap.defaults({
    ease: "power2.inOut",
    duration: 1.25,
    transformOrigin: "center center",
    stagger: function (index) {
      if (index === 0) {
        return 0.5;
      }
      if (index === 1) {
        return 1.25;
      }
      if (index === 2) {
        return 0.25;
      }
      if (index === 3) {
        return 1;
      }
      if (index > 3 && index < 8) {
        return 0.5;
      }
      return 0;
    },
  })
  return (
    // stagger in the cards, starting with the first card and scaling down to the last card
    gsap.fromTo(
      ".card",
      {
        scale: 1.25,
        autoAlpha: 0,
      },
      {
        scale: 1,
        autoAlpha: 1,
      }
    )
  );
}

Happy Tweening!

Link to comment
Share on other sites

Hey Rodrigo,

 

Looks like I had better luck opening the repo on Stackblitz, so I'm able to show my code exactly as I have it;

 

https://stackblitz.com/~/github.com/Modular-Everything/the-most-radicalist

 

The same files to check are still in the same place, and it's a pretty small project at this stage so hopefully it's easy to navigate.

 

I tried your suggestion — solid advice — but I still get the issue as before.

Link to comment
Share on other sites

Hi,

 

I'm having all sorts of problems opening files and trying to edit/fork your demo. It seems somehow related to how stackblitz and github are connecting.

 

I was able to see the error for a brief moment though, before the browser tab became unresponsive.

 

The only suggestion I would have so far would be to remove the animations and check the mouse move event on every card, create some console logs and see what you're getting there, because definitely something is undefined there which is causing this to break, but unfortunately right now there is no way to test, for me at least

 

Sorry that I haven't been of any assistance so far, hopefully you can create a minimal demo that we can tinker with.

 

Happy Tweening!

Link to comment
Share on other sites

Hey Rodrigo,

 

Sorry for the delayed response, thanks for checking this out for me so far.

 

I've managed to recreate this in a very minimal demo, found here:

 

https://codesandbox.io/p/sandbox/usegsap-nesting-7j82p6

 

Setting this up in a minimal demo narrowed the scope of the problem and I was able to pinpoint what's causing it, but I'm unsure what the solution is.

 

If you comment out the custom stagger function in `MyComponent.jsx` (line 30), the undefined 'reading x' error goes away.

 

What I'm trying to achieve is to have the first few cards tween in at different times, so you can see I'd like the index 0 to tween at 0.5, index 1 at 1.25, etc. I'm sure there's a better way, but this is definitely what's causing this weird error.

Link to comment
Share on other sites

  • Solution

Hi,

 

This mostly has to do with some clash between the globals you're setting with gsap.globals() and the quickTo instances. Keep in mind that using globals you're setting the same stagger to EVERY GSAP instance that you create after that, so I would avoid that.

 

Better simplify your code to this:

const getStagger = (index) => {
  if (index === 0) {
    return 0.5;
  }
  if (index === 1) {
    return 1.25;
  }
  if (index === 2) {
    return 0.25;
  }
  if (index === 3) {
    return 1;
  }
  if (index > 3 && index < 8) {
    return 0.5;
  }
  return 0;
};

function animateMediumCards(card) {
  return gsap.fromTo(
    // stagger in the cards, starting with the first card and scaling down to the last card
    ".box",
    {
      scale: 1.25,
      autoAlpha: 0,
    },
    {
      scale: 1,
      autoAlpha: 1,
      ease: "power2.inOut",
      duration: 1.25,
      transformOrigin: "center center",
      stagger: getStagger,
    }
  );
}

That seems to work with your current approach:

https://codesandbox.io/p/sandbox/usegsap-nesting-forked-75k6x9?file=%2Fsrc%2FMyComponent.jsx%3A24%2C1-60%2C2

 

Also this is another approach that I find cleaner since you don't need the react refs for the quickTo instances:

https://codesandbox.io/p/sandbox/blissful-danny-7wf3cs?file=%2Fsrc%2FCard.jsx%3A31%2C22

 

But in both the key is to not set the globals and just create the initial stagger animation in the fashion is shown in the demos.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hi,

 

Nope there is no globals() method in the GSAP core:

https://gsap.com/docs/v3/GSAP/

 

https://gsap.com/docs/v3/GSAP/gsap.defaults()

 

The thing is that the defaults method sets up global config for every single GSAP instance created afterwards, that's why is has to be handled carefully and in some very specific cases. Normally you won't need that, but if you need to use the same config in many different tweens you can use QuickTo:

https://gsap.com/docs/v3/GSAP/gsap.quickTo()

 

Or setup a global config object that can be applied in multiple tweens. Also you can create a timeline and set the defaults only for instances created by the timeline, but that is not something needed in this particular case:

https://gsap.com/docs/v3/GSAP/Timeline#defaults

 

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