Motion · GSAP-style

Stagger

stagger: .03 starts each element 30 ms after the last. Order the elements — by index, randomly, or by distance from a point — and you control the shape of the wave.

Stagger follows the order of the collection you pass in. Because a jsKjs collection is an array, you can sort it first: shuffle for sparkle, or sort by distance from a click for a ripple.

For a true radial wave, give each element its own delay proportional to its distance from the origin — the "ripple" button shows how in six lines. That is the effect GSAP calls stagger: { from: 'center', grid }, built from primitives.

Live · Dot grid — click a dot to ripple from it

View the source for this demo
HTML
<div class="dots" id="dots" aria-hidden="true"></div>
<div class="row" style="margin-top:12px">
  <button type="button" id="st-cascade">Cascade (index order)</button>
  <button type="button" id="st-random">Sparkle (random order)</button>
  <button type="button" id="st-center">Ripple from centre</button>
</div>
JavaScript
const COLS = 14, ROWS = 6;
for (let i = 0; i < COLS * ROWS; i++) $('<div class="dot">').attr('data-i', i).appendTo('#dots');
const $dots = $('#dots .dot');
const pulse = { scale: 1.8, opacity: 1, duration: .22, ease: 'power2.out' };
const rest = { scale: 1, opacity: .35, duration: .4, ease: 'back.out' };

$('#st-cascade').on('click', async () => {
  await $.to($dots, { ...pulse, stagger: .012 });
  $.to($dots, { ...rest, stagger: .012 });
});

$('#st-random').on('click', async () => {
  const shuffled = [...$dots].sort(() => Math.random() - .5);
  await $.to(shuffled, { ...pulse, stagger: .01 });
  $.to(shuffled, { ...rest, stagger: .01 });
});

function ripple(origin) {
  const ox = origin % COLS, oy = Math.floor(origin / COLS);
  $dots.each((i, el) => {
    const d = Math.hypot(i % COLS - ox, Math.floor(i / COLS) - oy);   // distance in cells
    $.to(el, { ...pulse, delay: d * .05 }).then(() => $.to(el, rest));
  });
}

$('#dots').on('click', '.dot', function () { ripple(+this.dataset.i); });
$('#st-center').on('click', () => ripple(Math.floor(ROWS / 2) * COLS + COLS / 2));

More examples

Stagger a list on load

JavaScript
$.from('.menu li', { x: -12, opacity: 0, duration: .3, stagger: .04 });

API

stagger: seconds

Offset each element in a multi-element tween — the signature "cascade" effect.

Reference: stagger →
$.to(target, { …props, duration, delay, ease, stagger, onComplete }) → Promise

Tween to a state. stagger offsets each element’s start; onComplete fires after the last finishes. Also chainable on sets: $(sel).to(props).

Reference: $.to() →

Migrating

Coming from GSAPA number works like GSAP's stagger: 0.05. Stagger objects ({ each, from, grid, amount }) are not included — sort the collection or compute delays, as above.

Related features