Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Julius Friedman

TweenMax.isTweening

Recommended Posts

Noticed that TweenMax.isTweening lets you determine if the engine is working on a tween for a given element.

I have a question about direction and inital / end values of the tween; what I am w
ondering is if you can determine what properties and in what direction the tween is going or some other type of state to go along with the tween besides tracking that yourself.

 

The engine must have the start and end values (just as the user must also unless they are using relative properties)...

e.g. you can look at the _gsTransform.x to determine what the x property is at the current moment but unless you keep very granular state you don't always know when or where you are in the transform, hence I was assuming I could get that from the tween however it's complicated as there may be multiple tweens playing and effecting the properties...

 

e.g. if I have a timeline and it's playing than TweenMax.isTweening will return true for that object, I inspect the _gsTransform to sample the properties I need however it would be nice to have an indication at this point if the Tween is going in forward or reverse without having to call

`TweenMax.getTweensOf()` and then looping the tweens which will effect the property... I would have to know which tweens I was looking for or at least what properties I was looking for to make a function like

TweenMax.isTweening(t, 'opacity')

TweenMax.isTweening(t, 'scale')

 

Which I feel is many times more useful than isTweening because you might only care about a certain property....

It seems like this would be efficient for the engine to handle as it already knows what is being tweened... It also doesn't seem like it's that complicated of a function to write on the basis on my point. You would just get the tweens for that element and look in the vars for the property being effected.


I can take a crack at it and see what I can come up with but please do let me know if you need an example or how you think I should handle this / how you guys typically handle this.


 

var tween = TweenMax.isTweening(t, 'scale');

var oldComplete = tween.vars.onComplete;

tween.onComplete = function(){ oldComplete(); }

 

This would easily let you get the tween which is effecting the scale property, wait for it to be completed and then call your function. You could also expand this to check again for something tweening scale etc.

 

If you agree then it seems the next logical step would be to add a `queue` function (optionally with labels) so you can then do something like:

TweenMax.queue(TweenMax.to(el, 1, {scale: 0}))

Which would queue the tween but only when there were no more scale operations... further options could also be allowed from there e.g. using a timeline etc..

 

Hopefully I missed something but if not hopefully you agree that this would be another good enhancement!

A few possible uses:

 

1) Augment tweens in a timeline / user interactions such that if another interaction occurs or another animation plays you can more seamlessly choose when to pause / resume or truncate etc.

2) Tell if something is on it's way to being hidden or a size or position or in advance what the end position / values will be (if not truncated etc), powerful when moving something relatively or running movement and scaling tweens separately due to 1)

3) Determine where to augment without waiting for the tween, e.g. I'm no longer forced to separate function logic so granularity because I can easily determine if the logic required is still able to run, Powerful for stacked animations e.g. if I have multiple unused graphics I want to animate out but keep that amount within a tolerance I can much more easily do that without any other state. (e.g. when only 2 graphics are in use maybe the augmented animation will play much more heavily then when there are 10 graphics in use i.e. they will only scale until there is 2 left then they will morph).

 

Let me know if that makes sense, I know I can probably achieve this by keeping small state objects around but since the engine already has the objects in memory as well as the resulting values in the to / from the tween it seems somewhat wasteful. It also seems to pair well to the way you can store information in the tween with set and it will store that value, this way I can . to, .from . whatever and {x:0, y: 0, { state:{ .... }}} and from the object in the state of the tween I can take intelligent action and then if I kept state as a reference I could access it from else where outside of the tween with no additional memory overhead...

 

Hopefully that makes sense but I have been looking at a lot of code today... I am going to try and get some sleep.

 

Sincerely!

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, Julius Friedman said:

It also doesn't seem like it's that complicated of a function to write on the basis on my point. You would just get the tweens for that element and look in the vars for the property being effected.

It's probably more complicated than you'd expect. It seems your statement was based on the assumption that start/end values are always stored cleanly in the vars object, but that isn't the case. For example, a bezier tween may contain an array of values with nested x/y pairs (or any property). And there are many other examples like that. 

 

Frankly, in all my years of doing this I can't remember anyone requesting this kind of functionality, nor have I needed it myself. Sure, there are times I may want to kill certain properties of a certain object from tweening, and that can already be accomplished with killTweensOf(). 

 

I totally appreciate your thoughtful suggestions and they're not without merit. However, when developing a product like GSAP, it's always a difficult balancing act between packing in as much functionality as I can while keeping the file size down and the performance way up...oh, and trying to prevent the API surface area from expanding like crazy to the point where it's just confusing/overwhelming for end users. 

 

I can't tell you how many times I've thought "well, in theory this feature might be cool..." or "oh, in this very specific use case, this feature would be nice to have..." and if I just keep cramming things in there, GSAP would end up becoming a monster. 

 

It's certainly possible to add code to the core to allow you to getTweensOf(target, property), but I'm struggling to convince myself that more than 0.01% of users would ever actually tap into that and I'm not sure it's worth the added complexity, kb, etc. Others are certainly welcome to chime in - if we get a lot of requests for that type of thing, I'd definitely reconsider it. But again, in all my years of doing this (and over 8,000,000 sites using GSAP including most award-winnings sites), I can't remember anyone else asking for that type of functionality. (That doesn't mean it's without merit).

 

Again, I sure appreciate the thought you've put into these posts and your desire to help us make GSAP even better. I'm working hard on GSAP 3.0 and I think you're gonna really like it. :) 

  • Like 3

Share this post


Link to post
Share on other sites
6 hours ago, GreenSock said:

It's probably more complicated than you'd expect. It seems your statement was based on the assumption that start/end values are always stored cleanly in the vars object, but that isn't the case. For example, a bezier tween may contain an array of values with nested x/y pairs (or any property). And there are many other examples like that. 

 

Frankly, in all my years of doing this I can't remember anyone requesting this kind of functionality, nor have I needed it myself. Sure, there are times I may want to kill certain properties of a certain object from tweening, and that can already be accomplished with killTweensOf(). 

 

I totally appreciate your thoughtful suggestions and they're not without merit. However, when developing a product like GSAP, it's always a difficult balancing act between packing in as much functionality as I can while keeping the file size down and the performance way up...oh, and trying to prevent the API surface area from expanding like crazy to the point where it's just confusing/overwhelming for end users. 

 

I can't tell you how many times I've thought "well, in theory this feature might be cool..." or "oh, in this very specific use case, this feature would be nice to have..." and if I just keep cramming things in there, GSAP would end up becoming a monster. 

 

It's certainly possible to add code to the core to allow you to getTweensOf(target, property), but I'm struggling to convince myself that more than 0.01% of users would ever actually tap into that and I'm not sure it's worth the added complexity, kb, etc. Others are certainly welcome to chime in - if we get a lot of requests for that type of thing, I'd definitely reconsider it. But again, in all my years of doing this (and over 8,000,000 sites using GSAP including most award-winnings sites), I can't remember anyone else asking for that type of functionality. (That doesn't mean it's without merit).

 

Again, I sure appreciate the thought you've put into these posts and your desire to help us make GSAP even better. I'm working hard on GSAP 3.0 and I think you're gonna really like it. :) 

 

With killTweensOf if there is a timeline is use or other tweens then you have to know which tweens your killing otherwise the timeline won't work anymore, this is more of a method to delay the an animation while another is taking place...

 

Lets say I have a scenario where a user is dragging something and I want to create an effect for the drag such that I also have an animation for the drop.

If the drop animation causes something to hide then I must manually keep state such that if the user drags and drops again I show the object and and then hide it again, this gets more complex if I am showing something like a status text or score and I don't want the drag to effect the existing display until the animation is done or I want to truncate that next animation and replace it with a new one which is more up to date....

 

It would sorta of be able to be achieved using a behavior function and the onStart / onComplete but I would need a bit of a framework to accurately wrap it up and I am also assuming that since you know your code better than I do that I would be easier for you to accommodate....

 

The objects to modify are passed directly to the engine and stored in vars of a tween or timeline? I am not seeing where it gets that dirty that it becomes a problem especially for someone who knows the architecture / API.

 

I would also imagine that since the engine offers things like lag smoothing and all of those advanced features then it only makes sense to expose them in a way which the user can also use and take advantage of...

 

E.g. if the engine knows it will skip a bunch of frames then it can also better choose which animations to animation if there were things like a priority and if that priority came from things like usage / requests to the property (which is also mathematically useful, e.g. how far along a tween is, when it will complete, etc).

 

It just seems natural to me to take advantage of a good engine with good features and TweenMax's scheduler seems to be just that.

 

The math you guys already do to determine things like proper ratio and spacing is quite good and I feel that if there is not something already useful for Sequencing besides the OnStart / OnComplete then perhaps it eventually makes sense to create something general for users to:

 

1) save memory / cycles

2) have consistent api / approaches / performance

3) be able to stagger / stack animations according to performance / load

4) take advantage of performance counters related to a tween (e.g. if I find scaling and rotation doesn't work that well I can switch in runtime)

etc.

5) allow users to react to tweens without having the vars, without events you can only have a single function as the entry point for the callbacks unless you dispatch on the element (and there is not always an element to dispatch on... proxies etc)

 

The framework itself is mostly already there and the additions would be similar to adding / changing the features like you do now IMHO...

 

When I get further along with some of my project / examples perhaps I can post the code to highlight how some of this would be useful if you really don't think it's important.

Here are some potential use cases which are slightly different

 

If I move something relatively but I want to cap the movement at a position / bounds I would need to combine onStart / onComplete and onUpdate, take into account the screen size / element position and transforms. Whereas if there was a better format for properties (perhaps similar to how the new CSS Unit stuff is being done...) I could write x: {minValue: 0, maxValue: 10, value: 'center, begin, end, top, bottom', unit: 'default, px, vw, etc'} specifying in the tween that the min / maxValues of x will be as well as what the value should be tweened to and how they should change.

 

I would take then tweens which are effecting value in the way I want and apply them to other objects as well...

 

This allows to make an Effect e.g. like a Reveal or a Scale or a Explosion etc and then use that effect in multiple places and on multiple objects yet change it with respect to performance.

 

I can stack the Scale with the Exploding such that if 2 are occurring then I can have less of a pronounced effect etc.

 

I have a user interaction which causes particles when pressed and a final effect on release, if the user rapidly presses the button the tween will occur in the same way each time and potentially cause different load to the engine. Without the state / performance metrics from the engine I have to keep track for myself if I can or should pronounce the effect as well as when it should take place.

 

E.g. if the effect is on it's way out and I start the tween again or start another tween to start the effect again then the drop animation will never complete unless I manually wait for it and time it such that the user CANNOT drag again while the animation is playing OR I must track the animation and elegantly truncate it to cause the new animation to play.

 

GSAP already has features to smooth eases and timing from one ease to another and this seems like the most natural extension of those features I can imagine.

 

If there are other ways to handle these types of things please let me know and I will give a shot at that methodology.

 

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.

×