Jump to content
Search Community

Gsap add inline style after animation

Lichay test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Yes GSAP must set inline styles, of course, to animate the CSS values. So in your example, those inline styles get set and then when you resize your screen you've got a CSS media query that applies a different rule at a different size but the inline style will always overrule that. It's just a logic issue.

 

Side note:  we strongly recommend always setting your transform-related values via GSAP. We explain why here

 

You could call ScrollTrigger.saveStyles(".box"); before your animation which will record the inline styles of that element and then re-apply them whenever ScrollTrigger has to revert things due to a refresh(). However, keep in mind that if the animation is in-progress when you resize the screen, those inline styles would continue to get set by that animation, so you'd need to kill() it. 

 

That's kinda what ScrollTrigger.matchMedia() is for. You can set up different animations/ScrollTriggers in there and it'd handle killing the ScrollTrigger instances that no longer apply. 

 

I hope that helps. 

  • Like 4
Link to comment
Share on other sites

By the way, I noticed you're doing this after a yoyo: 

onComplete: function () {
  this.progress(0).kill();
}

I'm curious why you're doing that. I can't see any benefit. 

 

Here's a quick demo that resets things on resize and works the way I think you wanted: 

See the Pen 7af3ffb9e2a84b0de9979f6389455f81?editors=0010 by GreenSock (@GreenSock) on CodePen

  • Like 4
Link to comment
Share on other sites

8 hours ago, GreenSock said:

By the way, I noticed you're doing this after a yoyo: 



onComplete: function () {
  this.progress(0).kill();
}

I'm curious why you're doing that. I can't see any benefit. 

 

Here's a quick demo that resets things on resize and works the way I think you wanted: 

 

 

I think first to set savestyle like on doc, but I think that have better way with onComplete function.

it work perfectly but i have small question on your example you create two media query that do same thinks have a reason for that?

edit: I add comment

 

Link to comment
Share on other sites

10 hours ago, GreenSock said:

By the way, I noticed you're doing this after a yoyo: 



onComplete: function () {
  this.progress(0).kill();
}

I'm curious why you're doing that. I can't see any benefit. 

 

Here's a quick demo that resets things on resize and works the way I think you wanted: 

 

 

Hey, I see reason to add it when I use onComplete function it kill the progress and work well 

with media query it work well but restart the animation on change screen sizing.

 

so in my situation I prefer use onComplete function and don't restart the animation on change screen size

 

edit: in complex animation it do some issue 

 

See the Pen QWGWPoj by lichaytiram (@lichaytiram) on CodePen

and again broken inline style

Link to comment
Share on other sites

55 minutes ago, ZachSaucier said:

To prevent the animation from running again when the media query is reached I'd probably use a variable to keep track of state:

 

 

but click event isn't include 

it should be click after animation stop play

Link to comment
Share on other sites

10 hours ago, Lichay said:

I see reason to add it when I use onComplete function it kill the progress and work well 

I'm still confused - are you seeing different behavior with the onComplete: () => this.progress(0).kill() than without it? All that's doing is rewinding and killing the animation, but if it's already set to yoyo, it's not doing anything different. A yoyo ends where it started anyway. So it seems completely redundant to me.

 

10 hours ago, Lichay said:

with media query it work well but restart the animation on change screen sizing.

 

so in my situation I prefer use onComplete function and don't restart the animation on change screen size

Yes, that was the whole point :) I thought you wanted a different animation that runs from a different spot at the various screen sizes. 

 

If you want it to maintain the progress, you can record the progress value and resume from there: 

See the Pen ZEBYGvv?editors=0010 by GreenSock (@GreenSock) on CodePen

 

11 hours ago, Lichay said:

and again broken inline style

Can you please explain what you mean? 

  • Like 2
Link to comment
Share on other sites

46 minutes ago, GreenSock said:

I'm still confused - are you seeing different behavior with the onComplete: () => this.progress(0).kill() than without it? All that's doing is rewinding and killing the animation, but if it's already set to yoyo, it's not doing anything different. A yoyo ends where it started anyway. So it seems completely redundant to me.

 

Yes, that was the whole point :) I thought you wanted a different animation that runs from a different spot at the various screen sizes. 

 

If you want it to maintain the progress, you can record the progress value and resume from there: 

 

 

 

Can you please explain what you mean? 

 

after animation finish (go and back) it should let you click on that 

in my example 

See the Pen QWGWPoj by lichaytiram (@lichaytiram) on CodePen

 

change the screen to small size (purple color) let the animation finish after that click on box (green) now you should resize screen size to big

and click again on box - you can see the jump the green box go down instead do click animation on top.

 

if you wait on big screen size and click after that you see the box stay on top and he doesn't go down.

That my problem inline css stay on box after click event (in complex situation)

Link to comment
Share on other sites

  • Solution

Yeah, you're asking to replay a tween, but use totally different starting values (which isn't a true replay). You could just invalidate() those animations when ScrollTrigger refreshes so that they basically dump all their starting values and re-record them on the next render: 

See the Pen 9ba2140853398921425efa6c78318661?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Is that what you're looking for? 

  • Like 3
Link to comment
Share on other sites

13 hours ago, GreenSock said:

Yeah, you're asking to replay a tween, but use totally different starting values (which isn't a true replay). You could just invalidate() those animations when ScrollTrigger refreshes so that they basically dump all their starting values and re-record them on the next render: 

 

 

 

Is that what you're looking for? 

yes it really work but i hard to understand what happened there.

in first load it add push (actions.push(action)) but after he get  refresh he do get refreshInit by lisener and update the element to current values .

That what  I understand but it still kepping push every resize and array get be bigger and bigger and slow the website.

it hard to understand how it work from inside because if array have 24 length how it possible to read the right css for same element?

 

edit: I actually improve your cod performance to this

 

    const imageActions = [];
    ScrollTrigger.saveStyles(images);
    ScrollTrigger.addEventListener("refreshInit", () => imageActions.forEach(elementAnimation => elementAnimation.invalidate()));

 

 imageActions[index] = action;

 

but I don't understand how it work in your example that length more then 6 how it ready well the style from array that have more then 1 (in your codpen example - .box ) elements inside

 

edit 2: i keep explore it and learn every gsap element refresh very time when resize screen maybe random time or something else

for example:

    

gsap.to('.box', {
      top: 100y: 5x: 30duration: 3ease: 'power4.out',
      onComplete: function () {
      console.log('run');
      }
   }
 
it will print on console when resize screen every some time
Link to comment
Share on other sites

Yeah, I didn't look closely at your logic in there, but the problem was that you've got the ScrollTrigger wired to an animation with an onComplete which is then looping through and adding click listeners. I wouldn't recommend structuring it that way - it'd be cleaner to just use a variable like "clickable" that's false initially, and then you toggle it to true in the onComplete, but you create all your listeners outside of that onComplete. 

 

I updated my demo to show you how I think you wanted it to function - it also uses an onRefresh and onRefreshInit to save the progress of the animation and re-apply it so that the animation maintains its progress even when you cross the media query thresholds.

See the Pen 9ba2140853398921425efa6c78318661?editors=0010 by GreenSock (@GreenSock) on CodePen

 

Better? 

 

18 hours ago, Lichay said:

i keep explore it and learn every gsap element refresh very time when resize screen maybe random time or something else

for example:

    

gsap.to('.box', {
      top: 100y: 5x: 30duration: 3ease: 'power4.out',
      onComplete: function () {
      console.log('run');
      }
   }
 
it will print on console when resize screen every some time

That doesn't appear to be true: 

See the Pen 8dce93c0d265dc1e2dad30b7c7f26d13?editors=0010 by GreenSock (@GreenSock) on CodePen

 

But it would run for a tween that's attached to a ScrollTrigger because when you resize, it affects the progress of the scroll, and the animation that's attached would be adjusted. 

 

Side note: I'm also going to adjust the behavior in 3.6.1 so that if you kill() an animation, it'll also kill() the attached ScrollTrigger. 

  • Like 2
Link to comment
Share on other sites

On 2/1/2021 at 7:40 AM, GreenSock said:

Yeah, I didn't look closely at your logic in there, but the problem was that you've got the ScrollTrigger wired to an animation with an onComplete which is then looping through and adding click listeners. I wouldn't recommend structuring it that way - it'd be cleaner to just use a variable like "clickable" that's false initially, and then you toggle it to true in the onComplete, but you create all your listeners outside of that onComplete. 

 

I updated my demo to show you how I think you wanted it to function - it also uses an onRefresh and onRefreshInit to save the progress of the animation and re-apply it so that the animation maintains its progress even when you cross the media query thresholds.

 

 

 

Better? 

 

That doesn't appear to be true: 

 

 

 

But it would run for a tween that's attached to a ScrollTrigger because when you resize, it affects the progress of the scroll, and the animation that's attached would be adjusted. 

 

Side note: I'm also going to adjust the behavior in 3.6.1 so that if you kill() an animation, it'll also kill() the attached ScrollTrigger. 

 

First of all thanks

and second I don't see reason to use both 

 

phase 1

    onRefreshInit: self => self.savedProgress = self.animation.invalidate().totalProgress(),
    onRefresh: self => self.animation.totalProgress(self.savedProgress)

and 

phase 2

    this.scrollTrigger && this.scrollTrigger.kill();
    this.kill();

 

because it work with only one phase 

 

and moreover 

in side phase 2

if I use 

 

    this.scrollTrigger && this.scrollTrigger.kill();
   or 

    this.kill();

 

it work no need both of them or have reason for performance? (phase 2)

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