Jump to content
Search Community

Additive animation

iliketoplay test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi, I have been missing a feature for a while now and was wondering if it's something you would consider adding in future releases?

 

The concept is to update currently running tweens without a sudden stop/start - instead you would relate to the previous animation's position, speed and velocity. It's called additive animation. Here's also a simple demo showing it: http://alexkuz.github.io/additive-animation/

 

I think we could get this effect with the Physics plugin, but that would be rather difficult. A much better approach would be to enable this as a property in the "killTweensOf" method or to create a new "updateTweenTo" method. Or maybe just having a property in the "to" method like "additive:true".

 

Maybe the concept of timing should also be considered with the above feature. Like say you are moving a box 200px in 1 second. If you cancel halfway in and move it back, this would also take 1 second - but you're only moving 100px. So having a "relativeTimeTo" method is another idea :-) This might also work great with additive animations, because they can adjust the time then.

 

I would LOVE this feature :-)

See the Pen wKdwab by iltp (@iltp) on CodePen

  • Like 1
Link to comment
Share on other sites

Hello Michael Vestergaard, and Welcome to the GreenSock Forum!

 

Are you talking about using relative values in GSAP, if so GSAP supports using relative values by using += or -=

 

See the Pen yYbBGb by jonathan (@jonathan) on CodePen

 

If this is not what you were referring to, than could please clarify some more, since i might be misunderstanding what you mean!

 

Resource:

TweenMax Docs under Notes / Tips: http://greensock.com/docs/#/HTML5/GSAP/TweenMax/

 

Thank You :)

  • Like 1
Link to comment
Share on other sites

Hi Jonathan

No, the relative values feature is nice, but not what I'm looking for. I want specific targets, not just += 100. Also that approach cancels and starts a new tween, with no blending of the two. If you look at the link http://alexkuz.github.io/additive-animation/ and click "Jump!" fast, you can see how the animation updates smoothly - this is additive animation.

Link to comment
Share on other sites

Hi Michael Vestergaard  :)

 

if i understood correctly , you just need BezierPlugin ;) , something like this : 

See the Pen 4552046de9bb4cda9509e51ec874bbc8 by MAW (@MAW) on CodePen

That's actually a really nice idea. Not super easy to use though, but it does the job :-) However you need to manually do this for all tweening properties - it would be nice to have this automated.

Link to comment
Share on other sites

Have you tried all of the overwrite property values?  .. auto is the default

 

Here are a list of all the GSAP overwrite  property values:

 

overwrite : String (or integer) - Controls how (and if) other tweens of the same target are overwritten. There are several modes to choose from, but "auto" is the default (although you can change the default mode using theTweenLite.defaultOverwrite property):
  • "none" (0) (or false) - no overwriting will occur.
     
  • "all" (1) (or true) - immediately overwrites all existing tweens of the same target even if they haven't started yet or don't have conflicting properties.
     
  • "auto" (2) - when the tween renders for the first time, it will analyze tweens of the same target that are currently active/running and only overwrite individual tweening properties that overlap/conflict. Tweens that haven't begun yet are ignored. For example, if another active tween is found that is tweening 3 properties, only 1 of which it shares in common with the new tween, the other 2 properties will be left alone. Only the conflicting property gets overwritten/killed. This is the default mode and typically the most intuitive for developers.
     
  • "concurrent" (3) - when the tween renders for the first time, it kills only the active (in-progress) tweens of the same target regardless of whether or not they contain conflicting properties. Like a mix of "all" and "auto". Good for situations where you only want one tween controling the target at a time.
     
  • "allOnStart" (4) - Identical to "all" but waits to run the overwrite logic until the tween begins (after any delay). Kills tweens of the same target even if they don't contain conflicting properties or haven't started yet.
     
  • "preexisting" (5) - when the tween renders for the first time, it kills only the tweens of the same target that existed BEFORE this tween was created regardless of their scheduled start times. So, for example, if you create a tween with a delay of 10 and then a tween with a delay of 1 and then a tween with a delay of 2 (all of the same target), the 2nd tween would overwrite the first but not the second even though scheduling might seem to dictate otherwise. "preexisting" only cares about the order in which the instances were actually created. This can be useful when the order in which your code runs plays a critical role.
Resources:

TweenMax Docs: http://greensock.com/docs/#/HTML5/GSAP/TweenMax/

defaultOverwrite global setting: http://greensock.com/docs/#/HTML5/GSAP/TweenLite/defaultOverwrite/

 

:)

  • Like 2
Link to comment
Share on other sites

Have you tried all of the overwrite property values?  .. auto is the default

 

Here are a list of all the GSAP overwrite  property values:

 

overwrite : String (or integer) - Controls how (and if) other tweens of the same target are overwritten. There are several modes to choose from, but "auto" is the default (although you can change the default mode using theTweenLite.defaultOverwrite property):
  • "none" (0) (or false) - no overwriting will occur.

     

  • "all" (1) (or true) - immediately overwrites all existing tweens of the same target even if they haven't started yet or don't have conflicting properties.

     

  • "auto" (2) - when the tween renders for the first time, it will analyze tweens of the same target that are currently active/running and only overwrite individual tweening properties that overlap/conflict. Tweens that haven't begun yet are ignored. For example, if another active tween is found that is tweening 3 properties, only 1 of which it shares in common with the new tween, the other 2 properties will be left alone. Only the conflicting property gets overwritten/killed. This is the default mode and typically the most intuitive for developers.

     

  • "concurrent" (3) - when the tween renders for the first time, it kills only the active (in-progress) tweens of the same target regardless of whether or not they contain conflicting properties. Like a mix of "all" and "auto". Good for situations where you only want one tween controling the target at a time.

     

  • "allOnStart" (4) - Identical to "all" but waits to run the overwrite logic until the tween begins (after any delay). Kills tweens of the same target even if they don't contain conflicting properties or haven't started yet.

     

  • "preexisting" (5) - when the tween renders for the first time, it kills only the tweens of the same target that existed BEFORE this tween was created regardless of their scheduled start times. So, for example, if you create a tween with a delay of 10 and then a tween with a delay of 1 and then a tween with a delay of 2 (all of the same target), the 2nd tween would overwrite the first but not the second even though scheduling might seem to dictate otherwise. "preexisting" only cares about the order in which the instances were actually created. This can be useful when the order in which your code runs plays a critical role.
Resources:

TweenMax Docs: http://greensock.com/docs/#/HTML5/GSAP/TweenMax/

defaultOverwrite global setting: http://greensock.com/docs/#/HTML5/GSAP/TweenLite/defaultOverwrite/

 

:)

Yes, these cannot blend any animations, they simply stop current (or future) tweens.

Link to comment
Share on other sites

That's actually a really nice idea. Not super easy to use though, but it does the job :-) However you need to manually do this for all tweening properties - it would be nice to have this automated.

Also the Bezier approach has small problem in my opinion:

- If you tween a value from 0-500, then halfway in tween it to 300 instead - the object will move too far and go back a little. You can try this in your demo too. The ideal situation would be to slow down instead - I think :-)

 

I made a small demo here: 

See the Pen yYbNbJ by iltp (@iltp) on CodePen

I'm not sure what's the best and most realistic looking effect would be. Slowing down would maybe be too drastic - but on the other hand this bezier seems too "effective".

Link to comment
Share on other sites

pls check BezierPlugin api /options , this's just a start for you , you can change values array and make your desired act  :)

 

http://greensock.com/docs/#/HTML5/Plugins/BezierPlugin/

Thanks. I might get close to something looking good with that :-)

But ultimately I'm requesting this to be built into GSAP, just like delays, staggers, timeline etc. I think it's an important feature and many other platforms are integrating it (like some of the React animation tools).

Link to comment
Share on other sites

Just a quick observation Michael, if you include TweenMax.. then you don't need to include the CSSPlugin or the EasePack since TweenMax already has those 2 Plugins, and many more included for your convenience.

 

TweenMax saves you the step of loading the common ones like CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin as well as EasePack, TimelineLite, and TimelineMax.

 

Hopefully we can address your concern with some other eyes on this from Jack and Carl ;)

Link to comment
Share on other sites

A more advanced version that solves the Bezier on update. In both my examples I'm resetting the tween time so it doesn't jump all over the screen, but I don't think you would normally do that for an additive animation.
 

See the Pen YyVWaX by osublake (@osublake) on CodePen


 
I'm still a little confused by this image. How are the 2 anchor points for the curve chosen. Is it the x-intercepts of the start of the new animation and the end of the old animation, or is there some formula used to calculate where the curve starts and end? If I knew that I could make it smoother.
 
VBPZZkH.png?1
 

Link to comment
Share on other sites

A more advanced version that solves the Bezier on update. In both my examples I'm resetting the tween time so it doesn't jump all over the screen, but I don't think you would normally do that for an additive animation.

 

See the Pen YyVWaX by osublake (@osublake) on CodePen

 

I'm still a little confused by this image. How are the 2 anchor points for the curve chosen. Is it the x-intercepts of the start of the new animation and the end of the old animation, or is there some formula used to calculate where the curve starts and end? If I knew that I could make it smoother.

 

VBPZZkH.png?1

 

Great work :-) Thanks for sharing this. Seems like you're on to something with this solution. However, have you notices the easing - doesn't look like an easeOut?

Also, I'm aware of various ways we can achieve this, you can also adjust the tween time depending on the distance to the target to have more realistic effects. But ultimately I'm requesting this as a built-in feature.

Link to comment
Share on other sites

Just a quick observation Michael, if you include TweenMax.. then you don't need to include the CSSPlugin or the EasePack since TweenMax already has those 2 Plugins, and many more included for your convenience.

 

TweenMax saves you the step of loading the common ones like CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin as well as EasePack, TimelineLite, and TimelineMax.

 

Hopefully we can address your concern with some other eyes on this from Jack and Carl ;)

Thanks, I know (been using GSAP for years) the code was real quick and dirty. But thank for the heads up :-)

Link to comment
Share on other sites

I think for the ease to look correct it would also have to be calculated during the update using something like this...

 

http://greensock.com/forums/topic/12533-directly-accessing-using-ease-functions/?p=52184

 

But then again, I'm still not sure how those points are calculated and if the values would should be treated as an ease or a normal path interpolation. One very important lesson I learned while making this

See the Pen OyPGEo by osublake (@osublake) on CodePen

is that Bezier easing is not calculated the same way as Bezier path. I'm curious as to how Apple solves this problem, but I can't find the video from the WWDC that explains how this works.

Link to comment
Share on other sites

Cool! That's the video.

 

The part about additive animations starts at around 25min. I must say that I was completely off the mark about how this work. It's actually more complicated than I was expecting and has nothing to do with Beziers or easing. From what I gather, an additve animation is a fromTo tween using relative values. When a new animation is added the old animation does not get overwritten. Instead, both animations continue to run in parallel with each other, and the difference between the two animations is calculated and that value is used.

 

So to get this to work like Apple does it, you would need to tween generic objects and then have an update method calculate the difference and apply it to your target. I'll have to look into this some more, but here's a slide that kind of shows what is going on. So the presentation row is the value that you would set on your target, which you can see is the difference between the 2 animations relative to the model's value.

 

2jki7kY.png

 

 

  • Like 3
Link to comment
Share on other sites

Jack, I would have to agree with Michael that this would be an awesome feature. Now that I've had a chance to play with it, I definitely think this could be another GSAP game-changer come v.1.19.0.

 

It really wasn't that hard to create. I just did modeled it after that slide. However, it was really confusing to understand at first because the values are relative. So if you want to move an object from x: 0 to x: 500, you would set it's starting position at x:-500 because the end position is 0. Yeah, confusing. Not really sure how a relative value would work for something like color.

 

I'm also not sure how to handle to easing. Applying easing to each individual tween won't work because it causes massive jumps. So now I have to figure out what is the starting value of the tween. Do I use the first tween's value, the last tween's value, is the value still relative... I don't know! I tried a lot of variations, but it still caused jumps or the easing didn't change affect the values. I'll try to figure that one out later.

 

The code is not super complicated. The only unusual thing is that I used a linked list as a data structure for the tweens, but you could use an array or a plain object. I just like using the linked list because it's faster and easier to manage than an array as it doesn't actually store anything.

 

 

See the Pen PPmJpL?editors=1010 by osublake (@osublake) on CodePen

 

  • Like 8
Link to comment
Share on other sites

Well I thought my demo was going to be picked up by Twitter or CodePen, but apparently nobody really cares for a demo where you can move a box around. Or maybe it's just not apparent that something awesome is actually taking place. I still stand by my statement about this being a game changer. There is no real JavaScript based solution for doing this kind of stuff. Do a Google search for additive animation or animation blending, and the only thing it will bring up is stuff for Unity, Unreal, or something from AutoDesk.

 

I just made a demo that makes it very apparent that something very different is going on here. The only thing it does is create an x and y tween every 100ms for each little ghost orb. The x and y value is just the x and y coordinates of the mouse. That's it. There are are no Bezier curves, rotations, angles, transform origins, crazy matrix calculations... nothing. Having said that, you are probably imagining a bunch of jagged or rough animations. 

 

Check it out. Play with my little ghostly friends. Each ghost is made up of 500 different particles, and it's just blending each one of them oh so perfectly. Move your mouse around to get them to follow you. They give up when your mouse leaves the screen.

 

See the Pen GpmPGy?editors=0010 by osublake (@osublake) on CodePen

 

  • Like 7
Link to comment
Share on other sites

Well I thought my demo was going to be picked up by Twitter or CodePen, but apparently nobody really cares for a demo where you can move a box around. Or maybe it's just not apparent that something awesome is actually taking place. I still stand by my statement about this being a game changer. There is no real JavaScript based solution for doing this kind of stuff. Do a Google search for additive animation or animation blending, and the only thing it will bring up is stuff for Unity, Unreal, or something from AutoDesk.

 

I just made a demo that makes it very apparent that something very different is going on here. The only thing it does is create an x and y tween every 100ms for each little ghost orb. The x and y value is just the x and y coordinates of the mouse. That's it. There are are no Bezier curves, rotations, angles, transform origins, crazy matrix calculations... nothing. Having said that, you are probably imaging a bunch of jagged or rough animations. 

 

Check it out. Play with my little ghostly friends. Each ghost is made up of 500 different particles, and it's just blending each one of them oh so perfectly. Move your mouse around to get them to follow you. They give up when your mouse leaves the screen.

 

See the Pen GpmPGy by osublake (@osublake) on CodePen

Fantastic amount of work you put into this - thanks a lot. And I agree it's a game changer - I think many others will too when they start understanding the concept.

Great demo :-)

 

In my opinion (and I have been using GSAP since the Flash days) this feature is just as important as staggers, timeline and textplugin. So fingers crossed that it will make it into a future release :-)

  • Like 2
Link to comment
Share on other sites

Thanks!

 

It's kind of funny how I had a hard time understanding what you were talking about when you started this topic. It seemed like one of the overwrite property values that Jonathan posted would take care of your problem, but then I saw a YouTube video on this and it hit me like a ton of bricks. It makes perfect sense now as this is how motion works in the real world. You don't switch from one direction to the next in a flash. There is going to be some overlap between two opposing forces. And this overlap also has a nice side effect because it creates a natural ease between the two.

 

This is definitely on the top of my list of GSAP features I'd like to see in the future. I don't see any reason why it would be hard to incorporate into GSAP. If you look at my previous demo, there's really not a lot of code that is used in the actual calculation of the animation. And I'm sure there's a better a way of calculating the values than how Apple did it. Trying to understand how to work with negative reversed values was insanely confusing. It was like all of sudden I developed the worst case of dyslexia.

 

Try to spread to the word some more. You really helped me out. I know to the untrained eye the differences might be subtle, so hopefully my new demo will make it more apparent.  

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