Jump to content
GreenSock

BrutalDev

Inline tween styles remain even when clearing/invalidating

Recommended Posts

Hi,

 

I have a basic timeline that tweens the opacity of list items in various ways. When certain things happen on screen I need to clear the timeline completely and also reset the elements back to their original starting values.

 

1st attempt: Just using restart() on the timeline expecting it to clear the existing inline "style" attribute. The timeline restarts nicely but it starts with the current inline values of the elements (eg: style="opacity: 0.89434") which ruins the animations because all the timings go off.

 

2nd attempt: Using invalidate() on the TimelineMax object to clear the existing values. This appears to have no effect, the inline styles are still in place after making the call. Calling restart() after an invalidate still has the same effect as attempt 1.

 

3rd attempt: Using clear() on the TimelineMax object and just re-adding all the TweenMax object to the timelines each time I want to play it. Clearing does indeed clear the tweens from the timeline, but does not reset the inline values so any subsequent tween will just start from the values it left off on.

 

Because the inline styles pretty much have the highest specificity I can't override easily by applying any CSS, I'll have to resort to stripping inline styles (manually or with jQuery) when getting rid of the tweens unless there is something built in to restore the elements back to when there was no tweening applied to them?

 

All the various 'kill' methods also don't get rid of the inline styles but at least it appears to reset when applying it again.

 

Please help, there's gotta be something simple to solve this problem.

 

Regards,

Werner

Link to comment
Share on other sites

Okay, first let me explain a few things:

 

When a tween renders for the first time, it must record the starting values so it looks at the target and grabs the current values. That way, it knows how to interpolate between the starting and ending values during the tween...

 

...So if you seek(0) on a tween or restart(), it will push them back to whatever the values were at the beginning of the tween (unless you're working with a from() tween of course, in which case it's reversed). This would not somehow "clear" any values from the element.style - it applies the starting values. 

 

And to be clear, in order to tween DOM element styles, GSAP must affect the element.style directly rather than attempting to create/apply a class or something like that - we NEED the high degree of specificity, otherwise if you had a class with a high(er) degree of specificity and you tried tweening the element it just wouldn't work. 

 

When you invalidate() a tween it just tells it to flush any starting values that it recorded internally when it first rendered - this also makes it re-record fresh ones the next time the tween renders. So you shouldn't expect invalidate() to do anything to the target.

 

When you clear() a timeline, all it does is dump the tweens from inside of it - that does nothing to cause the tweens to render in some special way or clear their targets' style properties, etc. clear() is like picking the tweens up out of their container and setting them on the floor outside of it so that they aren't contained in anything anymore. 

 

Okay, now the good news: the latest version of CSSPlugin (which is also inside TweenMax) recognizes a new "clearProps" special property which is a comma-delimited list of property names that you want to be cleared at the end of the tween. For example:

//at the end of the tween, clear only the left and top properties, leaving the color
TweenLite.to(element, 2, {left:100, top:200, color:"red", clearProps:"left,top"});

//or use "all" to clear ALL styles (even ones not tweened)
TweenLite.to(element, 2, {left:100, top:200, color:"red", clearProps:"all"});
 

Typically you don't need to define any vendor prefixes either - it'll handle that automatically. So, for example, to clear the transforms you can just put "transform" in the list or any of the transform-related properties like x, y, scaleX, rotation, etc. and it'll figure out if it should clear WebkitTransform or MozTransform or whatever. Same for "boxShadow" being "WebkitBoxShadow", etc.

 

Again, please make sure you're using the latest version. 

 

Does that help?

  • Like 1
Link to comment
Share on other sites

Hi BrutalDev,

 

Welcome to the GreenSock forums.

 

Most of what you are describing is consistent with how the platform is designed to work, although I'm a bit puzzled why attempt1: restart() didn't work as expected. Are you saying that the restart() didn't cause the timeline to play again from the beginning the exact same way that it played the first time?

 

When you clear(), kill() or invalidate() a timeline none of the properties of the target elements get reset. The running tweens will just simply stop dead in their tracks. Those methods are simply modifying/removing the data associated with that particular timeline/child-tweens (and possibly making them eligible for garbage collection). 

 

If you want the timeline to reset all the objects back to their starting positions you can do this:

 

 

 

myTimeline.pause(0);

//and if you want to then clear or kill it do
myTimeline.clear(); //or .kill()
 

 

Note, that using clear() or kill() will still leave all the objects that were tweened at their starting positions, but inline styles will still remain.

 

 

Moving forward with this issue, it would be very helpful to see a very simple example of the issues you are facing. Most importantly it would help to see how restart() isn't restarting the timeline properly.

 

Also as semi-related topics, the CSSPlugin now supports a clearProps property that allows you to remove certain inline styles or all styles when the tween is done. Check the latest docs (at the bottom) : http://api.greensock.com/js/com/greensock/plugins/CSSPlugin.html

 

Here is an example of a timeline that tweens 3 objects.

See the Pen 81bc98042d2029c1018c27374afc25c1 by GreenSock (@GreenSock) on CodePen

Click the reset button and you will see that no inline-styles remain after the timeline is killed and all objects reset back to their starting positions:

 

reset.click(function() {
  master.kill();
  TweenLite.set([red, blue, green], {clearProps:"all"});
});
 

 

I'm sure there is a way to get the results you desire without doing a lot of funky work-arounds. Again if we can see a very simple example of what you are trying to do (and what's breaking) it would really help.

  • Like 1
Link to comment
Share on other sites

Long story short, clearProps is EXACTLY what I'm looking for! I am using 1.8.1 and just misunderstood what invalidate and clear was doing to the timeline and that's what caught me out all along. I also should have RTFM for CSSPlugin, I was spending too much time thinking it was something the TimelineMax or TweenMax modules should be doing.

 

restart() was not working because I invalidate()/clear() in the middle of a tween and according to your explanation this will clear the starting values I would need to restart correctly and it continues from the values it detects in the style attribute. Totally understood.

 

I am manually clearing specific attributes with jQuery and regular expressions with the same selectors that do the tweens so you can imagine how pleased the clearProps makes me. There is also a rotation in there so offloading the prefix detection will also be great.

 

I can't test right now but based on the awesome information provided, the combination of kill() and clearProps should do the trick nicely. That set() in the code example is also going to be crucial since I only stop and clear when a user event occurs. I'll re-post my findings when I go refactor things tomorrow. Is there any way to automatically clearProps when stopping/clearing an infinitely looping timeline?

 

On a separate note, the code example has a call to kill() which I don't recall seeing, then I noticed there is a link to "Show Inherited Public Methods", a whole new world has opened up...

Link to comment
Share on other sites

Cool, glad to hear it makes sense. And don't worry, clear() and invalidate() are sometimes a little tricky to grasp until you have a need for them or try to use them. As for not reading the manual, we'll give you a pass as clearProps was only added yesterday;)

Link to comment
Share on other sites

  • 2 years later...

I am just thinking... isnt a better idea to simply remove css properties with raw javascript like this (I mean instead of using "clearProps")?

delete myObject.style.color;

I guess performance should be better to remove it directly like this. Just wondering if there may be any side effects.

Link to comment
Share on other sites

How much faster is that? Letting GSAP do it will handle vendor prefixes and transform properties managed by the engine.

  • Like 1
Link to comment
Share on other sites

The other thing that technique doesn't factor in is the values that are stored/cached in the _gsTransform object, like x/y/z/rotation/rotationX/rotationY/skewX/skewY. But other than that, it should be fine, though the performance difference would probably never be even remotely noticeable. 

  • Like 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.
×