Jump to content
Search Community

Changing the time of a tween?

maskedbacon test
Moderator Tag

Recommended Posts

Hi guys,

 

Is it possible to change the duration of a tween mid-tween?

 

I'm not seeing much in the documentation or around the interwebs about this (but maybe I'm blind). It would be an incredible feature for game development and the like so we could use fancy eases with dynamic movement.

 

Thanks!

David

Link to comment
Share on other sites

using TimelineMax you can adjust playback rate / timeScale so you can speed up or slow down a single tween or an entire sequence of tweens.

http://www.greensock.com/timelinemax/ view the interactive example and adjust the timeScale property.

 

I believe that once a TweenLite/Max instance is created its duration and all properties are set for the lifespan of the Tween. the dynamicProps plugin will allow the end values of the properties to change mid-tween. see the plugin explorer.

 

using TweenLite or TweenMax you can dynamically set a duration upon the tweens creation by calculating the distance needed to travel and the desired speed of movement.

 

If you have a specific scenario you need a solution for perhaps someone can provide more detailed help.

 

I think you will find that the many features of greensock can enhance anything you would do with normal ActionScript.

Link to comment
Share on other sites

Yep, Carl is right on with one minor exception: you can change the duration of a tween whenever you want, but be careful about in-progress tweens. For example, if a 2-second tween is halfway done and it's tweening a value from 0 to 100 linearly, that means the value would currently be 50. If you change the duration of the tween to 4 at that point, that means that the current time (1-second into the tween) is only 1/4th of the way done so the 0-100 tween would suddenly render at 25. You'd see it jerk from 50 to 25. Maybe that's what you want, but more often than not people prefer smooth transitions while tweening.

 

Like Carl said, dynamicProps makes it pretty simple to make things smoothly go to new destination values whenever you want even if the tween is in progress. TweenMax's updateTo() is somewhat similar to that as well. But neither affect the duration of the tween.

 

In summary, yes, you can change a tween's duration whenever you want but keep the logic in mind regarding how that would affect in-progress tweens.

Link to comment
Share on other sites

Hey, thanks for replying guys.

 

I was hoping that changing the duration would have some algorithm for compensating for the time difference... so, say, you were 50% of the way through a 2 second tween and changed it to 4 seconds, it would then take 4/2 = 2 seconds to complete the last 50%. updateTo already has the option to reset the time... I assume this doesn't reset the entire tween, so it's effectively changing the last, say, 50% of the tween to go at a different rate. It seems natural that you'd be able to change, the duration. No?

 

The problem with making new tweens instead of changing the duration of them is that it also resets the easing. So you get visual stutters instead of just sped up smooth completions. You could imagine many situations where you have a slow moving object that you'd just like to speed up depending on an action, and this would be awesome for that.

 

And by the way, if that's you Jack, I love your platform! I've been using it for years and I've converted many other developers to see the light :)

Link to comment
Share on other sites

If you change the duration, there are multiple ways that the tween could be adjusted. It could do the straightforward thing and keep its startTime where it is and just extend itself longer (what I described earlier) or it could alter its startTime or timeScale to accommodate the duration change while keeping the playhead locked in the same position - this would avoid the jump in values I described earlier but in some ways it's counter-intuitive ("why does my tween's startTime move when I alter the duration?"). See the challenge? But I already built timeScale to function that way (automatically adjusting the startTime to ensure a smooth transition when necessary) so the more I thought about it, the more sense it seemed to make to have duration changes work in a similar manner.

 

So I just posted version 11.5 of TweenLite/Max which now incorporate that functionality. You can alter the duration on the fly and it'll smoothly make the transition for you, altering the startTime accordingly if the tween is in-progress (active).

 

Happy? :)

 

Check it out when you have a chance and let me know if it works as you had hoped. http://www.greensock.com

Link to comment
Share on other sites

I didn't create a new method or property or anything - what exactly were you looking for in the docs?

 

Here's a simple example:

 

var tween:TweenMax = new TweenMax(mc, 4, {x:500});

TweenLite.delayedCall(2, changeDuration); //when the tween is halfway done, we'll change the duration to 16

function changeDuration():void {
   tween.duration = 16;
}

 

Make sense? Was there something you thought needed to be added to the ASDocs?

Link to comment
Share on other sites

I never knew duration was read/write :(

Yep, I tried to make stuff pretty simple like that. timeScale is a getter/setter too which makes it easy to tween. Yeah, you can literally tween another tween's timeScale to gradually speed it up or slow it down.

 

Oh, and another tip: if you alter the duration of a TimelineLite/Max, it will actually alter its timeScale instead so that all of the tweens inside of it play at the speed appropriate to fit within that duration you define (although it doesn't keep adjusting itself later if you add/remove tweens). For example, sequence 10 5-second tweens into a TimelineLite (50 seconds worth) and then set its duration to 5 and the TimelineLite's timeScale will become 0.1 so that it effectively causes the duration to behave as though it is 5. Kinda fun. :)

Link to comment
Share on other sites

  • 1 year later...

Hello, I know this thread has been dead for 2 years but I think that all of what has been said on it is relevant for my question.

 

I have a Timeline and I have dynamically changed the duration of a TweenMax in it, this works great for the tween, but the Timeline does not seem to adjust to the new duration. I even tried using the cacheIsDirty with no success...

 

Anyone can shed light on this?

 

Below an example of my problem:

 

import com.greensock.*;

var tl:TimelineMax = new TimelineMax;

tl.append(TweenMax.to(mc1,10,{onInit:changeDuration,x:mc2.x-mc2.width})); //The initial duration of this tween is 10, but is modified by change duration to 1.
tl.append(TweenMax.to(mc2,1,{y:mc2.y-mc2.height})); //I expect this tween to start as soon as mc1 has completed its new duration but it takes the older 10 second duration for it to start.

function changeDuration(){
var tw:TweenMax=tl.getActive(false,true,false)[0];

tw.duration=1
tw.cacheIsDirty=true;//I tried setting the cacheIsDirty to true, but it does not seem to do anything.
tl.cacheIsDirty=true;
}

Link to comment
Share on other sites

What you are experiencing is the intended behavior. Timelines do not automatically shift the timing of the children around.

 

when you appended your second tween:

 

tl.append(TweenMax.to(mc2,1,{y:mc2.y-mc2.height}));

 

it was given a startTime of 10 because that was the current duration of the timeline. That second tween will always have a startTime of 10 regardless of whether or not you later change the duration of the first tween to 1 second or 100 seconds long.

 

Just to be clear append simply adds a tween to the end of the timeline as the timeline is being created, it doesn't constantly monitor or enforce that tweens always play one after the other.

 

The good news is, after you change the duration of the first tween you can use shiftChildren to move the other tweens around:

 

give it a try:

 

http://www.greensock.com/as/docs/tween/ ... tChildren()

Link to comment
Share on other sites

Once again you are my saviour Carl! Thankyou! I could get it to work with the shiftChildren(), but to be honest I am not completely sure how :?

Could you please see my code and tell me how I am supposed to calculate the ignoreBeforeTime parameter?

 

import com.greensock.*;

var tl:TimelineMax = new TimelineMax;

tl.append(TweenMax.to(mc2,5,{y:String(-mc2.height)}));
tl.append(TweenMax.to(mc1,1000,{onInit:changeDuration,x:mc2.x-mc2.width})); 
tl.append(TweenMax.to(mc2,2,{y:String(-mc2.height)}));
tl.append(TweenMax.to(mc2,8,{y:String(mc2.height)}));
tl.append(TweenMax.to(mc1,1000,{onInit:changeDuration,x:String(-mc2.width),tint:0xff0000}));
tl.append(TweenMax.to(mc2,2,{y:String(-mc2.height),tint:0xff0000}));

function changeDuration(){
  var tw:TweenMax=tl.getActive(false,true,false)[0]; 
  var outdatedDuration:Number=tw.duration;
  var updatedDuration:Number=0.1;
  var ignore:Number =50// I can't figure this var out, I tried (tl.duration-outdatedDuration+updatedDuration) but it does not work for very high durations,oddly 50 does...

  tw.duration=updatedDuration;

  tl.shiftChildren(updatedDuration-outdatedDuration,false,ignore);
}

Link to comment
Share on other sites

i simplified the tweens to make my testing easier and more clear. i have 2 mcs stacked vertically on the left hand side of the stage.

 

import com.greensock.*;

var tl:TimelineMax = new TimelineMax;

tl.append(TweenMax.to(mc2,1,{x:100}));
tl.append(TweenMax.to(mc1,1000,{onInit:changeDuration, x:100})); 
tl.append(TweenMax.to(mc2,1,{x:0}));
tl.append(TweenMax.to(mc1,1000,{onInit:changeDuration, x:0}));
tl.append(TweenMax.to(mc2,1,{x:100}));


function changeDuration(){
  var tw:TweenMax=tl.getActive(false,true,false)[0]; 
  var outdatedDuration:Number=tw.duration;
  var updatedDuration:Number=1;
  var ignore:Number = tl.currentTime //don't shift children tweens that existed before this function runs

  tw.duration=updatedDuration;

  tl.shiftChildren(updatedDuration-outdatedDuration,false, tl.currentTime);
}

 

you will notice that the tweens with duration of 1000 get changed to 1 and all tweens play in immediate succession.

I am using the timeline's currentTime property to avoid shifting tweens prior to the current position of the playhead when the function runs.

it seems to work.

 

c

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