Jump to content
Search Community

gsap.from not working correctly in next js

Romanus test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

gsap.from doesn't work correctly in next js.
I want the text to go from opacity 0 to opacity 1.
But in next js javascrypt works with a delay. Because of this, opacity is 1 - 0 - 1.
to see the problem, open the link (in the screenshot) in a new tab, noticeable only when first opened.
Is it possible to solve this somehow?

The only option I see is to manually set the opacity to 0 and use gsap.to.
But this is not convenient in some cases.

GSAP NextJS App dir (forked) - StackBlitz

 

Screenshot_1.png

Link to comment
Share on other sites

It looks to me like the problem is very likely that in React 18+, useEffect() is actually called TWICE in strict mode and you're not doing any cleanup, so you're creating multiple conflicting animations. 

 

gsap.context() is your new best friend in React - it makes cleanup super easy and also allows you to use scoped selector text. Please read this article: 

 

 .from() tweens use the CURRENT value as the destination and it renders immediately the value you set in the tween, so when it's called the first time it'd work great but if you call it twice, it ends up animating from the from value (no animation). It's not a GSAP bug - it's a logic thing.

 

For example, let's say el.x is 0 and you do this: 

useEffect(() => {
  // what happens if this gets called twice?
  gsap.from(el, {x: 100})
}, []);

 

The first time makes el.x jump immediately to 100 and start animating backwards toward the current value which is 0 (so 100 --> 0). But the second time, it would jump to 100 (same) and animate back to the current value which is now 100 (100 --> 100)!  See the issue?

 

So just use a gsap.context() and do proper cleanup: 

 useEffect(() => {
   let ctx = gsap.context(() => {
     // put all your GSAP/ScrollTrigger code inside here...
   });
   return () => ctx.revert(); // <-- CLEANUP!
 }, []);

Does that resolve things? If not, please provide a CodeSandbox or Stackblitz illustrating the problem and we'd be happy to take a peek. But I bet the issue is just not doing proper cleanup. Here are some Next.js starter templates with GSAP: 

https://stackblitz.com/@GreenSockLearning/collections/gsap-nextjs-starters

 

Happy tweening!

  • Like 1
Link to comment
Share on other sites

Unfortunately, the problem is not the lack of context.

next js only sends html at first, then loads js a second later. I made the problem more visual. In the fromTo function, the color should change from blue to red. But the first second it's black because the js didn't load. Because of this, I cannot use from and fromTo normally, and scrollSmoother also does not start immediately, the first second of movement is sharp and all pins do not work

example - GSAP NextJS test - StackBlitz

Link to comment
Share on other sites

I'm completely unfamiliar with Next.js, but from some Googling it seems like that flash of unstyled content is a VERY common complaint in Next.js and of course it's completely unrelated to GSAP. The useIsomorphicLayoutEffect() technique seems to work: 

 

const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;

// use this instead of useEffect() or useLayoutEffect()
useIsomorphicLayoutEffect(() => {
  // your code here...
}, []);

It is described here: https://medium.com/@alexandereardon/uselayouteffect-and-ssr-192986cdcf7a

 

And here it is in a fork of your demo: 

https://stackblitz.com/edit/nextjs-sh4zey?file=app%2Fpage.js

 

Does that help? 

  • Thanks 1
Link to comment
Share on other sites

Thank you! It works. But there is something that I cannot understand.

In your fork, you are using useEffect but not importing it from React. This is causing an error in the console.

https://stackblitz.com/edit/nextjs-sh4zey?file=app%2Fpage.js

 

If import useEffect then the problem returns. Is it possible to get rid of the error and solve the problem?

https://stackblitz.com/edit/nextjs-rh3rpj?file=app%2Fpage.js

Link to comment
Share on other sites

  • Solution

Hi,

 

Indeed the import is missing and it should be there, but this (as you pointed in a previous post) is because the JS take some time to execute. What you're doing is creating a page on the server that is later send to the client. Regardless if GSAP runs or not on the server an HTML document is send to the client. In that document there is a link to a JS file and also you have some base styles. In this case the font color is black by default. Then the JS is executed at which point GSAP makes the font color blue and then tween the color to red. That is just the way from instances work because of execution order/time. If you want to prevent that you can either set the initial color or state of your element using CSS (something I always try to do when using from instances) or perhaps hide the element until before creating the from instance, something like this:

CSS

.my-title {
  opacity: 0;
  visibility: hidden;
}

JS

gsap.set(".my-title", { autoAlpha: 1, color: "blue" });
gsap.to(".my-title", { color: "red", duration: 5 });

Here is a live example:

https://stackblitz.com/edit/nextjs-gyxsen?file=app%2Fpage.js

 

As stated before this has nothing to do with the way GSAP works, it's just the way HTML/CSS/JS works. It just takes some time to run the JS and apply the initial styles in from and fromTo instances.

 

Hopefully this clear things up. Let us know if you have more questions.

 

Happy Tweening!

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Thank you! Your solution works. But why does the example with the error work better? In this example, the animation starts much earlier https://stackblitz.com/edit/nextjs-sh4zey?file=app%2Fpage.js

I wrote this question on stackoverflow, if I learn something new I will let you know. I'm trying to see if it's possible to run JavaScript instantly without getting an error)

Link to comment
Share on other sites

Sorry about the error with not including useEffect in the import. It was very late and my brain was half asleep. 

 

Rodrigo is correct - this is just the nature of SSR stuff. It's completely unrelated to GSAP. The reason that demo appears to work is probably because of the error - it was halting JS execution (not good). So yeah, that's not really a "solution" to your original question. Rodrigo's approach is likely the only valid one - initially hide your content and then only show it when the component is mounted. Like toggle the opacity or visibility (initially set it to be hidden). 

 

Good luck!

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • 8 months later...

Well I also have this same issue. Moral of the story is if you want use gsap in next js. You need to do opacity 0 in css only and in animation set opacity to 1. There is no need to use other things like uselayouteffect. Opacity 0 is needed only for loading elements that show on load and have gsap animation, not all. I think you guys need to do something specially for nextjs, if you think next js is future.

Edited by mbisht
added more details
Link to comment
Share on other sites

Hi @mbisht and welcome to the GreenSock forums!

 

We totally understand the relevance of React/Next in web development, but we also acknowledge other frameworks and vanilla projects as well. Because of that we work tirelessly to keep GSAP framework agnostic so every developer out there can have fun and creating amazing UIs with it.

 

As mentioned in this thread, this is just the nature of how HTML/CSS/JS works:

 

As you can see from that article we do our best to give our users the simplest and most robust solution possible. Sometimes that can be a bit more complicated or cumbersome, but that is due to the way some specific frameworks do their thing.

 

Happy Tweening!

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