BKWLD / tram

Cross-browser CSS3 transitions in JavaScript.
186 stars 23 forks source link

Feature ideas: delays and step durations #4

Closed danro closed 11 years ago

danro commented 11 years ago

After using tram on an actual project this weekend, I had some ideas about delays and durations.

1st, a delay in between queue steps is a must. I think wait() works nicely for this. I can alias it to "delay" if enough people prefer that.

tram(elem)
  .start({ opacity: 0 })
  .wait(2000)
  .then({ opacity: 1 })

2nd, I thought it would be nice to manually set the step duration for each step in the queue. For example, say you have opacity set to 1s, and width set to 400ms. Currently, Tram would wait for 1s, because that's the longest duration in that step:

tram(elem)
  .add('opacity 1s').add('width 400ms')
  .start({ opacity: 0.5, width: 100 }) // this step would take 1 second.
  .then(something)

But we could introduce a span virtual property to control how long to wait before going to the next step:

tram(elem)
  .add('opacity 1s').add('width 400ms')
  .start({ opacity: 0.5, width: 100, span: 500 }) // this step would take 500ms 
  .then(something)

Does span make you think too much about the dom? Should we call it time instead? I'm trying to keep it very separate from duration because that means something else entirely.. and I don't want new users to get confused about how this feature would compare to a traditional tween library like jquery.animate.

cc @josephschmitt @jeremiak @weotch

weotch commented 11 years ago
  1. I like "wait"
  2. Yeah, I like "time". Though I don't get your concern about "duration", cause it is the tween duration, right? But, I like both better than span.
danro commented 11 years ago

@weotch

I'm proposing a feature here that allows the "step" duration to be different than the "transition" duration. Consider the following scenario:

  1. I want to animate a box from 0-500px, and have it take 2 seconds.
  2. Then I want to simulate an overshoot and have the box move to 520px.
  3. However, I don't want to wait until the box is done moving to 500 before starting the overshoot. Instead of 2 seconds, I want to start the overshoot at say, 1.8 seconds.
  4. I don't want the opacity duration to be modified at all during the sequence.
tram(elem)
  .add('left 2s')
  .add('opacity 2s')
  .start({ opacity: 1, left: 500, span: '1.8s' }) 
  .then({ left: 520 })

So I still want the step to run for 2 seconds (and the opacity would keep going), but I am intentionally cutting it short to achieve a certain effect. That's the reason I don't want to use time here.

Any ideas?

danro commented 11 years ago

Alternatively I was considering something like this:

tram(elem)
  .add('left 2s')
  .add('opacity 2s')
  .start({ opacity: 1, left: 500, skip: true }, 
  .wait('1.8')
  .then({ left: 520 })

"Skip" would skip to the next item in the queue, which is a wait for 1.8 seconds.

danro commented 11 years ago

Not sure if "skip" is the right word though, maybe async ?

danro commented 11 years ago

Just to clarify here, I think async makes the most sense:

tram(elem)
  .add('left 2s')
  .start({ left: 500, async: true }) // this step does not wait to finish
  .wait('1.8') // this wait is triggered immediately.
  .then({ left: 520 }) // time to reach this step would be 1.8s instead of 2.
danro commented 11 years ago

Final spec for this feature:

tram(elem)
  .add('left 2s')
  .start({ left: 500, wait: '1s' }) // this step lasts 1 second instead of 2.
  .then({ top: 100 })
  .wait(500) // waits half a second between queue items.
  .then(callback);
weotch commented 11 years ago

@danro So the wait in line 3 is overriding the 2s in line 2?

danro commented 11 years ago

Nah, they're separate. Check out the example, and hopefully that will make more sense until I can document the wait property. http://bkwld.github.io/tram/examples/wait-usage.html