Every canvas below runs the exact same scripted spin: 6×4 cards land with a pre-wired 3-cluster of 10 on row 2, those three winners fade out, 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:
.tumble({ fall, dropIn }). the animation feel itself.PAUSE_AFTER_REMOVAL_MS. the breathing room between the win-fade and the refill drop-in. Different feels want different pauses: snappy slams want ~120 ms, bouncy / dramatic feels want ~300-400 ms. Each canvas’s value is tuned to match its tumble shape.
Classic. the all-rounder default
Loading recipe…
.tumble({
fall: { duration: 280, ease: 'sine.in', rowStagger: 40 },
dropIn: { duration: 480, ease: 'back.out(1.6)', rowStagger: 50, distance: 'perHole' },
})
Gentle gravity fall + soft overshoot landing. back.out(1.6) overshoots its target by ~60 % and settles. Start here; tweak from here. A reasonable default if you have no other constraints.
Cartoon bounce. multi-bounce settle
Loading recipe…
.tumble({
fall: { duration: 320, ease: 'sine.in', rowStagger: 60 },
dropIn: { duration: 700, ease: 'bounce.out', rowStagger: 70, distance: 'perHole' },
})
bounce.out does a real multi-bounce settle. Symbols actually bounce on landing. Longer durations (700 ms) let each bounce read. Be careful with this one on dense grids: the bouncing arrival overlaps the next phase visually and can slow the perceived pace.
Slam. hard-landing, sub-half-second tumble
Loading recipe…
.tumble({
fall: { duration: 180, ease: 'power4.in', rowStagger: 20 },
dropIn: { duration: 260, ease: 'expo.out', rowStagger: 25, distance: 'perHole' },
})
power4.in accelerates the fall steeply (heavy, gravity-like). expo.out lands hard with no overshoot. 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: 240, ease: 'sine.in', rowStagger: 0 },
dropIn: { duration: 380, ease: 'sine.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: 180, ease: 'sine.in', rowStagger: 90 },
dropIn: { duration: 320, ease: 'back.out(2.0)', rowStagger: 110, distance: 'perHole' },
})
Heavy rowStagger (110 ms on drop-in) makes each row land in its own beat. back.out(2.0) adds a stronger overshoot than Classic. 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
| Feel | Pause | Pick when | Avoid when |
|---|---|---|---|
| Classic | 250 ms | Default if you have no other constraints | . |
| Cartoon bounce | 320 ms | Soft overshoot, multi-bounce landing | Dense grids where the bounce overlaps the next phase |
| Slam | 120 ms | Turbo mode, sub-half-second tumbles | You want a longer beat between cascades |
| Rain column | 380 ms | Match-3 / chess-board / puzzle grids | Reels are visually distinct (the cohesive slab look fights the column gaps) |
| Wave | 280 ms | Strong per-row stagger, row-by-row arrival | Very 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.
Related
- Cascade 6×5 tumble. the same recipe with cluster-detection logic and a multiplier counter.
- Spin first, cascade after. open with a strip-spin, cascade the respins.
- Cascade with WinPresenter. drive the win-fade through
WinPresenterinstead of plain gsap.