damienmajer

Change tween duration on the fly

Recommended Posts

Hey,

 

When animating an unknown number of elements like so:

var timeline = new TimelineMax({repeat:-1}),
items = document.querySelectorAll('.item'),
startDuration = 20;


for(var i = 0; i < items.length; i++) {
  var myDelay = (i * 0.5);  
  animate(items[i], myDelay);  
}


function animate(item, delay) {
  var a = TweenMax.to(item, startDuration, { rotationZ:'360', ease:Linear.easeNone, repeat:-1 });
  timeline.add(a, delay);
}
 
What is the best way to modify the duration/speed of an individual tween?
 
Thanks

Share this post


Link to post
Share on other sites

Hi damienmajer :)

 

Welcome to the GreenSock forum.

 

I'm assuming you mean as part of the tween creation function so all the tweens aren't the same duration? If that's the case, I'd probably use a random number generator and use a min/max value:

function randomNumber(min, max) {
  return Math.random() * (max - min) + min;
}

You could also create an array of durations if you want tight control and randomly pick one of those for each tween. 

 

Does that help?

 

Happy tweening.

:)

Share this post


Link to post
Share on other sites

Hi,

 

Thanks for your reply.

 

What I meant was, once all the element are animating, how can I modify the duration of one of the elements? I.e speed up or slow down one item only.

Share this post


Link to post
Share on other sites

Ha! I wondered if that's what you meant, but I wasn't quite sure. I had a 50/50 shot and I guessed wrong. :)

 

If you want to change one/any of those tweens you created, you can certainly do that. I think just adjusting the timeScale() would be the easiest way. I dropped your code into a quick demo with some boxes to show you how to do it:

 

http://codepen.io/PointC/pen/oZoBpj/

 

Does that help?

 

Happy tweening.

:)

  • Like 4

Share this post


Link to post
Share on other sites

And in your example could I instead select box 3 via a class or data attribute?

Share this post


Link to post
Share on other sites

Great demo, Craig!

 

And in your example could I instead select box 3 via a class or data attribute? 

 

 

Take a look at TweenMax.getTweensOf()  if you pass in a selector like ".box3" it will return an array of all the tweens that use it as a target.

You could potentially need to loop through that array and change the timeScale() or duration() of multiple tweens.

  • Like 3

Share this post


Link to post
Share on other sites

In my demo I used item.anim as a name for the tweens so we could find them in the array and do something with the timeScale(). I was assuming they were identical so that would be the easiest way to get to them. But, as Carl mentioned, if all the items have some unique characteristic like a class, ID or data attribute, you can easily grab them via the getTweensOf() method. 

 

Here's a fork of my demo that also grabs the red and purple boxes via getTweensOf().

 

http://codepen.io/PointC/pen/BWmRYo/

 

Happy tweening.

:)

  • Like 2

Share this post


Link to post
Share on other sites

Thanks for all your help here guys. 

 

When adjusting the duration, how would you first reset the items rotation back to the 0?

Share this post


Link to post
Share on other sites

Not sure I'm using these functions correctly. The following returns a 'p.restart is not a function' error:

var p = TweenMax.getTweensOf(path);
p.restart();

Share this post


Link to post
Share on other sites

getTweensOf() returns an array of tweens :) Looks like you're trying to call restart() on the array object itself (bad). 

 

You could either loop through the elements of the array and call restart() on each one, or maybe drop them all into a timeline and just play. 

var tl = new TimelineLite();
tl.add(TweenMax.getTweensOf(path));

Does that help?

  • Like 1

Share this post


Link to post
Share on other sites

Assuming you just want to snap them back to their starting point quickly before changing the timeScale(), any of these should work too:

var p = TweenMax.getTweensOf(path);

TweenMax.set(p, {restart:true}) 
TweenMax.set(p, {progress:0}) 
TweenMax.set(p, {time:0}) 

Happy tweening.

:)

Share this post


Link to post
Share on other sites

Thought I'd tried that too. Will give it another go.

 

Thanks.

Share this post


Link to post
Share on other sites

I cant seem to reset a rotating element back to its starting position - see 

Please could you help?

 

 

Share this post


Link to post
Share on other sites

getTweensOf() returns an array. Your code sets p to an array with one item. You can set the progress of the first tween to 0 and pause it to reset it.

 

$('button').on('click', function(){
    var p = TweenMax.getTweensOf( $('.orbit1 .path') );
    p[0].progress(0).pause();
});

 

If you intend to control each orbiting ball on its own, I would recommend not putting them all in a timeline as the point of a timeline is to have everything perfectly synchronized. If you start telling the playheads of each child tweene to jump all over the place while the parent timeline is still progressing forward you will probably get undesired results.

 

  • Like 1

Share this post


Link to post
Share on other sites

This gets them back to their start position, but only when using pause. How do I return them to their start position but resume the rotation? Or maybe better to remove the animation and start again as a new timeline for performance?

 

See the codepen...

 

 

Share this post


Link to post
Share on other sites

I'm not sure if I'm not understanding the desired outcome here, but couldn't you just restart the timeline in your click function?

 

Is that what you meant?

 

Happy tweening.

:)

Share this post


Link to post
Share on other sites

No, the final product will have filters that will remove and add orbits. Any orbits that aren't removed when a filter is applied need to be set back to their start position and begin rotating again. See the attached codepen - how can a reset and restart immediately?

 

 

Share this post


Link to post
Share on other sites

o.k. - if I understand your desired outcome correctly, I'd echo @Carl's advice above and not place them on a timeline. Is this what you meant?

 

 

  • Like 2

Share this post


Link to post
Share on other sites

Hi Crag,

 

I do get more desirable results this way. Whats the easiest way to pause all tweens if not on a timeline?

Share this post


Link to post
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.