Jump to content
GreenSock

cerulean

Constant motion Timeline ?

Recommended Posts

I have a situation where I want to have a number of objects tweening from different starting points towards a common goal. They are moving in the same direction, and should move at the same pace.

I also want to get rid of the object when it reaches its goal, and add a new one (or the same one) at the back of the queue.

 

Picture a line of people moving forward in a queue: they shuffle forward slowly, all at the same speed. We start the queue with a line already formed, that is, we 'open the scene' with the line in place.

 

Is there a way to do this with TimelineMax? I had thought of something like this

_mainTimeline.to(_people,TIME,{z:"+=1000"},"+=1");
But they won't all end up at the same end point. If I substitute a fixed end point (i.e. z:1000) then they won't move at the same pace, since they distance they must cover is different. I also need to figure out a way to keep adding and removing from the queue.

 

I suppose the answer might be to maintain an array of TweenMax's, or simply to do old-school ENTER_FRAME +='s, but I very much like the robustness of TimelineMax

Link to comment
Share on other sites

Hmm I think something like this could work for the speed issue:

var _people:Array = [ person1, person2 ... etc ];
var finalz:Number = 1000;
var multiplier = 0.001;
// I'll assume it should take 1 second to move from z:0 to z:1000
// the difference is 1000 * 0.001 = 1 second

for each (var person:MovieClip in _people) {
  var time:Number = Math.abs(person.z - finalz) * multiplier;
  _mainTimeline.to(person, time, { z:finalz }, "+=1");
  // all persons should move at the same rate, however they will
  // reach z:1000 at different times
}
Link to comment
Share on other sites

Hi,

 

I think you can get the effect you described by offsetting the start time of repeating TweenMax tweens.

 

I mistakenly thought this was the JavaScript forum so I whipped up this demo

See the Pen d34a9a17fdf7a03668d9de69cdfa6475 by GreenSock (@GreenSock) on CodePen

 

is that the effect you are going for?

 

If so I can convert it actionscript for you tomorrow, but the code is virtually the same minus the jQuery stuff.

  • Like 1
Link to comment
Share on other sites

Thanks.  I see the basic concept, that you stagger them with the offset based on total number, but, yes, seeing it in AS3 might help.  I'm a bit unclear what the ()time and scale() calls are for, and how the delayedCall() fits in —  

 

I was able to get the thing to work using a formula that did something like this: calculate for each element already in position the tween time by (finalZ - currentZ)/pixelsPerSecond -- and then simply doing a TweenMax onComplete to generate a new Tween for each object when it had reached the destination.  It worked, but I was unhappy with it, as it both used a TimelineMax and then popped out of it to start generating Tweens — ugh.

 

Yours looks great -- if you could explain it slightly more that would be very helpful

Link to comment
Share on other sites

time() is used to advance the timeline far enough so that you can see all the clips. it takes 1 second for each clip to move all the way to the right. so time(.97) is when the first clip is almost off the screen and all the other tweens are partially advanced.

 

I paused the timeline and slowed it down so you could better see what is happening.

The delayedCall starts the timeline after 1 second so that you have time to see it in its paused state. 

 

Most of those additional commands are totally optional.

 

here is the AS3 code (Box is a movie clip in the library)

 

import com.greensock.*;
import com.greensock.easing.Linear;


var tl = new TimelineLite();
   
for (var i = 0; i<5; i++){
  var mc:Box = new Box();
  mc.x = -20;
  addChild(mc);
  TweenMax.set(mc, {tint:Math.random() * 0xffffff});
  tl.add(TweenMax.to(mc, 1, {x:550, repeat:-1, ease:Linear.easeNone}), i/5)


}
//following code is optional

//advance the timeline so that the first clip is almost off screen.
//pause it
//slow it down (optional)
tl.time(0.97).pause().timeScale(0.2);

//start the timeline after 1 second
TweenLite.delayedCall(1, tl.play);

attached is a cs5 fla

 

 

constantTimeline_CS5.zip

  • Like 1
Link to comment
Share on other sites

Thanks! One question: with a timeline like this, where the attached tweenmax'es go on forever, what is the length of the timeline, so the next thing added knows when to fire?

mainTL.add(carlsTimelineWithRepeatingTweenMaxes); // what's the length?mainTL.add(anotherTimeline); // to determine when this will start?
It works well but as my objects move in z space and also randomly in x space, I have to do some resetting when they get back to the end, that is 'onRepeat' --

 

One thing: I tried setting progress() but I had to set it to something like 0.001 -- is that because the 'duration' is 'infinite'?

 

UPDATE:

 

Yes, having problems when I try to add to main timeline. It just doesn't seem to work there very well -- as if adding it were resetting the already set time()…

Link to comment
Share on other sites

yes, timelines with infinitely repeating tweens do not have finite durations, there literally is no end.

 

Another approach that might suit you instead of repeating the tweens, restart them AND move them to the timeline's current time. This way the timeline at any moment will always have finite duration... its just changing very often.

 

User the fla i attached above and replace the code with this;

 

import com.greensock.*;
import com.greensock.easing.Linear;


var tl = new TimelineLite();
   
for (var i = 0; i<5; i++){
  var mc:Box = new Box();
  mc.x = -20;
  addChild(mc);
  TweenMax.set(mc, {tint:Math.random() * 0xffffff});
  tl.to(mc, 1, {x:550, ease:Linear.easeNone, onComplete:shift, onCompleteParams:["{self}"]}, i/5)


}


//advance the timeline so that the first clip is almost off screen.
//pause it
//slow it down (optional)
tl.time(0.97).pause().timeScale(0.2);




//start the timeline after 1 second
TweenLite.delayedCall(1, tl.play);


//restart the tween at the timeline's current time... literally move the tween to a new position
function shift(tween){
tween.restart().startTime(tl.time());
}
  • Like 1
Link to comment
Share on other sites

Thanks -- I'll try that.  I did get it working fine in the end, but only by keeping it a separate timeline -- that is, if I created the child timeline (as per your original helpful code) and set the time() to be partway through (.5 for me, .97 in your code), when I added it to my main timeline the time got set back to 0.  Is this to be expected? Or is there something going wrong somewhere in my code?

Link to comment
Share on other sites

hi, I'm having a tough time visualizing exactly what happens but it seems expected. When you add the child timeline to the parent, the beginning of the child is placed at whatever insertion point you declare in the parent timeline. you may have to offset the position of the child to account for the fact that its playhead is already in "the future".

Link to comment
Share on other sites

Ah.  So I have to also move the parent's timeline forward some as well?  That is, if the child timeline is 5 seconds into playing and I add the child timeline at 25 seconds into the parent timeline, I would have to move the parent timeline immediately to 30 seconds for the child timeline to be where I set it?   If so, I am confused -- if you have a snippet illustrating, good karma to you!

Link to comment
Share on other sites



import com.greensock.*;
import com.greensock.easing.Linear;


var main:TimelineLite = new TimelineLite();
main.to(b, 2, {rotation:180});
main.add(insertTl);


var tl = new TimelineLite();
   
for (var i = 0; i<5; i++){
  var mc:Box = new Box();
  mc.x = -20;
  addChild(mc);
  TweenMax.set(mc, {tint:Math.random() * 0xffffff});
  tl.to(mc, 1, {x:550, ease:Linear.easeNone, onComplete:shift, onCompleteParams:["{self}"]}, i/5)


}


//advance the timeline so that the first clip is almost off screen.
//pause it
//slow it down (optional)
tl.time(0.97).pause()




//start the timeline after 1 second
//TweenLite.delayedCall(1, tl.play);


//restart the tween at the timeline's current time... literally move the tween to a new position
function shift(tween){
tween.restart().startTime(tl.time());
}


function insertTl(){
trace(tl.time());
main.add(tl, main.time()-tl.time());
tl.time(0.97).play();
}

Link to comment
Share on other sites

Thanks -- one question -- what is 'b' in the second line? And are you adding this tween to simply give the timeline some space to add the second one?

 

Seems to work well when I applied to my own code. Thanks for giving me an insight into a new way to work with timelines. I've been kind of assembling them beforehand and then trying to put together different ones in larger structures, like lego, but this approach is very useful, where you operate through a callback and can reference the current state of running timlines. Thanks.

 

One thing -- although it works well, I'm getting a glitch where another timeline already added to the main timeline, the one just preceding the one I'm adding, gets its last bit replayed. When I add a timeline at a point before the current end of the timeline, and have it already set forward in time (as per your example), can this in any way affect other timelines already on the main timeline? I shouldn't think so, but this method of adding already-time()'d timelines at an 'earlier' point is new to me.

Link to comment
Share on other sites

b, is just the target of a tween used only to give the main timeline something other than the child timeline.

 

I just added another timeline to that demo and its timing was not affected by adding the constant timeline. So, no, I am not sure what you are referring to in the last part of the question.

Link to comment
Share on other sites

Thanks.  I'm sure any 'glitches' are at my end.  I was just wondering if adding a timeline at, say, "+-8" and setting it to "time(8)" would cause any sideeffects to any sibling timelines, but I assume that's totally silly…

 

My one other question would be this: if I had a child timeline with a negative time offset, as we've been doing, does the parent timeline have to have sufficient duration() to "accommodate" it?

parentTimeline = new TimelineMax;


childTimeline = new createMyChildTimeline; // duration() == 20, for example.

childTimeline.time(10);

parentTimeline.add(childTimeline,"-=10"); // but parentTimeline.duration() == 0 at this point

Or would the parent need to have a duration() of at least 10 to accommodate the "-" time setting in the add?

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