Jump to content
GreenSock

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

Reusing animation with different values

Go to solution Solved by OSUblake,

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

Lets say i have two points for storeing start and end position.

var planeStart = new Point();
var planeEnd = new Point();
planeStart.x = 0;
planeStart.y = 0;
planeEnd.x = 1000;
planeEnd.y = 1000;

then i make my animation.

var animation = new TimelineLite()
.fromTo(plane.position, 30, { x: planeStart.x, y: planeStart.y }, { x: planeEnd.x, y: planeEnd.y, });

When the animation is done, i cache it (reuse everything to avoid memory overhead).

 

 

Problem:

Now i want to start the animation again, but with new planeStart and planeEnd positions.

 

Changing the reference objects before playing the animation doesn't work 

planeStart.x = 0;
planeStart.y = 500;
planeEnd.x = 1000;
planeEnd.y = 500;

Repeating the instantiation with updated reference objects doesn't work 

animation.fromTo(plane.position, 30, { x: planeStart.x, y: planeStart.y }, { x: planeEnd.x, y: planeEnd.y, });

Creating a new timeline with updated references DOES work 

animation = new TimelineLite()

.fromTo(plane.position, 30, { x: planeStart.x, y: planeStart.y }, { x: planeEnd.x, y: planeEnd.y, });

But that kinda negates the purpos of caching in the first place. :(

 

 

Edit:

I need to use timelines, because it's a multiplayer game, and when people join, all running animations will jump to their current state.

i have tried .invalidate() and .kill() without success.

Link to comment
Share on other sites

From what I know of GSAP and JavaScript, you will not be able to update your values unless you create a new timeline simply because of the nature of the code.

 

Please note this is how I understand GSAP works - Carl or Jack will be able to confirm it at some point.

 

Once you create the timeline, it stores the values you give them and keeps it for future use. Unless you run the instatiation again, those values will remain on that line of code. If you were using TweenLite (or Max) you would be able to kill them because they are created as you call them.

 

One way I would imagine you could acomplish that and still use TimelineLite would be to have a onStart call, where you reference a function that checks the values to be used. Another option would be to have an onUpdate call doing the same thing, again, haven't tried updating values on timelines yet.

 

Saying that, I have just tried to acomplish it myself with the above methods and failed.

 

My guess is that you would have to consider using TweenLite or re-running the instatiation of the timeline in order to achieve the desired effect.

 

To be honest, if you are updating the animation on the fly, it kind of defeats the point of caching it, no?

  • Like 1
Link to comment
Share on other sites

Thank you for answering and trying things out :)

 

 

To be honest, if you are updating the animation on the fly, it kind of defeats the point of caching it, no?

 

Not really, if I'm able to reuse the TimelineLite object (changeing the values) and avoid casting "new" I will be fine.

 

Everytime you use "new" you abandon an object, that becomes garbage and at some point have the get cleaned up by the gc.

 

(Its not only the animation I'm caching, its also the sprites and sounds used by the animation. so I'm caching a wrapper object that contains this animation)

 

This wouldn't be a problem if it wasn't a game.

But because its a game, and over time will play thousands of different animations (never ending), it will unfortunatly start filling up the GC, and it might cause lag's and poor performance (especially on mobile devices).

 

Lets see if someone can shed some light on this, I really hope its possible!

Link to comment
Share on other sites

Hi bQvle,

 

If you just want to avoid doing another new TimelineLite(), I would recommend that you call 

animation.clear() //remove all child tweens, timelines, callbacks from timeline

 and then add a new tween with the new values

 

http://greensock.com/docs/#/HTML5/GSAP/TimelineLite/clear/

  • Like 2
Link to comment
Share on other sites

Hi bQvle,

 

If you just want to avoid doing another new TimelineLite(), I would recommend that you call 

animation.clear() //remove all child tweens, timelines, callbacks from timeline

 and then add a new tween with the new values

 

http://greensock.com/docs/#/HTML5/GSAP/TimelineLite/clear/

 

Hi Carl, 

 

Sorry for being paranoid, but wouln't that just leave the "tween" objects to the GC, rather then the whole timeline object?

 

 

Also, while I have your attention.  :mrgreen:

 

Is there a build in method for stopping the global ticker, and calling the tick event manually? I just want to make sure its perfectly in sync with my renderer.

so i could call the TweenLite/Max "update/animate/tick" function before i do my renderer.

 

I dont know if its my OCD, but i feel like there is some "sync" jitter in the animations. and that would happend if the rendere sometimes gets called before the tween has happend.

Link to comment
Share on other sites

I think I found a solution that I'll go with.

 

If I put every animated object in a gameobject container, I can just rotate/move the that gameobject, then the GameEngine matrix will handle positioning and angle of the animation. and the timeline itself can be with "static" values.

 

 

About the Ticker I'm still curious. But i guess it more complicated then so. (I assume you run every timeline-animation on its own ticker, to allow pause/resume/rewind etc.)

 

If i could just make sure that my gameloop/ticker is the last to get executed. (to assure that all animation has happend, before rendering the canvas)

Link to comment
Share on other sites

Thanks Dipscom,

 

Yes i could actually use that Ticker for my game.. hmm.

 //add listener that requests an event object parameter, binds scope to the current scope (this), and sets priority to 1 so that it is called before any other listeners that had a priority lower than 1...
 TweenLite.ticker.addEventListener("tick", myFunction, this, true, -1);

Would priority -1 make sure that the tweens has already animated before "myFunction" is called?

Link to comment
Share on other sites

I take it you're using PIXI from your other thread, which means you can use the updateTo method as long as it is not a plugin value.

 

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

 

As for the ticker, I don't think that matters since it is called after the engine updates.

 

 

Yep I'm using PIXI,

but what you say would require me to iterate through all my tweens/timelines and call the updateTo, correct?

 

Currently my gameloop is just running on a requestAnimationFrame, so I don't see why i shouldn't just use the built in TweenMax/TweenLite ticker. (if someone could confirm that priority "-1" would put the callback at the end of the stack, to assure all the tweens have been processed before I do the renderer)

Link to comment
Share on other sites

No, you only update what you want. You can even update the values while it's tweening.

 

I just said it doesn't matter for the tick. The priority is for the callbacks you add.

Link to comment
Share on other sites

No, you only update what you want. You can even update the values while it's tweening.

 

But if using updateTo, the smartest thing would be not starting the tween. and then call updateTo from somewhere in my gameloop before the renderer right?

 

 

I just said it doesn't matter for the tick. The priority is for the callbacks you add.

 

Yep, but you would think that the currently running timelines and tweens also exsist in that callback stack? and by adding my gameloop/animate with lower priority would make sure tweens happend before renderer.

Link to comment
Share on other sites

So for the tick, I would have it do two calls - one to update any values, and then one to call the renderer. That will make sure it happens last.

 

About the updateTo, it depends how you want your tweens to look and where you want them to start from. I made a little demo that shows the updateTo being applied while the stars are tweening. The update button will change one of the star's x value to 275. Notice how once you update a star, it will only go between the point at which you updated it, and 275.

 

See the Pen 03e54aae77aacc6e9fd889392674dea6 by osublake (@osublake) on CodePen

Link to comment
Share on other sites

Ah, thank you for the clerification and example!

 

I misunderstod updateTo, I thought it was for manually stepping a tween/timeline. (Thats what you get for mixing questions) :)

So updateTo will allow me to change the values in a ".to()", but it will only work on tweens/TweenMax and not timelines.

(which answers my enitial question, except I'm using a timeline)

 

 

About the tick's I think you misunderstood me to, i wasn't concerned about updating the values between ticks.

 

But rather make sure that all the "tween ticks" happends before the "render tick" just to avoid visual jitter/tearing because with two "tickers/requestAnimationFrame" i have no idea what is called when. But if i use the TweenLite.ticker, and set priority to -1, hopefully all the tweens will update before the render tick. I assume that all Tweens and Timelines exsist in that ticker with priority 0.

Link to comment
Share on other sites

  • Solution

Correct. A timeline adds TweenLite instances, which don't have the updateTo method. However, you can add a TweenMax instance by using .add(). And it doesn't have to be in a .to() tween, that's just what I used. I made another version of that demo using a timeline. Notice how I'm not even keeping track of the tweens. I used the .getTweensOf() method to get the tween I want.

 

Once again, setting priority to -1 doesn't matter. Your tweens are going to be updated before it calls your callback, which would be your renderer. Look at the console which shows the tick count. The tween is updated first.

 

See the Pen 5f6c34d42995223f0025eda5b3637ae6?editors=001 by osublake (@osublake) on CodePen

  • Like 3
Link to comment
Share on other sites

Blake, thanks for the great support and for creating that demo that shows the order of execution of the tick and the custom callback.

 

bqvle, 

 

I can't see you having any problem tying your render calls to the ticker. FWIW you can not manually trigger a tick.

It's been a busy day around here and Jack usually handles the more technical questions. If you have any unanswered questions or need more clarification, please post them below and we'll do our best to get you answers tomorrow.

Link to comment
Share on other sites

Blake,

I get it! :)  +1 on the great support and examples! really helpful!

 

Carl,

Thanks, but I think I'm set for now, blake addressed both of my questions very well.

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