PR pixi-reels

ReelSetEvents

pixi-reels


pixi-reels / index / ReelSetEvents

Interface: ReelSetEvents

Defined in: events/ReelEvents.ts:41

Events emitted by a ReelSet.

Extends

  • Record<string, unknown[]>

Indexable

[key: string]: unknown[]

Properties

PropertyTypeDescriptionDefined in
adjust:complete[{ reelIndex: number; }]MultiWays: per-reel AdjustPhase exit.events/ReelEvents.ts:121
adjust:start[{ fromRows: number; reelIndex: number; toRows: number; }]MultiWays: per-reel AdjustPhase entry. fromRows is the row count before the reshape; toRows is the row count after.events/ReelEvents.ts:119
cascade:chain:end[{ chain: number; nextGrid: string[][]; winners: readonly { reel: number; row: number; }[]; }]Tumble cascade: a single chain stage just finished. both destroy AND refill drop-in are done, and the chain is about to loop back to the next detectWinners (or exit). The mirror of cascade:chain:start. - chain. same 1-indexed chain stage number as chain:start. - winners. cells that were destroyed this stage. - nextGrid. the grid the next chain iteration will read.events/ReelEvents.ts:285
cascade:chain:start[{ chain: number; currentGrid: string[][]; winners: readonly { reel: number; row: number; }[]; }]Tumble cascade: a single chain stage just started. Fired inside runCascade(...) after detectWinners returns a non-empty list, BEFORE destroySymbols runs. The canonical place to cue per-cascade SFX, light up a chain counter HUD, or freeze auto-play controls for the duration of the stage. Pair with cascade:chain:end for symmetric setup / teardown. - chain. 1-indexed chain stage number (1 on the first refill, 2 on the second, etc.). - winners. cells about to be destroyed this stage. - currentGrid. grid as it stands right now (pre-destroy).events/ReelEvents.ts:271
cascade:destroy:end[{ cells: readonly { reel: number; row: number; }[]; failed?: readonly { reel: number; row: number; }[]; }]Tumble cascade: destroySymbols(cells, ...) just finished. every cell’s playDestroy() settled and the viewport dim (if any) was restored. Mirror of cascade:destroy:start. - cells. the cells the call was invoked with (same identity as the start payload). - failed. optional; present only when one or more playDestroy() promises rejected. The next refill() / setResult() resets these cells via _replaceSymbol, so the visible state recovers automatically. listen if you want to log / replay-mark / alarm on the rejection.events/ReelEvents.ts:314
cascade:destroy:start[{ cells: readonly { reel: number; row: number; }[]; }]Tumble cascade: destroySymbols(cells, ...) is about to start. Fires once per call. both inside runCascade and when consumers call destroySymbols directly. Empty cell lists do NOT emit this event (the call returns immediately with no animation). Use this to cue a destroy SFX, dim a HUD, or capture the pre-destroy grid for replay logging. Synchronous; the destroy tweens start right after listeners return.events/ReelEvents.ts:300
cascade:dropIn:end[{ reelIndex: number; }]Tumble cascade: this reel’s drop-in animation finished.events/ReelEvents.ts:204
cascade:dropIn:start[{ reelIndex: number; }]Tumble cascade: this reel’s drop-in animation just started.events/ReelEvents.ts:180
cascade:dropIn:symbol[{ duration: number; ease: string; offsetRows: number; reelIndex: number; rowIndex: number; signal: AbortSignal; symbol: ReelSymbol; view: Container; }]Tumble cascade: about to animate one symbol’s drop-in. Same contract as cascade:fall:symbol. fires right BEFORE the tween, listeners may start parallel tweens. offsetRows is the number of cells this symbol will traverse (1 for top-row refills, more for survivors sliding past larger holes). signal aborts when the drop-in is skipped / slammed. Use it to kill parallel tweens or gsap.delayedCall handles (landing squish, bounce, badge animations) so a slam-stop doesn’t leave timers firing after the library has snapped the view to its grid position.events/ReelEvents.ts:193
cascade:fall:end[{ reelIndex: number; }]Tumble cascade: this reel’s fall-out animation finished.events/ReelEvents.ts:155
cascade:fall:start[{ reelIndex: number; }]Tumble cascade: this reel’s fall-out animation just started. Fires once per reel per spin() (never on refill(). refill skips the fall).events/ReelEvents.ts:126
cascade:fall:symbol[{ distance: number; duration: number; ease: string; reelIndex: number; rowIndex: number; signal: AbortSignal; symbol: ReelSymbol; view: Container; }]Tumble cascade: about to animate one symbol’s fall-out. Fires once per visible symbol per cascade:fall:start, right BEFORE the GSAP tween begins. listeners can start parallel tweens on any other view property (scale, alpha, badge text, spine track) and they’ll run in sync with the library’s view.y animation. - symbol. the ReelSymbol about to fall (current id, current view) - view. the symbol’s PixiJS container (same as symbol.view) - duration, ease, distance. what the library will animate - signal. aborts when the fall is skipped / slammed. Register a one-shot signal.addEventListener('abort', cleanup, { once: true }) to kill any parallel tweens or gsap.delayedCall handles your listener started, so a slam-stop doesn’t leave squish / bounce timers firing after the library has snapped the view to its final position.events/ReelEvents.ts:144
cascade:gravity:end[{ reelIndex: number; }]Tumble cascade. two-stage refill only: this reel’s gravity stage just finished. Fires per-reel; the global hold (gravityHoldMs) begins AFTER the slowest reel reports this event.events/ReelEvents.ts:242
cascade:gravity:error[{ error: unknown; }]Tumble cascade. two-stage refill only: a user-supplied gate (gravityHold promise/factory or onGravityComplete callback) rejected or threw. The engine logs the error to console.error and slams the refill so the awaited refill() / runCascade() promise still settles. but the original rejection reason would otherwise be lost. Listen here to forward the error to your own logger / alarm / error reporter. - error. whatever the user-supplied promise rejected with (or onGravityComplete threw). Typed unknown because user code is free to throw anything.events/ReelEvents.ts:256
cascade:gravity:start[{ reelIndex: number; }]Tumble cascade. two-stage refill only: this reel’s GRAVITY stage just started. Gravity = surviving symbols sliding down to fill the holes the winners left behind, without any new symbols entering yet. New symbols stay hidden above the viewport until cascade:dropIn:start fires later in the same refill (after gravityHoldMs). NEVER fires in the default mode: 'combined' refill. only when the caller opts into mode: 'gravity-then-drop' on refill() / runCascade({ refillMode: ... }).events/ReelEvents.ts:216
cascade:gravity:symbol[{ duration: number; ease: string; offsetRows: number; reelIndex: number; rowIndex: number; signal: AbortSignal; symbol: ReelSymbol; view: Container; }]Tumble cascade. two-stage refill only: about to animate one survivor sliding down. Same contract as cascade:dropIn:symbol but scoped to survivors (no new symbols). offsetRows is how many cells this survivor will slide down. Reels where no survivor moves (e.g. all winners landed at the top of the column) skip this event entirely. the gravity stage has nothing to animate there.events/ReelEvents.ts:227
cascade:place:end[{ isInitial: boolean; placedSymbols: readonly ReelSymbol[]; reelIndex: number; winnerRows: readonly number[]; }]Tumble cascade: new symbol identities just landed in the reel buffer. Fires AFTER placeSymbols snaps everything to grid, BEFORE the drop-in tween starts. the canonical spot to apply per-symbol decorations (multiplier badges, sticky markers) so they fall WITH the symbol. cascade:place is a single-moment placement (no animation), so it has no :start counterpart. only this :end. - isInitial: true on Moment A (after a spin() click). Every visible row is “new”. winnerRows is [] because there’s no prior grid. - isInitial: false on Moment B (a refill()). winnerRows lists the row indices whose old symbols were cleared by the win; rows in that set are new arrivals, the rest are survivors sliding down to fill holes. Pair with computeDropOffsets (or just walk winnerRows yourself) if you need to decorate only new arrivals.events/ReelEvents.ts:173
destroyed[]-events/ReelEvents.ts:384
nudge:cancelled[{ direction: "up" | "down"; distance: number; reason: string; reelIndex: number; }]A nudge was cancelled via options.signal.abort() or by destroying the reel mid-tween. The strip has been snapped to its post-nudge landed position (deterministic landing. the contract is “incoming lands at these positions” regardless of how the tween ended), but the original nudge() promise rejected with an AbortError. Listeners that animate alongside the nudge (HUDs, SFX) should treat this as a “stop and clean up” signal, NOT a “the nudge finished normally” signal. call animations should be cut, not played out. nudge:complete does NOT fire alongside this event.events/ReelEvents.ts:378
nudge:complete[{ direction: "up" | "down"; distance: number; reelIndex: number; symbols: string[]; }]A reel-at-rest nudge finished. the strip has snapped to its post-nudge grid position. Mirror of nudge:start. symbols is the full new visible column top-to-bottom (handy for win-detection re-runs).events/ReelEvents.ts:360
nudge:start[{ direction: "up" | "down"; distance: number; reelIndex: number; }]A reel-at-rest nudge is about to tween. Fires after Reel.nudge has finished pre-placing incoming symbols into the buffer and snapping the strip to its pre-tween grid. i.e. the observable state at the moment this event fires is the about-to-animate state, not the pre-mutation state. To capture the pre-nudge frame, snapshot the grid before awaiting the call. Nudges are always per-reel. multi-reel sync is via Promise.all([...]) of independent calls, each of which emits its own start/complete pair. - direction: 'down'. symbols visually move down, new symbols enter from the top of the visible window. - direction: 'up'. opposite: symbols move up, new symbols enter from the bottom.events/ReelEvents.ts:350
pin:expired[CellPin, PinExpireReason]-events/ReelEvents.ts:96
pin:migrated[CellPin, { clamped: boolean; fromRow: number; reelIndex: number; toRow: number; }]MultiWays: a pin was relocated by an AdjustPhase reshape because its originRow either no longer fits within the new shape (clamped: true) or fits at a row that differs from its current visual position. Always fires from a MultiWays AdjustPhase. non-MultiWays slots never emit this event.events/ReelEvents.ts:105
pin:moved[CellPin, { col: number; row: number; }]-events/ReelEvents.ts:95
pin:overlayCreated[CellPin, unknown]Fires whenever the engine creates a visual overlay symbol for a pin during a spin’s motion phase. The overlay argument is the pooled ReelSymbol instance. typed as unknown here to keep this module free of symbol-layer imports; cast to your concrete symbol class. Use this hook to drive animation state on the overlay (e.g. set a Spine animation track). The overlay is recycled on pin:overlayDestroyed.events/ReelEvents.ts:327
pin:overlayDestroyed[CellPin, unknown]Fires when the engine is about to release a pin’s visual overlay back to the pool (on spin:allLanded, unpin, or pin replacement). Use this hook to stop any animations or listeners you attached.events/ReelEvents.ts:333
pin:placed[CellPin]A pin was placed at a cell. The pin’s originRow is captured at placement and frozen for its lifetime; on MultiWays slots it controls how the pin migrates across reshapes (see pin:migrated). For non-MultiWays slots originRow === pin.row and never changes. but the field is still on the payload, so trace logs can show the intent.events/ReelEvents.ts:94
shape:changed[number[]]MultiWays: setShape(rowsPerReel) recorded a new target shape for the upcoming AdjustPhase. Fires before any geometry change. No-op for non-MultiWays slots. they never see this event.events/ReelEvents.ts:114
skip:boosted[{ current: SpeedProfile; previous: SpeedProfile; }]Round-aware skip() first-press boost: in standard (non-cascade) mode, the engine switched the active speed profile to the fastest registered one for the rest of this round. Fires once per round on the first skip() press only, alongside the slam. never on subsequent presses, never on slamStop() or requestSkip(), and never in cascade mode (which auto-slams refills instead of boosting speed). The round-end restore on the next spin() does not fire this event; listen to speed:changed if you need that signal.events/ReelEvents.ts:60
skip:completed[]-events/ReelEvents.ts:49
skip:requested[]-events/ReelEvents.ts:48
speed:changed[SpeedProfile, SpeedProfile]-events/ReelEvents.ts:61
spin:allLanded[SpinResult]-events/ReelEvents.ts:46
spin:allStarted[]-events/ReelEvents.ts:43
spin:complete[SpinResult]-events/ReelEvents.ts:47
spin:reelLanded[number, string[]]-events/ReelEvents.ts:45
spin:start[]-events/ReelEvents.ts:42
spin:stopping[number]-events/ReelEvents.ts:44
spotlight:end[]-events/ReelEvents.ts:63
spotlight:start[SymbolPosition[]]-events/ReelEvents.ts:62
win:end["aborted" | "complete"]WinPresenter finished. either naturally (complete) or via abort.events/ReelEvents.ts:86
win:group[Win, readonly SymbolPosition[]]A single win is now being presented. Fires once per win per cycle. before win:symbol fires for its cells. Subscribe to draw per-win visuals (payline polyline, cluster outline, number popup) using reelSet.getCellBounds(col, row).events/ReelEvents.ts:76
win:start[readonly Win[]]WinPresenter started a sequence. Fires once per show() call, with the full list of wins in the order they’ll be shown (sorted by value desc by default).events/ReelEvents.ts:69
win:symbol[unknown, SymbolPosition, Win]A specific cell is being animated. Fires once per cell per win per cycle. symbol is typed as unknown to keep this module free of symbol-layer imports; cast to ReelSymbol (or your subclass). When WinPresenter.stagger > 0, successive cells fire this event one after another with that gap.events/ReelEvents.ts:84