Jump to content
Search Community

Why is GSAP not respecting initial/from values for some tweens?

alvinteh test
Moderator Tag

Recommended Posts

There are issues with a couple of Tweens in a project I'm working on. For some reason, GSAP does not seem to respect the initial/from values for those Tweens on the first playthrough of the timeline.

 

The tween is simple, I'm trying to animate some text elements as follows:

 timeline.fromTo(headerRef.current.children, {
    filter: 'blur(4rem)',
    opacity: 0,
    scale: 0.05,
    y: '75px',
  },
  {
    filter: 'blur(0rem)',
    opacity: 1,
    scale: 1,
    y: 0,
    ease: 'power1.out',
    duration: 0.4,
    stagger: 0.25,
});

However,  prior to play, the filter/opacity/scale/y values of the respective elements do not reflect the initial/from values indicated in the code above, and as a result, the tween looks incorrect.

 

I have attached a clipped video showcasing the issue. Note how on the opacity and filter blur values of the first <span> are 1/0rem initially. However, when I perform a tweenTo() back to the original position of the timeline, and opacity/blur values are correct, and the subsequent playback is correct.


Things I have tried to no avail:

  • Switching the fromTo() to a to() (and not specifying the initial values in CSS)
  • Switching the fromTo() to a to() (and specifying the initial values in CSS)
  • Switching the fromTo() to a from() (and not specifying the final/target values in CSS)
  • Switching the fromTo() to a from() (and specifying the final/target values in CSS)
  • Removing the ease and stagger properties (those alter some of the initial values as expected, but they are still incorrect)
  • Simplifying the properties being animated (e.g. cut everything other than opacity); this expectedly does not resolve the issue

Outside of the workaround, no other code is interacting with/manipulating the animated elements. Interestingly enough, this issue only presents itself on the first tween of the timeline (and it does not seem to affect all tweens, only two in my entire project). In addition, while I don't think it should affect things, these are child timelines within a larger parent timeline (from my previous thread).

 

 Some workarounds that resolve the issue:

 

(1) The issue is resolved if I add a set() call right after fromTo() to "force" the initial values, i.e:

timeline.fromTo(...); // Full code from initial snippet
                
timeline.set(headerRef.current.children, {
  filter: 'blur(4rem)',
  opacity: 0,
  scale: 0.05,
  y: '75px',
}, '<');

(2) Given the issue only presents itself in the first tween, if I add another "meaningless" tween before the actual one, the actual tween works smoothly. 

timeline.fromTo(headerRef.current.children, {
  z: '1px'
}, {
  z: 0
});

timeline.fromTo(...); // Full code from initial snippet

While I have added a CodePen that describes what I am trying to achieve, I have not been able to reproduce the issue in the CodePen.

 

I appreciate that the lack of a CodePen with the issue makes debugging/assisting this matter more challenging, and the fact that I found workarounds may also make this a lower priority, but if possible, I would still like to understand the cause of the issue and it should be properly resolved.

See the Pen vYPJqBV by alvinteh (@alvinteh) on CodePen

Link to comment
Share on other sites

CodePen isn't always ideal for these kinds of issues, so here are some Stackblitz starter templates for most of the frameworks out there. 

In case of React are you doing proper cleanup? Or even better use our new useGSAP() hook  it is indeed hard to debug something if we don't see the issue. If these don't solve the issue, what I like to do is start disabling big chunks of my code base until the issue is gone and then start introducing small chunks back in to see if the issue comes back. That way you can pin point the issue and thus debug it. Are you for instance having CSS in the line of transition: all 500ms ease-in?

Link to comment
Share on other sites

Yes, I am using the useGSAP() hook. I don't think it's a React issue though, other than the refs, there is nothing React-specific in this case (a contrast from my previous thread).

 

7 minutes ago, mvaneijgen said:

If these don't solve the issue, what I like to do is start disabling big chunks of my code base until the issue is gone and then start introducing small chunks back in to see if the issue comes back. That way you can pin point the issue and thus debug it.

I have tried that (that is how I noticed it the issue, if present, only affects the first tween in the child timeline), but did not manage to progress much further debugging-wise. I also highly doubt the issue has to do with the properties being animated, as the other affected tween(s) involve different properties. The elements also behave/appear correctly when I remove all of the tweens. What I find most peculiar is that this only affects a couple of tweens, and only on the initial playthrough (I have also tested using GSDevTools).

 

5 minutes ago, mvaneijgen said:

Are you for instance having CSS in the line of transition: all 500ms ease-in?

Sorry, I don't quite get your question? There is no CSS pertaining to animations and/or transitions, if that is what you are asking, only things like font-family and font-size, which shouldn't impact the animation.

Link to comment
Share on other sites

Hi,

 

I'm not seeing the issue in the codepen demo you linked, but most likely this is about FOUC (Flash Of Unstyled Content):

https://gsap.com/resources/fouc/

 

That is absolutely expected since it takes a few moments to execute the JS code that creates the animations and renders things the proper way, that is GSAP setting the opactiy to 0 and the blur value in the Tween configuration. Is just the way browser rendering works, not really a GSAP issue.

 

Hopefully this clear things up.

Happy Tweening!

Link to comment
Share on other sites

Hi Rodrigo, thanks for getting back to me!

Yes, the issue does not exist in the CodePen demo; I was unfortunately unable to reproduce it in a minimal demo.

 

Question on the FOUC: do you mean that  the opacity: 1 style is being set prior to GSAP executing the fromTo()? If so, shouldn't specifying the initial styles via CSS resolve that? 

On my end, my belief is that GSAP is somehow mistakenly setting that opacity: 1 style as there are no other scripts/CSS influencing that element's display. When I remove the tweens, the inline styles expectedly disappear -> I believe those are being injected by GSAP. Looking at the video I shared, you can see that the two <span>s (i.e. the two children being animated) have opacity values of 1/0.6062, among other styles, that do not tally with the initial values set in the fromTo(). The tween code for the actual project and the CodePen demo are identical.

 

In case it was some form of race condition, I have also tried specifying the initial values in CSS (mentioned in my post), but those are also (expectedly) being overridden by GSAP, though unfortunately with the wrong values (i.e. I expect GSAP to inject opacity: 0, but it is injecting opacity: 1).

 

I also doubt the issue has to do with the tween itself, due to how workaround #2 works. On the flip side, removing the problematic tween only causes the issue to affect the new first tween.

 

My guess is there is some form of race condition somewhere, although how/why that causes GSAP to inject the incorrect initial values is perplexing.

 

Or, if we approach this from another angle, how does GSAP determine and populate the initial style values? Perhaps understanding that will help me identify the root cause.

Edited by alvinteh
Added extra info on video
Link to comment
Share on other sites

Hi,

 

Yeah I believe that the confusion might stem from not understanding exactly what from() and fromTo() instances do:

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

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

 

Basically animate from the values you pass into the config object to the element's natural state at the moment when the code is created. So in your case your elements both have no blur applied to them and their opacity is 1, that's their natural value when the instance is created. Then GSAP animates them from opacity: 0 and blur: 15px to their natural state (opacity: 1 and blur: 0). The best way to avoid FOUC is to hide a parent element (if possible) and after the from instances are created, show the parent element again:

gsap.from(".text", {
  opacity: 0,
  filter: "blur(15px)",
  duration: 1,
});
// Now show the parent
gsap.set(".text-parent", { autoAlpha: 1 });
24 minutes ago, alvinteh said:

In case it was some form of race condition, I have also tried specifying the initial values in CSS (mentioned in my post)

I didn't see any styles neither in your snippet nor your demo 🤷‍♂️

24 minutes ago, alvinteh said:

being overridden by GSAP, though unfortunately with the wrong values (i.e. I expect GSAP to inject opacity: 0, but it is injecting opacity: 1)

Nope, GSAP is doing exactly what's supposed to, starting from opacity: 0 and finishing with opacity: 1, I don't see any of that in the video or the demo.

24 minutes ago, alvinteh said:

if we approach this from another angle, how does GSAP determine and populate the initial style values? Perhaps understanding that will help me identify the root cause.

I strongly recommend you to read the documentation links I provided above and the article from my first post in this thread:

https://gsap.com/resources/fouc/

 

Hopefully this clear things up.

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