pixi-reels
All recipes

Tumble feels. every preset

Five interactive canvases, same spin + cascade-refill loop. Only the .tumble({ fall, dropIn }) config changes between them. Click each SPIN to compare the feel without writing a line of code.

Every canvas below runs the exact same scripted spin: a 6×4 board of real Thunderkick spine symbols lands with a pre-wired 3-cluster of low1 on row 2, those three winners play their authored explode clip (compressed per canvas via TrackEntry.timeScale to match each tumble’s tempo), the loop pauses for a configured beat, then the cascade refill drops survivors into the holes and brings a fresh row from above. Two things vary between canvases:

  1. .tumble({ fall, dropIn }). the animation feel itself.
  2. PAUSE_AFTER_REMOVAL_MS. the breathing room between the explosion and the refill drop-in. Different feels want different pauses: snappy slams want ~8 frames (133 ms), slow / dramatic feels want 18-24 frames (300-400 ms). Every timing on this page is a whole number of 60 fps frames written in ms (267 = 16 frames, 400 = 24, 50 = 3). animations land on frame boundaries instead of arbitrary milliseconds.

Classic. the all-rounder default

Loading recipe…

.tumble({
  fall:   { duration: 267, ease: 'power2.in', rowStagger: 33 },
  dropIn: { duration: 400, ease: 'power2.in', rowStagger: 50, distance: 'perHole' },
})

Gravity on both ends: the board accelerates out, the new symbols accelerate in and stop dead on the grid. no settle animation at all. Two ease families are banned here by the art: overshoot (back, bounce). an overshooting frame gaps from its neighbours and only reads well on frameless art. and decelerating settles (*.out). a framed tile easing gently into place reads mushy; a falling tile hits its slot like the physical object it’s drawn as.

Slow drop. long hang, heavy stagger

Loading recipe…

.tumble({
  fall:   { duration: 333, ease: 'power2.in', rowStagger: 67 },
  dropIn: { duration: 700, ease: 'power2.in', rowStagger: 67, distance: 'perHole' },
})

The slow, dramatic variant: a long 700 ms (42-frame) power2.in with a heavy stagger. each row hangs at the top, then accelerates into its slot. The pacing lives entirely in duration + stagger; the landing itself still hits dead. (On frameless art this slot is where you’d reach for bounce.out.)

Slam. hard-landing, sub-half-second tumble

Loading recipe…

.tumble({
  fall:   { duration: 167, ease: 'power3.in', rowStagger: 17 },
  dropIn: { duration: 250, ease: 'power3.in', rowStagger: 17, distance: 'perHole' },
})

power3.in on both ends. the steepest acceleration into a dead stop. The whole tumble plays in under half a second. A reasonable basis for a turbo mode toggle on top of a default-classic build.

Rain column. board-falls-as-a-slab

Loading recipe…

.tumble({
  fall:   { duration: 233, ease: 'power2.in', rowStagger: 0 },
  dropIn: { duration: 367, ease: 'power2.in', rowStagger: 0, distance: 'auto' },
})

rowStagger: 0 makes every row start together. distance: 'auto' overrides the gravity-correct per-hole distance with a uniform full-column-height drop, so the new column appears as a coherent slab from above the viewport. Match-3, puzzle, or chess-board grids where “the board itself moves” is the visual idea.

Wave. rolling top-to-bottom reveal

Loading recipe…

.tumble({
  fall:   { duration: 183, ease: 'power2.in', rowStagger: 83 },
  dropIn: { duration: 333, ease: 'power2.in', rowStagger: 117, distance: 'perHole' },
})

Heavy rowStagger (117 ms = 7 frames on drop-in) makes each row land in its own beat. the wave IS the stagger. Row 0 lands, then row 1, then row 2. Pair with row-by-row sound cues if you want a per-row audio hit. The more cascades in a chain, the more rows arrive in sequence.

Picking between them

FeelPausePick whenAvoid when
Classic250 ms (15f)Default if you have no other constraints.
Slow drop333 ms (20f)Long hang, heavy staggerTurbo-first games. the hang slows the perceived pace
Slam133 ms (8f)Turbo mode, sub-half-second tumblesYou want a longer beat between cascades
Rain column400 ms (24f)Match-3 / chess-board / puzzle gridsReels are visually distinct (the cohesive slab look fights the column gaps)
Wave300 ms (18f)Strong per-row stagger, row-by-row arrivalVery dense grids. the stagger makes the whole tumble feel long

The Pause column is PAUSE_AFTER_REMOVAL_MS in each recipe. the gap between the win-fade ending and the refill drop-in starting. It’s not a library setting; it’s just an await wait(ms) in your spin loop. Tuning it per feel is the single biggest lever on cascade pacing after the tumble config itself.

Beyond these five: anything goes. ease accepts any GSAP easing string. rowStagger is plain ms. distance is 'perHole' / 'auto' / a number. Mix to taste; the algorithm and lifecycle stay exactly the same.

Going beyond config

If a feel needs effects the config can’t express (squish, sticky badge tweens, spine state transitions, particle bursts). those are events, not config fields. Subscribe to cascade:fall:symbol / cascade:dropIn:symbol and run parallel tweens on any view property; they fire before the library’s view.y tween so your tweens stay in sync.

See the full tumble recipe doc for the per-symbol event hooks, the cascading-multiplier pattern, and the phase-override escape hatch.

Assets provided by Thunderkick