Lab 01 / 04

Stagger Lab

One call, many targets, offset in time or in value. Every sample below is a single stagger() doing the choreography.

Spec 01 — Grid Stagger

n = 144 · grid [16, 9]

Tip — click any individual cell to ripple from its index.

animate(cells, {
  keyframes: [
    { scale: 0.35, backgroundColor: '#2442ff', duration: 280 },
    { scale: 1,    backgroundColor: '#121212', duration: 560 },
  ],
  ease: 'outExpo',
  delay: stagger(30, { grid: [16, 9], from: 'center' }),
});

Spec 02 — Wave

n = 24 · from 'center' · loop + alternate

animate(bars, {
  scaleY: [0.15, 1],
  duration: 700,
  ease: 'inOutSine',
  loop: true,
  alternate: true,
  delay: stagger(60, { from: 'center' }),
});

Spec 03 — Text Cascade

splitText · staggered sine loop

STAGGER EVERYTHING

const { chars } = splitText('#cascade', { chars: true });
animate(chars, {
  y: ['0.35em', '-0.35em'],
  duration: 850,
  ease: 'inOutSine',
  loop: true,
  alternate: true,
  delay: stagger(70),
});

Spec 04 — Value Stagger

rotate: stagger([-45, 45])

The underused killer feature: stagger() can distribute the values themselves — here rotation is spread from −45° to +45° and lightness steps up per index, while a second stagger offsets the delays.

animate(squares, {
  rotate: stagger([-45, 45]),          // values, not delays
  backgroundColor: (el, i) => `hsl(231, 100%, ${18 + i * 6}%)`,
  delay: stagger(60),                  // and delays too
  duration: 700,
  ease: 'inOutQuad',
});