pixi-reels

ReelSetEvents

pixi-reels


pixi-reels / index / ReelSetEvents

Interface: ReelSetEvents

Defined in: events/ReelEvents.ts:87

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:245
adjust:start[{ fromCells: number; reelIndex: number; toCells: number; }]MultiWays: per-reel AdjustPhase entry. fromCells is the cell count before the reshape; toCells is the cell count after.events/ReelEvents.ts:243
anticipation:reel[{ order: number; reelIndex: number; total: number; }]A reel has BEGUN its anticipation tease (fired after any stagger offset, i.e. the moment it actually starts slowing). Carries the reel’s place in the tease sequence so you can drive per-step tension SFX / a pitch ramp (order / (total - 1)) / escalating visuals without re-deriving which reels are teasing from spin:stopping. Only fires for reels that tease (in the anticipation set AND the effective hold is > 0). - reelIndex: the reel now teasing. - order: 0-based position within the anticipation set (0 = first tease). - total: number of reels teasing this spin.events/ReelEvents.ts:102
anticipation:reelEnd[{ reelIndex: number; }]A teasing reel’s tease has ENDED (the reel landed). Fires only for reels that actually teased, just before that reel’s spin:reelLanded. Pair with anticipation:reel to bracket a per-reel tension effect.events/ReelEvents.ts:108
anticipation:segment[{ index: number; reelIndex: number; speed: number; targetSpeed: number; total: number; }]One leg of an anticipation curve has begun on a reel. Fires once per segment, in order, only for teases configured with a curve. The bookend events say a tease started and ended; this says which leg is playing, so a surge can get a different sound from the crawl that follows it without polling reel.speedNormalized and inferring the boundary. - reelIndex: the teasing reel. - index / total: this leg’s place in the curve. - speed: the leg’s target as a multiple of spinSpeed (as authored). - targetSpeed: the same target in px/frame.events/ReelEvents.ts:121
cascade:chain:end[{ chain: number; nextGrid: string[][]; winners: readonly { cell: number; reel: 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:409
cascade:chain:start[{ chain: number; currentGrid: string[][]; winners: readonly { cell: number; reel: 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:395
cascade:destroy:end[{ cells: readonly { cell: number; reel: number; }[]; failed?: readonly { cell: number; reel: 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:438
cascade:destroy:start[{ cells: readonly { cell: number; reel: 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:424
cascade:dropIn:end[{ reelIndex: number; }]Tumble cascade: this reel’s drop-in animation finished.events/ReelEvents.ts:328
cascade:dropIn:start[{ reelIndex: number; }]Tumble cascade: this reel’s drop-in animation just started.events/ReelEvents.ts:304
cascade:dropIn:symbol[{ cellIndex: number; duration: number; ease: string; offsetCells: number; reelIndex: 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. offsetCells is the number of cells this symbol will traverse (1 for top-cell 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:317
cascade:fall:end[{ reelIndex: number; }]Tumble cascade: this reel’s fall-out animation finished.events/ReelEvents.ts:279
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:250
cascade:fall:symbol[{ cellIndex: number; distance: number; duration: number; ease: string; reelIndex: 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:268
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:366
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:380
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:340
cascade:gravity:symbol[{ cellIndex: number; duration: number; ease: string; offsetCells: number; reelIndex: 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). offsetCells 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:351
cascade:place:end[{ isInitial: boolean; placedSymbols: readonly ReelSymbol[]; reelIndex: number; winnerCells: 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 cell is “new”. winnerCells is [] because there’s no prior grid. - isInitial: false on Moment B (a refill()). winnerCells lists the cell indices whose old symbols were cleared by the win; cells in that set are new arrivals, the rest are survivors sliding down to fill holes. Pair with computeDropOffsets (or just walk winnerCells yourself) if you need to decorate only new arrivals.events/ReelEvents.ts:297
destroyed[]-events/ReelEvents.ts:508
nudge:cancelled[{ direction: "forward" | "reverse"; 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:502
nudge:complete[{ direction: "forward" | "reverse"; 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:484
nudge:start[{ direction: "forward" | "reverse"; 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: 'forward'. symbols visually move down, new symbols enter from the top of the visible window. - direction: 'reverse'. opposite: symbols move up, new symbols enter from the bottom.events/ReelEvents.ts:474
pin:expired[CellPin, PinExpireReason]-events/ReelEvents.ts:220
pin:migrated[CellPin, { clamped: boolean; fromCell: number; reelIndex: number; toCell: number; }]MultiWays: a pin was relocated by an AdjustPhase reshape because its originCell either no longer fits within the new shape (clamped: true) or fits at a cell that differs from its current visual position. Always fires from a MultiWays AdjustPhase. non-MultiWays slots never emit this event.events/ReelEvents.ts:229
pin:moved[CellPin, { cell: number; reel: number; }]-events/ReelEvents.ts:219
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:451
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:457
pin:placed[CellPin]A pin was placed at a cell. The pin’s originCell 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 originCell === pin.cell and never changes. but the field is still on the payload, so trace logs can show the intent.events/ReelEvents.ts:218
shape:changed[number[]]MultiWays: setShape(cellsPerReel) 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:238
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:184
skip:completed[SkipInfo]The same press, once its reels are down: in the same tick for a slam, as the last freed reel lands for a quicken (however it got down, its own stop or a later slam). The same info its skip:requested carried.events/ReelEvents.ts:167
skip:queued[SkipContext<SpeedProfile>]requestSkip() came before the result: the press is kept and fires the moment the result arrives. The same context its skip:requested will carry, minus the reels, which are not known yet.events/ReelEvents.ts:173
skip:requested[SkipInfo]A skip press freed reels. reels lists the indices this press frees (already-landed and held reels are excluded), partial is true when reels are still spinning after it (a tease-protected press, a reel group, or a slamStop({ reels }) / slamStop({ except }) call), and mode says what freeing means: 'slam' places them now, 'quicken' asks each for its landing sooner and the landing arrives as the usual spin:reelLanding / spin:reelLanded. speed and payload are the press’s own, the same SkipContext every phase’s onSkip(ctx) saw.events/ReelEvents.ts:161
speed:changed[SpeedProfile, SpeedProfile]-events/ReelEvents.ts:185
spin:allLanded[SpinResult]-events/ReelEvents.ts:149
spin:allStarted[]-events/ReelEvents.ts:89
spin:complete[SpinResult]-events/ReelEvents.ts:150
spin:reelLanded[number, string[]]-events/ReelEvents.ts:148
spin:reelLanding[number, string[]]A reel is ON its result frame: the strip is snapped, every visible symbol has had onReelLanded(), and the landing bounce (if any) is about to tween. The frame to start a landing-coupled presentation on - an overlay, a per-reel SFX, a symbol takeover. Fires after the onReelLanded() loop by contract, so a listener that takes a landed symbol’s track over finds the engine’s own landing already set and can replace it in the same tick. Fires on every landing path - animated stop, slam, and each cascade refill stage that lands new symbols on the reel - and, unlike spin:reelLanded, is not deduplicated per spin. spin:reelLanded is the LATER bookend: it fires when the reel is fully at rest, a whole bounceDuration after this one on an animated stop, and in the same tick as this one on a slam, which has no bounce.events/ReelEvents.ts:147
spin:start[]-events/ReelEvents.ts:88
spin:stopping[number]-events/ReelEvents.ts:90
spotlight:end[]-events/ReelEvents.ts:187
spotlight:start[SymbolPosition[]]-events/ReelEvents.ts:186
win:end["aborted" | "complete"]WinPresenter finished. either naturally (complete) or via abort.events/ReelEvents.ts:210
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(reel, cell).events/ReelEvents.ts:200
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:193
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:208