velocity icon indicating copy to clipboard operation
velocity copied to clipboard

Stagger decay

Open ccorcos opened this issue 10 years ago • 4 comments

Stagger adds a really nice touch to animations like transition.slideUpIn, but I'm having an issue using it with large lists. My specific case is this: I have 100 items in a list, but only 5 are visible. If I use transition.slideUpIn with a duration of 300ms and a stagger of 100ms, it looks great. However, if I start scrolling, I easily outpace the animation in one flick. In fact, the animation ends up taking 99*100+300 seconds = 10.2 seconds. This is no good.

So what I'd like to be possible is some sort of stagger decay. For example:

$elements.velocity('transition.slideUpIn', {duration: 200, stagger: 100, decay: 10})

The second element will have a 100ms stagger from the first. But the third will be 90 seconds after the second, and so on. Thus the total animation time with 10+ elements is 0.75 seconds.

ccorcos avatar Apr 09 '15 22:04 ccorcos

@ccorcos @julianshapiro sounds like a good idea. Actually, I think it will be more realistic if the stagger effect accelerates (or decays).

Only I think a coefficient will be more suitable then a steady decrease.

ydaniv avatar Apr 11 '15 08:04 ydaniv

Actually yes, deceleration is probably much better than decay

ccorcos avatar Apr 14 '15 05:04 ccorcos

I could see uses for both linear and coefficient based changes - maybe 0 < x < 1 for a percentage change, and 1 < x for a linear change?

If the change is decreasing then clamp it at 0 (otherwise might be hard to work out why the first and last elements are starting at the same time etc).

How about something like this -

var decay = parseFloat(opts.decay);
if (Type.isFunction(opts.stagger)) {
    decay = opts.decay.call(element, elementIndex, elementsLength);
}
if (typeof decay === "number" && decay !== 0) {
    if (decay > -1 && decay < 1) {
        opts.delay = Math.max(0, opts.delay - ((decay * elementIndex) * opts.delay));
    } else {
        opts.delay = Math.max(0, opts.delay - (decay * elementIndex));
    }
}

Rycochet avatar Apr 14 '15 08:04 Rycochet

I've already written about this and Julian has responded to it as well. Can't seem to find the thread right now though, but here's a fiddle:

http://jsfiddle.net/tommiehansen/nq94kt90/

This doesn't use any fancy solutions or stuff like decelleration etc but i don't think that's a bad thing but rather a good thing. I can't imagine that one would want to waste CPU/GPU-cycles on stuff that isn't visible anyway.

My test instead uses javascripts slice-method and simply applies animation #1 to X number of first objects and animation #2 to Y number of objects after those X number of objects.

This is important for when animation larger lists of different kind since, just as the first poster say, the total animation duration becomes way too long and it doesn't make much sense to applying hefty animations to objects that aren't in view anyway.

tommiehansen avatar Apr 21 '15 07:04 tommiehansen