Jump to content
Search Community

How to add time at the end of a timeline

danissimo test
Moderator Tag

Recommended Posts

Yeah, you could add dummy tween at any any specific time you want

 

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


var tl = new TimelineLite();
tl.to(mc, 1, {x:100})
trace(tl.duration()); // 1 


//add a dummy set() at a time of 10 that does nothing to nothing (basically a tween with no duration, target or vars)
tl.set({}, {}, 10);
trace(tl.duration()); //10

or to add the set() 4 seconds after the last tween in the timeline ends (relative position) use

tl.set({}, {}, "+=4") // 
  • Like 3
Link to comment
Share on other sites

  • 4 weeks later...

I'm sure this plugin is very useful to you, but I see a few issues with making it a part of GSAP:

 

Adding an empty set() only really serves one purpose - to add empty space at the end of a timeline. For a lot of people it's not a common requirement so I'm not sure it really needs a custom function just to change

timeline.set({},{},"+=5");

to

timeline.addDelay(5);
// only 5 characters are saved here, compared to all that would be added
// to GSAP if this was built into TimelineLite

The only other purpose it could serve, would be as an alternative to adding the delay to the next tween e.g.

new TimelineLite().to(target, duration, vars)
                  .to(target, duration, vars, "+=4")

could become

new TimelineLite().to(target, duration, vars)
                  .addDelay(4)
                  .to(target, duration, vars)

which is not necessarily an 'improvement'. The API already serves this purpose, and Jack is not usually inclined to add cruft to the API if it isn't really necessary.

 

 

There could also be further confusion added by the unclear nature of adding 'delay' wherever you want. Take the following for instance:

new TimelineLite().to(target, 5, vars)
                  .addDelay(4, 0)
                  .to(target, 5, vars)

Adding 'delay' to anywhere but the end of the timeline immediately makes this behaviour more complicated to understand.

 

A 5 second tween is added to the start of the timeline, and then a 4 second delay is added to the start as well. Without immediate knowledge of the function, one might consider this addDelay function to 'push' the first tween forward, which of course it doesn't. It in fact does absolutely nothing in the context of this timeline, since the entire 'delay' falls inside the duration of the first tween. The user is left with a 10 second tween, no delay, and an erroneous addDelay in the middle of it.

 

Don't forget that tweens and timelines also have a delay() function for both getting and setting delay, which is probably another source for confusion.

 

 

Sorry if I sound really negative about the function; it's a good idea in theory, and like I said I'm sure it works well for you. I'm just wary about trying to add something that isn't super clear to the GSAP API when it already supports all of what you are trying to achieve. If you don't agree, or there are other uses I haven't thought of, please feel free to tell me I'm wrong :D

  • Like 1
Link to comment
Share on other sites

It makes sense.

 

I added the position parameter to keep in in line with the rest of the available methods but I can see that it might actually cause confusion.

 

Coming from jQuery, .addDelay(s) seemed logical.

 

An alternative would be a method that accepts values like

  • "+=4" to add a delay at the end
  • 4 to extend the duration until (at least) 4s.

This should be called something like .extendDuration() or .minimumDuration()

 

The problem with timeline.set({},{},"+=5"); is that it's anything but clear and not something easy to come up with.

Link to comment
Share on other sites

I agree with a lot of what both of you are saying, and Jamie is exactly right about me being very hesitant to bloat the API if there's any way we can avoid it. Granted, timeline.set({}, {}, "+=5") isn't nearly as readable/intuitive as timeline.pad(5) or something like that. However, I think it's important to think through WHY we'd need it. In what practical scenario is this useful? 

 

I can only think of two scenarios:

  1. You want a function called after some amount of delay beyond when some tweens complete. In this scenario, it's easy to just add a callback with a delay, like timeline.call(yourFunction, ["param"], scope, "+=5") or even more concisely timeline.add(yourFunction, "+=5")
  2. You want to add another tween at the end, but there should be a gap. In this case, a relative offset is perfect, like timeline.to(..., "+=5")

So I'm having a rough time finding a real-world scenario where a new method would truly make things more concise or intuitive, beyond what the current API already enables. 

 

If we added a minimumDuration() method, it may cause more confusion because what if you get a timeline back from some method (you may not know how the timeline was built or what its contents are) and you want to append some animations to the end of it, but someone applied a minimumDuration() to it and there's a 10-second gap at the end? You might get really frustrated and keep wondering why the heck there's such a delay. And what should happen if you clear() that timeline? Does it also get rid of that minimumDuration? And if you've got only a 1-second tween in a timeline and then you minimumDuration(20) and then append a to() tween, would that go right after the 1-second tween or at the 20-second spot? Probably the 20-second spot, but it might seem very unintuitive to some users. I imagine some folks might get pretty frustrated if they want to have it immediately follow the 1-second tween (ignore the minimumDuration while building). Then it may force us to add more parameters to the add() method and to(), and all the other build methods so that users can indicate if offsets are relative to the last "real" tween/callback or if the minimumDuration should be factored in. 

 

See why we have to be so careful? I've been doing this long enough to have seen things that seemed like great ideas in a particular scenario and then it ballooned into a much bigger deal down the road. There are often ripple effects to little feature additions like this that can be tough to see initially. 

  • Like 1
Link to comment
Share on other sites

Awesome reasoning!

 

I agree that jQuery's .delay() is often better translated to the delay property in each tween, but in some cases a simple .addDelay(time) can be useful.

 

Example A: when the timeline is not built in a linear way, eg:

  1. tween an element when timeline is created
  2. tween more in a loop
  3. maybe add a delay in a complex function or if I'm debugging
  4. tween some other element in another function
  5. an onComplete in an automated way

Example B: adding up a variable delay to an existing one (JS version here):

tl.to(element, 1, {x:10});
tl.addDelay(delay); //easy
tl.to(element, 1, {y:100}, '-=2');
tl.to(element, 1, {x:10});
tweenDelay = -2 + delay;
tl.to(element, 1, {y:100}, (tweenDelay<0?'-=':'+=')+tweenDelay);//meh

.

 

 

I suppose .minimumDuration() is not as simple as it may seem and the scenarios where it's useful is rare: I only needed to delay the call of onComplete.

I could just use .call(onCompleteFn, 5) but 5s might not end up at the end of the timeline, of course.

Link to comment
Share on other sites

In example A there are 2 things:
 
You say 'maybe add a delay' and then follow up with adding more tweens, but it still doesn't clear up whether this delay is just to 'pad' an onComplete to a minimum duration or whether it should actually affect the timelines duration and therefore the point at which new tweens are appended.
 
You also want to 'automate' the onComplete (I assume this is a minimum duration kind of automation?). Lets' say you want to make sure the onComplete occurs at least 5 seconds from the last tween, and at least 25 seconds from the start of the timeline. You could add this behaviour like this:

new TimelineLite({ onStart: function() {
  var minDuration = 25;
  var minPadding = 5; // minimum gap from the timelines final tween
  if (minDuration - minPadding < this.duration() {
    this.set({}, {}, "+=" + minPadding);
  } else {
    this.set({}, {}, minDuration);
  }
}, onComplete: completeFunction });

In regards to your 'meh' option in example B, you can easily accomplish that without the extra variable or conditional:

tl.to(element, 1, {x:10});
tl.to(element, 1, {y:100}, "+=" + (-2 + delay));

Just as you don't need to check if delay is positive or negative before adding it to -2, offset also conforms to this basic logic.
"+=-5" is the same as "-=5"
"-=-5" is the same as "+=5"

Link to comment
Share on other sites

For the record, the engine is smart enough to parse a value like "+=-5" because I figured some folks would try to do exactly what you're talking about (plug a variable in). So...

//clunky:
tl.to(element, 1, {y:100}, (tweenDelay<0?'-=':'+=')+tweenDelay);
//clean (same result)
tl.to(element, 1, {y:100}, "+=" + tweenDelay);

Again, it's fine if tweenDelay is a negative number. 

Link to comment
Share on other sites

  • 2 years later...

Hi @venn. Can you explain exactly what your goal is? Typically you shouldn't need to do that sort of stuff. You can drop a label in wherever you want, and then insert things at that spot. Like

.addLabel("myLabel", "+=5")
.to(..., "myLabel")

Or you can modularize your animation code using functions that spit back a tween or timeline that you then nest into a master timeline and place them wherever you want. I'm just having a tough time imagining a case where you'd really need to .set({}, {}, "+=5"). 

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