Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
kreativzirkel

Vue <transition> jump bug with gsap v3

Recommended Posts

Sorry, I don't have the time to reproduce this in codepen; maybe it only happens in our dev environment. But fact is: We had no issue under gsap v2, with v3 we do have. I don't see what I've done wrong here. 

 

video of the bug with gsap 3

https://imgur.com/a/SV60XJJ

 

probably trivial, but just to be sure: here how it's supposed to look (working with gsap 2)

https://imgur.com/a/VGhSY4F

 

simple vue template:

<template>
	<transition @enter="enter" @leave="leave">
		<div v-if="isOpen">
			<div class="overlay" ref="overlay"></div>
			<div class="container" ref="container">
				...
			</div>
		</div>
	</transition>
</template>

 

with gsap 3:

enter(el, done) {
    return gsap.timeline({ onComplete: done })
        .from(this.$refs.container, this.enterDuration, {
            xPercent: 100,
            ease: 'power3',
            clearProps: 'all',
        }, 0)
        .from(this.$refs.overlay, this.enterDuration, {
            opacity: 0,
            clearProps: 'all',
        }, 0);
},

 

with gsap 2:

enter(el, done) {
    return new TimelineMax({ onComplete: done })
        .from(this.$refs.container, this.enterDuration, {
            xPercent: 100,
            ease: Power3.easeOut,
            clearProps: 'all',
        }, 0)
        .from(this.$refs.overlay, this.enterDuration, {
            opacity: 0,
            clearProps: 'all',
        }, 0);
},

 

 

Thrilled to hear what you think. Until there's a solution for that I sadly have to revert to v2 😢

 

Thanks!

Share this post


Link to post
Share on other sites

It's hard to say without the ability to see it for ourselves. Guessing somewhat blindly, it could be because the overwrite property has a different default in GSAP3. In GSAP 2 it was "auto" by default but in GSAP 3 it's false. You can test it by putting gsap.defaults({overwrite:"auto"}); to the top of your script.


Side note, it's good to put the duration inside of the vars parameter.

  • Like 1

Share this post


Link to post
Share on other sites

Hi,

 

I remember running into a similar issue in a project working with React Transition Group (keep in mind that RTG and Vue transition work in a very similar fashion as both are heavily inspired by earlier versions of angular's ng-animate). The issue is the initial position of the elements when the animation starts, that's why you add clearProps: "all" in your tweens. A good solution is to remove clearProps from the config and add a couple of .set() instances at the start of the timeline in order to give the initial state to the elements being animated, a bit like this:

 

return gsap.timeline({ onComplete: done })
  .set(this.$refs.container, { xPercent: 100 })
  .set(this.$refs.overlay, { opacity: 0 })
  .to(this.$refs.container, {
    duration: this.enterDuration,
    xPercent: 0,
    ease: 'power3',
  }, 0)
  .to(this.$refs.overlay, {
    duration: this.enterDuration,
    opacity: 0.65,
  }, 0);

The overhead of using this approach should be virtually none, so you shouldn't have any performance issues.

 

I don't have time to create a full working Vue demo, so I made a simple codepen demo instead:

 

See the Pen JjjeNQN?editors=0010 by rhernando (@rhernando) on CodePen

 

Consider the first click of the show sidebar as the moment when the element is mounted, for the purposes of this situation just imagine that the sidebar and overlay are not visible when the code runs for the first time.

 

Happy Tweening!!!

  • Like 3

Share this post


Link to post
Share on other sites
11 hours ago, ZachSaucier said:

Side note, it's good to put the duration inside of the vars parameter.

why is that? I really like the "old syntax"; I'm used to it, it's faster to type, easier to see at a glance what the duration is, etc.

 

I will need to look into the `overwrite` solution; right now here in Germany shoulllld be sleeping time :D

having to set where things are at the beginning of the timline would be really bothersome and be kind of a downgrade for me personally– 

 

 

Share this post


Link to post
Share on other sites
1 hour ago, kreativzirkel said:

why is that? I really like the "old syntax"; I'm used to it, it's faster to type, easier to see at a glance what the duration is, etc.

We moved it into the vars parameter so that it can be used with defaults/inheritance. The v2 syntax may not be supported whenever GSAP eventually moves on to v4. 

 

1 hour ago, kreativzirkel said:

having to set where things are at the beginning of the timline would be really bothersome and be kind of a downgrade for me personally

Maybe passing in specific values to the clearProps would be viable? 

Share this post


Link to post
Share on other sites
3 hours ago, kreativzirkel said:

why is that? I really like the "old syntax"; I'm used to it, it's faster to type, easier to see at a glance what the duration is, etc.

 

Another benefit is that you can use function based values.

 

gsap.to(".box", {
  duration: i => (i + 1) / 4,
  x: 200
});

 

See the Pen 3b45dbd961f8c12e15170827914ca9ed by osublake (@osublake) on CodePen

 

 

  • Like 3

Share this post


Link to post
Share on other sites
14 minutes ago, OSUblake said:
3 hours ago, kreativzirkel said:

why is that? I really like the "old syntax"; I'm used to it, it's faster to type, easier to see at a glance what the duration is, etc.

 

Another benefit is that you can use function based values.

And it fits with keyframes and makes the code more readable/clear. Trust me - it's a little annoying at first for people who are very used to the "old" way, but I'm pretty confident you'll grow to appreciate it after a while. 

  • Like 2

Share this post


Link to post
Share on other sites
10 hours ago, kreativzirkel said:

having to set where things are at the beginning of the timline would be really bothersome and be kind of a downgrade for me personally

Not to be stubborn about this, but the sequence of using a from() instance with clearProps in it is somehow close to this: clearProps will remove all inline styles from the DOM element, then GSAP records the initial position of the element, sets a new position to the one pass in the config object and finally tweens the properties to the initially recorded values, so using a set call at the start of the timeline is not very different from that.

 

Just my two cents on the subject.

Happy Tweening!!!

  • Like 3

Share this post


Link to post
Share on other sites

I'm confused :D

The reason I use clearProps is not to set the initial value; I thought clearProps clears the properties AFTER the tween. I use it to clean the element of any unnecessary styles afterwards (in the style tag), so that it doesn't interfere with my "normal" css positioning etc. (I had responsive issues in the past)

 

Again: I thought clearProps only does something AFTER the tween is completed.

 

Anyhow: I thought the .from() syntax does what @Rodrigo describes under the hood, so I don't have to. I mean why else would .from() exist if it doesn't work like that? and it has/does in v2. 

 

Just to be clear: do you guys say the issue I showed in the video is supposed to happen like this under v3 or do you agree that this is a bug (be it from gsap v3 or my code)?

Share this post


Link to post
Share on other sites
1 hour ago, kreativzirkel said:

Just to be clear: do you guys say the issue I showed in the video is supposed to happen like this under v3 or do you agree that this is a bug (be it from gsap v3 or my code)?

 

Hard to say without being able to test it. Try changing the default overwrite, and see it that helps.

 

gsap.defaults({
  overwrite: "auto"
});

 

  • Like 1

Share this post


Link to post
Share on other sites

`overwrite: "auto"` didn't do the trick, unfortunately.

 

I made 2 code sandboxes illustrating the issue.

 

without issue

https://codesandbox.io/s/gsap-v2-no-jump-bug-umw6x?fontsize=14

 

with issue

https://codesandbox.io/s/gsap-v3-jump-bug-in-vue-3272l?fontsize=14

 

Interesting: when you remove `clearProps` from the v3 sandbox, the issue doesn't occur. So apparently I do not understand what clearProps is supposed to do or we really have gsap bug here.

 

Nevertheless: even if the v3 sandbox illustrates the intended behavior, I'd argue this should be changed to the way it worked in v2. Thrilled to read if you disagree with that and why you made this change.

 

Share this post


Link to post
Share on other sites
3 hours ago, kreativzirkel said:

The reason I use clearProps is not to set the initial value; I thought clearProps clears the properties AFTER the tween.

Actually clearProps is working at the start of the animation and is quite logic if you think about it. You have a DOM element and it's natural initial position is x: 0, then you use a from() instance in order to animate such element from x: 100% to x: 0 (initial position), the element is moved to x: 100% and then animated to 0. Then in the out animation you have a to() instance that moves the element to x: 100%. If for some reason the from instance is started when the value of x is not 0 the animation will end in the value of x it has when it was created, right? clearProps to the rescue!! clearProps removes all inline styles applied by GSAP so the element returns to it's initial natura position, that is x: 0, then the from instance moves it to x: 100% and animates it back to x: 0. The from instance is setting the position of the element, not the clearProps in the config object. But clearProps is the reason why you're seeing that particular jump in this case and why using a set() instance and then a regular to() instance doesn't create such issue.

 

The big question is why this differ from V2? We'll summon our beloved Tween Lama @GreenSock so He can enlight us all and clear this doubts ;) 

  • Like 1

Share this post


Link to post
Share on other sites
Quote

clearProps

You may enter a comma-delimited list of property names into clearProps that you want to clear from the element’s style property when the tween completes (or use "all" or true to clear all properties). This can be useful if, for example, you have a class (or some other selector) that should apply certain styles to an element when the tween is over that would otherwise get overridden by the element.style-specific data that was applied during the tween. Typically you do not need to include vendor prefixes.

https://greensock.com/docs/v3/GSAP/CorePlugins/CSSPlugin

 

The docs don't reflect that clearProps clears the `style`-tag BEFORE the tween starts. 

 

See the Pen eYYbrKM by katerlouis (@katerlouis) on CodePen

 

as I understand Rodrigo, the box in

See the Pen eYYbrKM by katerlouis (@katerlouis) on CodePen

 should clear the style tag before the second tween (y), which doesn't happen. In case this is because both tweens end up in transforms, I also added a change in background color to the first tween. But the background color also stays until the end of the second tween, where everything gets reset by `clearProps`.

 

I guess either Rodrigo or me are wrong :D

Can anybody confirm Rodrigos statement about clearProps?

 

But yeah; it remains to be revealed why v3 behaves different. Thrilled to hear the Elders on that!

 

 

PS: Linking to a pen via bookcode gets weird results :D

Share this post


Link to post
Share on other sites

Mhhh.... yeah you're right about that, it seems the real issue here is mixing from instances with clearProps in V3 creates a different effect that in V2

 

From instances with clearProps V2:

See the Pen oNNJygN?editors=0010 by rhernando (@rhernando) on CodePen

 

From Instance with clearProps V3:

See the Pen ExxGRVJ?editors=0010 by rhernando (@rhernando) on CodePen

  • Like 1

Share this post


Link to post
Share on other sites

Yes, thanks for pointing this out - I'm working on a fix and should have something in the beta tomorrow sometime. 

  • Like 2

Share this post


Link to post
Share on other sites

Nice, I found a bug! Whoop Whoop!

 

Out of curiosity. Could you share with us what went wrong there and what you did under the hood to fix it? (Not that I will understand more then 20% of it, if I'm lucky..)

  • Like 1

Share this post


Link to post
Share on other sites

Well, there isn't really a concise explanation I can offer, but basically when there's a from() or fromTo() tween the engine needs to create a secondary tween instance internally to record the initial values so that they can be reverted properly in certain cases (like if your from() tween has immediateRender and a delay, there could be other external things that mess with values between the initial render and when the tween actually starts, thus it must run that zero-second tween at the start to ensure things are exactly where they're supposed to be). That internal zero-duration tween in this case had clearProps being applied, thus at the very start of both from() tweens, the properties were getting cleared so I needed to have clearProps ignored in that case. 

  • Like 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×