@energy8platform/game-engine 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +121 -0
  2. package/dist/animation.cjs.js +18 -3
  3. package/dist/animation.cjs.js.map +1 -1
  4. package/dist/animation.esm.js +18 -3
  5. package/dist/animation.esm.js.map +1 -1
  6. package/dist/core.cjs.js +18 -3
  7. package/dist/core.cjs.js.map +1 -1
  8. package/dist/core.esm.js +18 -3
  9. package/dist/core.esm.js.map +1 -1
  10. package/dist/host.cjs.js +18 -3
  11. package/dist/host.cjs.js.map +1 -1
  12. package/dist/host.d.ts +3 -5
  13. package/dist/host.esm.js +18 -3
  14. package/dist/host.esm.js.map +1 -1
  15. package/dist/index.cjs.js +18 -2535
  16. package/dist/index.cjs.js.map +1 -1
  17. package/dist/index.d.ts +3 -1020
  18. package/dist/index.esm.js +20 -2525
  19. package/dist/index.esm.js.map +1 -1
  20. package/dist/slot.cjs.js +1872 -61
  21. package/dist/slot.cjs.js.map +1 -1
  22. package/dist/slot.d.ts +555 -28
  23. package/dist/slot.esm.js +1857 -62
  24. package/dist/slot.esm.js.map +1 -1
  25. package/dist/vite.cjs.js +0 -5
  26. package/dist/vite.cjs.js.map +1 -1
  27. package/dist/vite.esm.js +0 -5
  28. package/dist/vite.esm.js.map +1 -1
  29. package/package.json +2 -35
  30. package/src/animation/Tween.ts +14 -3
  31. package/src/host/index.ts +0 -1
  32. package/src/host/types.ts +0 -3
  33. package/src/index.ts +0 -28
  34. package/src/slot/anim/easing-map.ts +16 -2
  35. package/src/slot/cascade/TumbleController.ts +230 -0
  36. package/src/slot/config/ReelSystemConfig.ts +559 -0
  37. package/src/slot/config/presets.ts +222 -0
  38. package/src/slot/features/extra.ts +189 -0
  39. package/src/slot/features/index.ts +44 -0
  40. package/src/slot/features/symbols.ts +183 -0
  41. package/src/slot/features/types.ts +136 -0
  42. package/src/slot/features/wilds.ts +151 -0
  43. package/src/slot/grid/ReelGrid.ts +93 -24
  44. package/src/slot/grid/SymbolCell.ts +45 -11
  45. package/src/slot/index.ts +61 -2
  46. package/src/slot/motion/AnticipationController.ts +96 -0
  47. package/src/slot/motion/SpinEngine.ts +384 -0
  48. package/src/slot/system/ReelSystem.ts +295 -0
  49. package/src/vite/index.ts +0 -5
  50. package/dist/react-jsx.cjs.js +0 -3
  51. package/dist/react-jsx.cjs.js.map +0 -1
  52. package/dist/react-jsx.d.ts +0 -602
  53. package/dist/react-jsx.esm.js +0 -2
  54. package/dist/react-jsx.esm.js.map +0 -1
  55. package/dist/react.cjs.js +0 -3787
  56. package/dist/react.cjs.js.map +0 -1
  57. package/dist/react.d.ts +0 -1467
  58. package/dist/react.esm.js +0 -3771
  59. package/dist/react.esm.js.map +0 -1
  60. package/dist/ui.cjs.js +0 -2999
  61. package/dist/ui.cjs.js.map +0 -1
  62. package/dist/ui.d.ts +0 -1116
  63. package/dist/ui.esm.js +0 -2983
  64. package/dist/ui.esm.js.map +0 -1
  65. package/src/react/EngineContext.ts +0 -26
  66. package/src/react/ReactScene.ts +0 -88
  67. package/src/react/applyProps.ts +0 -271
  68. package/src/react/catalogue.ts +0 -17
  69. package/src/react/createPixiRoot.ts +0 -31
  70. package/src/react/extendAll.ts +0 -74
  71. package/src/react/hooks.ts +0 -46
  72. package/src/react/index.ts +0 -29
  73. package/src/react/jsx-runtime.ts +0 -346
  74. package/src/react/reconciler.ts +0 -338
  75. package/src/slot/freeSpins/FreeSpinsSession.ts +0 -40
  76. package/src/state/StateMachine.ts +0 -231
  77. package/src/state/index.ts +0 -1
  78. package/src/ui/BalanceDisplay.ts +0 -159
  79. package/src/ui/Button.ts +0 -304
  80. package/src/ui/FlexContainer.ts +0 -775
  81. package/src/ui/Label.ts +0 -124
  82. package/src/ui/LabelValue.ts +0 -122
  83. package/src/ui/Layout.ts +0 -291
  84. package/src/ui/Modal.ts +0 -170
  85. package/src/ui/Panel.ts +0 -204
  86. package/src/ui/ProgressBar.ts +0 -170
  87. package/src/ui/ScrollContainer.ts +0 -478
  88. package/src/ui/Slider.ts +0 -241
  89. package/src/ui/Toast.ts +0 -150
  90. package/src/ui/Toggle.ts +0 -201
  91. package/src/ui/WinDisplay.ts +0 -145
  92. package/src/ui/index.ts +0 -33
  93. package/src/ui/view.ts +0 -28
package/dist/ui.d.ts DELETED
@@ -1,1116 +0,0 @@
1
- import { Texture, Container, TextStyle, ColorSource } from 'pixi.js';
2
-
3
- /**
4
- * Universal view input type for UI component visual slots.
5
- *
6
- * - `string` — texture name, resolved via `Sprite.from()`
7
- * - `Texture` — wrapped in a `Sprite`
8
- * - `Container` — used as-is (Sprite, Graphics, NineSliceSprite, AnimatedSprite, custom...)
9
- */
10
- type ViewInput = string | Texture | Container;
11
- /**
12
- * Resolve a ViewInput to a Container instance.
13
- *
14
- * @example
15
- * ```ts
16
- * resolveView('btn-idle') // → Sprite.from('btn-idle')
17
- * resolveView(someTexture) // → new Sprite(someTexture)
18
- * resolveView(myCustomContainer) // → myCustomContainer (as-is)
19
- * resolveView(undefined) // → null
20
- * ```
21
- */
22
- declare function resolveView(input: ViewInput | undefined | null): Container | null;
23
-
24
- type FlexDirection = 'row' | 'column';
25
- type JustifyContent = 'start' | 'center' | 'end' | 'space-between' | 'space-around';
26
- type AlignItems = 'start' | 'center' | 'end' | 'stretch';
27
- type AlignContent = 'start' | 'center' | 'end' | 'space-between' | 'stretch';
28
- type AlignSelf = 'auto' | 'start' | 'center' | 'end' | 'stretch';
29
- interface FlexItemConfig {
30
- /** Flex grow factor (0 = fixed size) */
31
- flexGrow?: number;
32
- /** Flex shrink factor (0 = don't shrink, default: 1) */
33
- flexShrink?: number;
34
- /** Explicit width override for layout calculations */
35
- layoutWidth?: number | string;
36
- /** Explicit height override for layout calculations */
37
- layoutHeight?: number | string;
38
- /** Override parent's alignItems for this child */
39
- alignSelf?: AlignSelf;
40
- /**
41
- * Exclude from flex layout (acts like position: absolute).
42
- *
43
- * Positioning props (`top`/`right`/`bottom`/`left`/`centerX`/`centerY`) describe
44
- * the **visual bounding rectangle**, so children with a centered internal
45
- * origin (Button, Label — `anchor = 0.5`) are positioned intuitively.
46
- * `left: 100` places the visible left edge at 100px, regardless of origin.
47
- */
48
- flexExclude?: boolean;
49
- /** Distance from top edge of parent content area to the child's visual top */
50
- top?: number;
51
- /** Distance from right edge of parent content area to the child's visual right */
52
- right?: number;
53
- /** Distance from bottom edge of parent content area to the child's visual bottom */
54
- bottom?: number;
55
- /** Distance from left edge of parent content area to the child's visual left */
56
- left?: number;
57
- /**
58
- * X coordinate of the child's visual center within parent content area.
59
- * Accepts pixels (`200`) or a percentage of parent content width (`'50%'`).
60
- * Takes precedence over `left`/`right`.
61
- */
62
- centerX?: number | string;
63
- /**
64
- * Y coordinate of the child's visual center within parent content area.
65
- * Accepts pixels or a percentage of parent content height (`'50%'`).
66
- * Takes precedence over `top`/`bottom`.
67
- */
68
- centerY?: number | string;
69
- }
70
- interface FlexContainerConfig {
71
- /** Layout direction (default: 'row') */
72
- direction?: FlexDirection;
73
- /** Main-axis distribution (default: 'start') */
74
- justifyContent?: JustifyContent;
75
- /** Cross-axis alignment (default: 'start') */
76
- alignItems?: AlignItems;
77
- /** Gap between children in pixels (default: 0) */
78
- gap?: number;
79
- /** Padding [top, right, bottom, left] or single number (default: 0) */
80
- padding?: number | [number, number, number, number];
81
- /** Individual padding overrides (take priority over `padding`) */
82
- paddingTop?: number;
83
- paddingRight?: number;
84
- paddingBottom?: number;
85
- paddingLeft?: number;
86
- /** Enable wrapping to next line (default: false) */
87
- flexWrap?: boolean;
88
- /** Distribution of lines along the cross axis when wrapping (default: 'start') */
89
- alignContent?: AlignContent;
90
- /** Maximum width before wrapping (only with flexWrap) */
91
- maxWidth?: number;
92
- /** Maximum height before wrapping (only with flexWrap + column) */
93
- maxHeight?: number;
94
- /** Explicit container width — number in pixels, or string percentage (e.g. "50%") resolved against parent */
95
- width?: number | string;
96
- /** Explicit container height — number in pixels, or string percentage (e.g. "50%") resolved against parent */
97
- height?: number | string;
98
- }
99
- /**
100
- * Lightweight flexbox-like layout container for PixiJS.
101
- *
102
- * Supports row/column direction, justify/align, gap, padding, wrapping,
103
- * and flex-grow distribution. Zero external dependencies.
104
- *
105
- * @example
106
- * ```ts
107
- * const toolbar = new FlexContainer({
108
- * direction: 'row',
109
- * justifyContent: 'space-between',
110
- * alignItems: 'center',
111
- * gap: 16,
112
- * padding: 12,
113
- * });
114
- *
115
- * toolbar.addFlexChild(button1);
116
- * toolbar.addFlexChild(button2);
117
- * toolbar.resize(800, 60);
118
- * ```
119
- */
120
- declare class FlexContainer extends Container {
121
- readonly __uiComponent: true;
122
- private _config;
123
- private _padding;
124
- private _maxWidth;
125
- private _maxHeight;
126
- /** @internal */ _explicitWidth: number;
127
- /** @internal */ _explicitHeight: number;
128
- /** @internal */ _computedWidth: number;
129
- /** @internal */ _computedHeight: number;
130
- /** @internal */ _availableWidth: number;
131
- /** @internal */ _availableHeight: number;
132
- /** @internal */ _rawWidth: number | string;
133
- /** @internal */ _rawHeight: number | string;
134
- private _layoutChildren;
135
- private _layoutDirty;
136
- private _layoutSuspended;
137
- constructor(config?: FlexContainerConfig);
138
- /** Add a child with optional flex config. Also registers in flex layout. */
139
- addFlexChild(child: Container, flexConfig?: FlexItemConfig): this;
140
- /** Remove a child from flex layout and display list */
141
- removeFlexChild(child: Container): this;
142
- /** Remove all flex children */
143
- clearFlexChildren(): this;
144
- /**
145
- * Override addChild so children automatically participate in flex layout.
146
- * This enables declarative usage from React JSX.
147
- */
148
- addChild<T extends Container>(...children: T[]): T;
149
- addChildAt<T extends Container>(child: T, index: number): T;
150
- removeChild<T extends Container>(...children: T[]): T;
151
- /** Get all flex layout children (read-only) */
152
- get flexChildren(): readonly Container[];
153
- /** Suspend automatic layout recalculation. Call resumeLayout() to flush. */
154
- suspendLayout(): void;
155
- /** Resume automatic layout and flush if dirty. */
156
- resumeLayout(): void;
157
- /** Update the container size and recalculate layout */
158
- resize(width: number, height: number): void;
159
- /** Update layout direction */
160
- setDirection(direction: FlexDirection): void;
161
- /** Update justifyContent */
162
- setJustifyContent(justify: JustifyContent): void;
163
- /** Update alignItems */
164
- setAlignItems(align: AlignItems): void;
165
- /** Update gap */
166
- setGap(gap: number): void;
167
- /** Update padding */
168
- setPadding(padding: number | [number, number, number, number]): void;
169
- /**
170
- * Recalculate and apply layout positions for all children.
171
- * Called automatically by `resize()`. Call manually after
172
- * adding/removing children without resize.
173
- */
174
- updateLayout(): void;
175
- /** Computed content size (after layout) */
176
- getContentSize(): {
177
- width: number;
178
- height: number;
179
- };
180
- /** React reconciler update hook — applies changed config props */
181
- updateConfig(changed: Record<string, any>): void;
182
- destroy(options?: boolean | {
183
- children?: boolean;
184
- texture?: boolean;
185
- textureSource?: boolean;
186
- }): void;
187
- }
188
-
189
- type ButtonState = 'default' | 'hover' | 'pressed' | 'disabled';
190
- interface ButtonConfig {
191
- /** Custom view for default state (string texture name, Texture, or Container) */
192
- defaultView?: ViewInput;
193
- /** Custom view for hover state */
194
- hoverView?: ViewInput;
195
- /** Custom view for pressed state */
196
- pressedView?: ViewInput;
197
- /** Custom view for disabled state */
198
- disabledView?: ViewInput;
199
- /** Width (for Graphics-based button, ignored when custom views provided) */
200
- width?: number;
201
- /** Height (for Graphics-based button) */
202
- height?: number;
203
- /** Corner radius (for Graphics-based button) */
204
- borderRadius?: number;
205
- /** Colors for each state (for Graphics-based button) */
206
- colors?: Partial<Record<ButtonState, number>>;
207
- /** Scale on press */
208
- pressScale?: number;
209
- /** Scale animation duration (ms) */
210
- animationDuration?: number;
211
- /** Start disabled */
212
- disabled?: boolean;
213
- /** Button text (rendered on top of the view) */
214
- text?: string;
215
- /** Button text style */
216
- textStyle?: Record<string, unknown>;
217
- /** Press callback */
218
- onPress?: () => void;
219
- }
220
- /**
221
- * Interactive button with per-state custom views and animations.
222
- *
223
- * Each visual state accepts a `ViewInput`: texture name, Texture, or any Container
224
- * (Sprite, NineSliceSprite, AnimatedSprite, custom artwork, etc).
225
- * Falls back to colored Graphics when no custom view is provided.
226
- *
227
- * @example
228
- * ```ts
229
- * // Graphics-based (quick prototyping)
230
- * const btn = new Button({
231
- * width: 200, height: 60, borderRadius: 12,
232
- * colors: { default: 0x22aa22, hover: 0x33cc33 },
233
- * text: 'SPIN',
234
- * onPress: () => spin(),
235
- * });
236
- *
237
- * // Asset-based (production art)
238
- * const btn = new Button({
239
- * defaultView: 'btn-idle',
240
- * hoverView: 'btn-hover',
241
- * pressedView: 'btn-pressed',
242
- * disabledView: 'btn-disabled',
243
- * text: 'SPIN',
244
- * onPress: () => spin(),
245
- * });
246
- *
247
- * // Custom Container view
248
- * const btn = new Button({
249
- * defaultView: myAnimatedSprite,
250
- * text: 'SPIN',
251
- * });
252
- * ```
253
- */
254
- declare class Button extends Container {
255
- readonly __uiComponent: true;
256
- private _views;
257
- private _state;
258
- private _enabled;
259
- private _config;
260
- private _textObj;
261
- /** Press callback */
262
- onPress?: () => void;
263
- constructor(config?: ButtonConfig);
264
- /** Current button state */
265
- get state(): ButtonState;
266
- /** Enable the button */
267
- enable(): void;
268
- /** Disable the button */
269
- disable(): void;
270
- /** Whether the button is enabled */
271
- get enabled(): boolean;
272
- set enabled(value: boolean);
273
- /** Whether the button is disabled */
274
- get disabled(): boolean;
275
- /** Update button text */
276
- set text(value: string);
277
- private _buildViews;
278
- private _rebuildViews;
279
- private _setState;
280
- private _onPointerOver;
281
- private _onPointerOut;
282
- private _onPointerDown;
283
- private _onPointerUp;
284
- private _onPointerUpOutside;
285
- /** React reconciler update hook */
286
- updateConfig(changed: Record<string, any>): void;
287
- destroy(options?: boolean | {
288
- children?: boolean;
289
- texture?: boolean;
290
- textureSource?: boolean;
291
- }): void;
292
- }
293
-
294
- interface ProgressBarConfig {
295
- /** Width of the bar */
296
- width?: number;
297
- /** Height of the bar */
298
- height?: number;
299
- /** Corner radius (for Graphics-based bar) */
300
- borderRadius?: number;
301
- /** Fill color (for Graphics-based bar, ignored when fillView provided) */
302
- fillColor?: number;
303
- /** Track background color (for Graphics-based bar, ignored when trackView provided) */
304
- trackColor?: number;
305
- /** Border color */
306
- borderColor?: number;
307
- /** Border width */
308
- borderWidth?: number;
309
- /** Animated fill (smoothly interpolate) */
310
- animated?: boolean;
311
- /** Animation speed (0..1 per frame, default: 0.1) */
312
- animationSpeed?: number;
313
- /** Custom track background (string texture name, Texture, or Container) */
314
- trackView?: ViewInput;
315
- /** Custom fill bar (string texture name, Texture, or Container) */
316
- fillView?: ViewInput;
317
- }
318
- /**
319
- * Horizontal progress bar with optional custom track/fill views.
320
- *
321
- * Supports asset-based skinning: provide `trackView` and/or `fillView`
322
- * as texture names, Textures, or any Container (NineSliceSprite, custom artwork, etc).
323
- * Falls back to colored Graphics when no custom views are provided.
324
- *
325
- * @example
326
- * ```ts
327
- * // Graphics-based (quick prototyping)
328
- * const bar = new ProgressBar({ width: 300, height: 20, fillColor: 0x22cc22 });
329
- * bar.progress = 0.5;
330
- *
331
- * // Asset-based (production art)
332
- * const bar = new ProgressBar({
333
- * width: 300, height: 20,
334
- * trackView: 'bar-track',
335
- * fillView: new NineSliceSprite({ texture: 'bar-fill', ... }),
336
- * });
337
- * bar.progress = 0.75;
338
- * ```
339
- */
340
- declare class ProgressBar extends Container {
341
- readonly __uiComponent: true;
342
- private _track;
343
- private _fill;
344
- private _fillMask;
345
- private _borderGfx;
346
- private _config;
347
- private _progress;
348
- private _displayedProgress;
349
- constructor(config?: ProgressBarConfig);
350
- /** Get/set progress (0..1) */
351
- get progress(): number;
352
- set progress(value: number);
353
- /**
354
- * Call each frame if animated is true.
355
- */
356
- update(_dt: number): void;
357
- /** React reconciler update hook */
358
- updateConfig(changed: Record<string, any>): void;
359
- private updateMask;
360
- }
361
-
362
- interface LabelConfig {
363
- text?: string;
364
- style?: Partial<TextStyle>;
365
- /** Maximum width — text will be scaled down to fit */
366
- maxWidth?: number;
367
- /** Auto-fit: scale text to fit maxWidth */
368
- autoFit?: boolean;
369
- }
370
- /**
371
- * Enhanced text label with auto-fit scaling and currency formatting.
372
- *
373
- * @example
374
- * ```ts
375
- * const label = new Label({
376
- * text: 'BALANCE',
377
- * style: { fontSize: 24, fill: 0xffd700 },
378
- * maxWidth: 200,
379
- * autoFit: true,
380
- * });
381
- * ```
382
- */
383
- declare class Label extends Container {
384
- readonly __uiComponent: true;
385
- private _text;
386
- private _maxWidth;
387
- private _autoFit;
388
- constructor(config?: LabelConfig);
389
- /** Get/set the displayed text */
390
- get text(): string;
391
- set text(value: string);
392
- /** Get/set the text style */
393
- get style(): TextStyle;
394
- /** Set max width constraint */
395
- set maxWidth(value: number);
396
- /**
397
- * Format and display a number as currency.
398
- *
399
- * @param amount - The numeric amount
400
- * @param currency - Currency code (e.g., 'USD', 'EUR')
401
- * @param locale - Locale string (default: 'en-US')
402
- */
403
- setCurrency(amount: number, currency: string, locale?: string): void;
404
- /**
405
- * Format a number with thousands separators.
406
- */
407
- setNumber(value: number, decimals?: number, locale?: string): void;
408
- /** React reconciler update hook */
409
- updateConfig(changed: Record<string, any>): void;
410
- private fitText;
411
- }
412
-
413
- type LabelValueAlign = 'start' | 'center' | 'end';
414
- interface LabelValueConfig {
415
- /** Caption text (top row, typically smaller/muted) */
416
- label?: string;
417
- /** Value text (bottom row, typically larger/prominent) */
418
- value?: string;
419
- /** Style for the caption Label */
420
- labelStyle?: Partial<TextStyle>;
421
- /** Style for the value Label */
422
- valueStyle?: Partial<TextStyle>;
423
- /** Gap in pixels between caption and value (default: 4) */
424
- gap?: number;
425
- /** Horizontal alignment of both rows (default: 'center') */
426
- align?: LabelValueAlign;
427
- /** Maximum width — value will be auto-scaled to fit when exceeded */
428
- maxWidth?: number;
429
- /** Optional padding (forwarded to the underlying FlexContainer) */
430
- padding?: FlexContainerConfig['padding'];
431
- }
432
- /**
433
- * Two-row text cell with a muted caption above and a prominent value below —
434
- * the archetypal casino UI pattern (BALANCE/€500, BET/€1, WIN/€0.00).
435
- *
436
- * Extends FlexContainer, so it participates in parent flex layouts directly
437
- * (you can pass `flexGrow`, `alignSelf`, etc. when it's a child of another
438
- * FlexContainer) and auto-sizes to its contents when no explicit size is set.
439
- *
440
- * @example
441
- * ```tsx
442
- * <labelValue
443
- * label="BALANCE"
444
- * value={`€${balance.toFixed(2)}`}
445
- * labelStyle={{ fontSize: 12, fill: 0x888888 }}
446
- * valueStyle={{ fontSize: 22, fill: 0xffffff, fontWeight: 'bold' }}
447
- * gap={6}
448
- * align="center"
449
- * />
450
- * ```
451
- */
452
- declare class LabelValue extends FlexContainer {
453
- private readonly _labelEl;
454
- private readonly _valueEl;
455
- private _valueMaxWidth;
456
- constructor(config?: LabelValueConfig);
457
- /** Get the caption Label (for advanced styling / animation) */
458
- get labelElement(): Label;
459
- /** Get the value Label */
460
- get valueElement(): Label;
461
- /** Update caption text */
462
- setLabel(text: string): void;
463
- /** Update value text */
464
- setValue(text: string): void;
465
- /** React reconciler update hook */
466
- updateConfig(changed: Record<string, any>): void;
467
- }
468
-
469
- interface PanelConfig {
470
- /** Width */
471
- width?: number;
472
- /** Height */
473
- height?: number;
474
- /** Background color (for Graphics-based panel) */
475
- backgroundColor?: number;
476
- /** Background alpha */
477
- backgroundAlpha?: number;
478
- /** Corner radius */
479
- borderRadius?: number;
480
- /** Border color */
481
- borderColor?: number;
482
- /** Border width */
483
- borderWidth?: number;
484
- /** 9-slice texture (if provided, uses NineSliceSprite instead of Graphics) */
485
- nineSliceTexture?: string | Texture;
486
- /** 9-slice borders [left, top, right, bottom] */
487
- nineSliceBorders?: [number, number, number, number];
488
- /** Padding inside the panel */
489
- padding?: number;
490
- /** Flex layout config for content */
491
- layout?: Partial<FlexContainerConfig>;
492
- }
493
- /**
494
- * Background panel with optional flexbox content layout.
495
- *
496
- * Supports both Graphics-based (color + border) and 9-slice sprite backgrounds.
497
- * Children added via `addContent()` participate in flex layout automatically.
498
- *
499
- * @example
500
- * ```ts
501
- * // Simple colored panel
502
- * const panel = new Panel({ width: 400, height: 300, backgroundColor: 0x222222, borderRadius: 12 });
503
- *
504
- * // 9-slice panel (texture-based)
505
- * const panel = new Panel({
506
- * nineSliceTexture: 'panel-bg',
507
- * nineSliceBorders: [20, 20, 20, 20],
508
- * width: 400, height: 300,
509
- * });
510
- * ```
511
- */
512
- declare class Panel extends Container {
513
- readonly __uiComponent: true;
514
- private _bg;
515
- private _content;
516
- private _internalSetup;
517
- private _panelConfig;
518
- constructor(config?: PanelConfig);
519
- /** Access the content flex container — add children here for layout */
520
- get content(): FlexContainer;
521
- /** Suspend content layout recalculation. Call resumeLayout() to flush. */
522
- suspendLayout(): void;
523
- /** Resume content layout and flush if dirty. */
524
- resumeLayout(): void;
525
- /** Convenience: add a child to the content layout */
526
- addContent(child: Container): this;
527
- /** Resize the panel */
528
- setSize(width: number, height: number): void;
529
- /**
530
- * Override addChild so external children are routed to content FlexContainer.
531
- * Enables `<panel><label /><button /></panel>` in React JSX.
532
- */
533
- addChild<T extends Container>(...children: T[]): T;
534
- removeChild<T extends Container>(...children: T[]): T;
535
- /** React reconciler update hook */
536
- updateConfig(changed: Record<string, any>): void;
537
- destroy(options?: boolean | {
538
- children?: boolean;
539
- texture?: boolean;
540
- textureSource?: boolean;
541
- }): void;
542
- }
543
-
544
- interface BalanceDisplayConfig {
545
- /** Label prefix (e.g., "BALANCE") */
546
- prefix?: string;
547
- /** Text style overrides */
548
- style?: Record<string, unknown>;
549
- /** Currency code */
550
- currency?: string;
551
- /** Locale for number formatting */
552
- locale?: string;
553
- /** Max width */
554
- maxWidth?: number;
555
- /** Animate value changes */
556
- animated?: boolean;
557
- /** Animation duration in ms */
558
- animationDuration?: number;
559
- }
560
- /**
561
- * Reactive balance display component.
562
- *
563
- * Automatically formats currency and can animate value changes
564
- * with a smooth countup/countdown effect using engine Tween.
565
- *
566
- * @example
567
- * ```ts
568
- * const balance = new BalanceDisplay({ currency: 'USD', animated: true });
569
- * balance.setValue(1000);
570
- *
571
- * // Wire to SDK
572
- * sdk.on('balanceUpdate', ({ balance: val }) => balance.setValue(val));
573
- * ```
574
- */
575
- declare class BalanceDisplay extends Container {
576
- readonly __uiComponent: true;
577
- private _prefixLabel;
578
- private _valueLabel;
579
- private _config;
580
- private _currentValue;
581
- private _displayedValue;
582
- /** Internal target for Tween animation */
583
- private _tweenTarget;
584
- constructor(config?: BalanceDisplayConfig);
585
- /** Current displayed value */
586
- get value(): number;
587
- /**
588
- * Set the balance value. If animated, smoothly counts to the new value.
589
- */
590
- setValue(value: number): void;
591
- /**
592
- * Set the currency code.
593
- */
594
- setCurrency(currency: string): void;
595
- private animateValue;
596
- private updateDisplay;
597
- private layoutLabels;
598
- /** React reconciler update hook */
599
- updateConfig(changed: Record<string, any>): void;
600
- destroy(options?: boolean | {
601
- children?: boolean;
602
- texture?: boolean;
603
- textureSource?: boolean;
604
- }): void;
605
- }
606
-
607
- interface WinDisplayConfig {
608
- /** Text style overrides */
609
- style?: Record<string, unknown>;
610
- /** Currency code */
611
- currency?: string;
612
- /** Locale for number formatting */
613
- locale?: string;
614
- /** Countup duration in ms */
615
- countupDuration?: number;
616
- /** Scale pop animation on win */
617
- popScale?: number;
618
- }
619
- /**
620
- * Win amount display with countup animation.
621
- *
622
- * Shows a dramatic countup from 0 to the win amount, with optional
623
- * scale pop effect — typical of slot games. Uses engine Tween system.
624
- *
625
- * @example
626
- * ```ts
627
- * const winDisplay = new WinDisplay({ currency: 'USD' });
628
- * scene.container.addChild(winDisplay);
629
- * await winDisplay.showWin(150.50); // countup animation
630
- * winDisplay.hide();
631
- * ```
632
- */
633
- declare class WinDisplay extends Container {
634
- readonly __uiComponent: true;
635
- private _label;
636
- private _config;
637
- /** Internal target for Tween countup */
638
- private _tweenTarget;
639
- constructor(config?: WinDisplayConfig);
640
- /**
641
- * Show a win with countup animation.
642
- *
643
- * @param amount - Win amount
644
- * @returns Promise that resolves when the animation completes
645
- */
646
- showWin(amount: number): Promise<void>;
647
- /**
648
- * Skip the countup animation and show the final amount immediately.
649
- */
650
- skipCountup(amount: number): void;
651
- /**
652
- * Hide the win display.
653
- */
654
- hide(): void;
655
- private displayAmount;
656
- /** React reconciler update hook */
657
- updateConfig(changed: Record<string, any>): void;
658
- destroy(options?: boolean | {
659
- children?: boolean;
660
- texture?: boolean;
661
- textureSource?: boolean;
662
- }): void;
663
- }
664
-
665
- interface ModalConfig {
666
- /** Overlay color */
667
- overlayColor?: number;
668
- /** Overlay alpha */
669
- overlayAlpha?: number;
670
- /** Close on overlay tap */
671
- closeOnOverlay?: boolean;
672
- /** Animation duration */
673
- animationDuration?: number;
674
- }
675
- /**
676
- * Modal overlay component.
677
- * Shows content on top of a dark overlay with enter/exit animations.
678
- *
679
- * Content is automatically centered via position calculations.
680
- *
681
- * @example
682
- * ```ts
683
- * const modal = new Modal({ closeOnOverlay: true });
684
- * modal.content.addChild(settingsPanel);
685
- * modal.onClose = () => console.log('Closed');
686
- * await modal.show(1920, 1080);
687
- * ```
688
- */
689
- declare class Modal extends Container {
690
- readonly __uiComponent: true;
691
- private _overlay;
692
- private _contentContainer;
693
- private _config;
694
- private _showing;
695
- private _internalSetup;
696
- /** Called when the modal is closed */
697
- onClose?: () => void;
698
- constructor(config?: ModalConfig);
699
- /** Content container — add your UI here */
700
- get content(): Container;
701
- /**
702
- * Override addChild so external children are routed to _contentContainer.
703
- * Enables `<modal><flexContainer>...</flexContainer></modal>` in React JSX.
704
- */
705
- addChild<T extends Container>(...children: T[]): T;
706
- removeChild<T extends Container>(...children: T[]): T;
707
- /** Whether the modal is currently showing */
708
- get isShowing(): boolean;
709
- /**
710
- * Show the modal with animation.
711
- */
712
- show(viewWidth: number, viewHeight: number): Promise<void>;
713
- /**
714
- * Hide the modal with animation.
715
- */
716
- hide(): Promise<void>;
717
- /** React reconciler update hook */
718
- updateConfig(changed: Record<string, any>): void;
719
- }
720
-
721
- type ToastType = 'info' | 'success' | 'warning' | 'error';
722
- interface ToastConfig {
723
- /** Auto-dismiss after this many ms (0 = manual dismiss only) */
724
- duration?: number;
725
- /** Toast position from bottom */
726
- bottomOffset?: number;
727
- /** Custom background view (string texture name, Texture, or Container). Sized to fit text. */
728
- backgroundView?: ViewInput;
729
- }
730
- /**
731
- * Toast notification component for displaying transient messages.
732
- *
733
- * @example
734
- * ```ts
735
- * const toast = new Toast();
736
- * scene.container.addChild(toast);
737
- * await toast.show('Connection lost', 'error', 1920, 1080);
738
- * ```
739
- */
740
- declare class Toast extends Container {
741
- readonly __uiComponent: true;
742
- private _bg;
743
- private _customBg;
744
- private _text;
745
- private _config;
746
- private _dismissPending;
747
- constructor(config?: ToastConfig);
748
- /**
749
- * Show a toast message.
750
- */
751
- show(message: string, type?: ToastType, viewWidth?: number, viewHeight?: number): Promise<void>;
752
- /**
753
- * Dismiss the toast.
754
- */
755
- dismiss(): Promise<void>;
756
- /** React reconciler update hook */
757
- updateConfig(changed: Record<string, any>): void;
758
- destroy(options?: boolean | {
759
- children?: boolean;
760
- texture?: boolean;
761
- textureSource?: boolean;
762
- }): void;
763
- }
764
-
765
- type LayoutDirection = 'horizontal' | 'vertical' | 'grid' | 'wrap';
766
- type LayoutAlignment = 'start' | 'center' | 'end' | 'stretch';
767
- type LayoutAnchor = 'top-left' | 'top-center' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
768
- interface LayoutConfig {
769
- /** Layout direction (default: 'vertical') */
770
- direction?: LayoutDirection;
771
- /** Gap between children in pixels (default: 0) */
772
- gap?: number;
773
- /** Padding inside the layout container [top, right, bottom, left] or a single number */
774
- padding?: number | [number, number, number, number];
775
- /** Alignment of children on the cross axis (default: 'start') */
776
- alignment?: LayoutAlignment;
777
- /** Anchor point determining where the layout is positioned relative to its coordinates */
778
- anchor?: LayoutAnchor;
779
- /** Number of columns (only for 'grid' direction) */
780
- columns?: number;
781
- /** Maximum width for 'wrap' direction before wrapping to next line */
782
- maxWidth?: number;
783
- /** Whether to auto-layout when children change (default: true) */
784
- autoLayout?: boolean;
785
- /** Breakpoints: map of max viewport widths to override configs */
786
- breakpoints?: Record<number, Partial<LayoutConfig>>;
787
- }
788
- /**
789
- * Responsive layout container powered by a lightweight built-in flex layout solver.
790
- *
791
- * Supports horizontal, vertical, grid, and wrap layout modes with
792
- * alignment, padding, gap, and viewport-anchor positioning.
793
- * Breakpoints allow different layouts for different screen sizes.
794
- *
795
- * @example
796
- * ```ts
797
- * const toolbar = new Layout({
798
- * direction: 'horizontal',
799
- * gap: 20,
800
- * alignment: 'center',
801
- * anchor: 'bottom-center',
802
- * padding: 16,
803
- * breakpoints: {
804
- * 768: { direction: 'vertical', gap: 10 },
805
- * },
806
- * });
807
- *
808
- * toolbar.addItem(spinButton);
809
- * toolbar.addItem(betLabel);
810
- * scene.container.addChild(toolbar);
811
- *
812
- * toolbar.updateViewport(width, height);
813
- * ```
814
- */
815
- declare class Layout extends Container {
816
- readonly __uiComponent: true;
817
- private _layoutConfig;
818
- private _padding;
819
- private _anchor;
820
- private _maxWidth;
821
- private _breakpoints;
822
- private _items;
823
- private _viewportWidth;
824
- private _viewportHeight;
825
- private _flex;
826
- constructor(config?: LayoutConfig);
827
- /** Add an item to the layout */
828
- addItem(child: Container): this;
829
- /** Remove an item from the layout */
830
- removeItem(child: Container): this;
831
- /** Remove all items */
832
- clearItems(): this;
833
- /** Get all layout items */
834
- get items(): readonly Container[];
835
- /**
836
- * Update the viewport size and recalculate layout.
837
- * Should be called from `Scene.onResize()`.
838
- */
839
- updateViewport(width: number, height: number): void;
840
- private applyLayoutStyles;
841
- private buildFlexItemConfig;
842
- private applyAnchor;
843
- private resolveConfig;
844
- /** React reconciler update hook */
845
- updateConfig(changed: Record<string, any>): void;
846
- destroy(options?: boolean | {
847
- children?: boolean;
848
- texture?: boolean;
849
- textureSource?: boolean;
850
- }): void;
851
- }
852
-
853
- type ScrollDirection = 'vertical' | 'horizontal' | 'both';
854
- interface ScrollContainerConfig {
855
- /** Visible viewport width */
856
- width: number;
857
- /** Visible viewport height */
858
- height: number;
859
- /** Scroll direction (default: 'vertical') */
860
- direction?: ScrollDirection;
861
- /** Background color (undefined = transparent) */
862
- backgroundColor?: ColorSource;
863
- /** Border radius for the mask (default: 0) */
864
- borderRadius?: number;
865
- /** Gap between items (default: 0) */
866
- elementsMargin?: number;
867
- /** Padding */
868
- padding?: number;
869
- /** Disable easing/inertia */
870
- disableEasing?: boolean;
871
- /** Show scrollbar indicator (default: false) */
872
- scrollbar?: boolean;
873
- /** Custom scrollbar thumb view (string texture name, Texture, or Container) */
874
- thumbView?: ViewInput;
875
- /** Scrollbar width in px (default: 6) */
876
- scrollbarWidth?: number;
877
- /** Scrollbar padding from edge (default: 4) */
878
- scrollbarPadding?: number;
879
- /** Scrollbar color (when no thumbView, default: 0xaaaaaa) */
880
- scrollbarColor?: number;
881
- /** Scrollbar alpha (default: 0.5) */
882
- scrollbarAlpha?: number;
883
- }
884
- /**
885
- * Scrollable container with touch/drag, mouse wheel, and inertia.
886
- *
887
- * @example
888
- * ```ts
889
- * const scroll = new ScrollContainer({
890
- * width: 600,
891
- * height: 400,
892
- * direction: 'vertical',
893
- * elementsMargin: 8,
894
- * });
895
- *
896
- * for (let i = 0; i < 50; i++) {
897
- * scroll.addItem(createRow(i));
898
- * }
899
- *
900
- * scene.container.addChild(scroll);
901
- * ```
902
- */
903
- declare class ScrollContainer extends Container {
904
- readonly __uiComponent: true;
905
- private _viewport;
906
- private _internalSetup;
907
- private _content;
908
- private _maskGfx;
909
- private _bg;
910
- private _scrollConfig;
911
- private _items;
912
- private _scrollbar;
913
- private _scrollbarConfig;
914
- private _dragging;
915
- private _dragStart;
916
- private _contentStart;
917
- private _velocity;
918
- private _lastDragPos;
919
- private _lastDragTime;
920
- private _inertiaActive;
921
- private _onTickBound;
922
- private _onWheelBound;
923
- constructor(config: ScrollContainerConfig);
924
- /**
925
- * Override addChild so external children are routed to scroll content.
926
- * Enables `<scrollContainer><label /><panel /></scrollContainer>` in React JSX.
927
- */
928
- addChild<T extends Container>(...children: T[]): T;
929
- removeChild<T extends Container>(...children: T[]): T;
930
- /** React reconciler update hook */
931
- updateConfig(changed: Record<string, any>): void;
932
- /** Enable mouse wheel scrolling (call after adding to stage) */
933
- enableWheel(canvas: HTMLCanvasElement): void;
934
- /** Set scrollable content. Replaces any existing items. */
935
- setContent(content: Container): void;
936
- /** Add a single item */
937
- addItem(child: Container): this;
938
- /** Remove all items */
939
- clearItems(): void;
940
- /** Get items */
941
- get items(): readonly Container[];
942
- /** Scroll to make a specific item index visible */
943
- scrollToItem(index: number): void;
944
- /** Current scroll position */
945
- get scrollPosition(): {
946
- x: number;
947
- y: number;
948
- };
949
- /** Resize the scroll viewport */
950
- setViewportSize(width: number, height: number): void;
951
- private layoutItems;
952
- private _onPointerDown;
953
- private _onPointerMove;
954
- private _onPointerUp;
955
- private startInertia;
956
- private stopInertia;
957
- private _inertiaTick;
958
- private _onWheel;
959
- private clampScroll;
960
- private updateScrollbar;
961
- destroy(options?: boolean | {
962
- children?: boolean;
963
- texture?: boolean;
964
- textureSource?: boolean;
965
- }): void;
966
- }
967
-
968
- interface SliderConfig {
969
- /** Minimum value (default: 0) */
970
- min?: number;
971
- /** Maximum value (default: 1) */
972
- max?: number;
973
- /** Step increment (0 = continuous, default: 0) */
974
- step?: number;
975
- /** Initial value (default: min) */
976
- value?: number;
977
- /** Track width in pixels (default: 200) */
978
- width?: number;
979
- /** Track height in pixels (default: 8) */
980
- height?: number;
981
- /** Corner radius for Graphics-based track/fill (default: 4) */
982
- borderRadius?: number;
983
- /** Track background color (ignored when trackView provided) */
984
- trackColor?: number;
985
- /** Fill bar color (ignored when fillView provided) */
986
- fillColor?: number;
987
- /** Handle radius (for Graphics-based handle, default: 12) */
988
- handleRadius?: number;
989
- /** Handle color (for Graphics-based handle, ignored when handleView provided) */
990
- handleColor?: number;
991
- /** Custom track background view */
992
- trackView?: ViewInput;
993
- /** Custom fill bar view */
994
- fillView?: ViewInput;
995
- /** Custom handle view */
996
- handleView?: ViewInput;
997
- /** Called when value changes during drag */
998
- onUpdate?: (value: number) => void;
999
- /** Called when drag ends */
1000
- onChange?: (value: number) => void;
1001
- }
1002
- /**
1003
- * Draggable slider with customizable track, fill, and handle views.
1004
- *
1005
- * @example
1006
- * ```ts
1007
- * const volume = new Slider({
1008
- * min: 0, max: 1, value: 0.5,
1009
- * width: 200, height: 8,
1010
- * fillColor: 0xffd700,
1011
- * onUpdate: (v) => console.log('Volume:', v),
1012
- * });
1013
- * ```
1014
- */
1015
- declare class Slider extends Container {
1016
- readonly __uiComponent: true;
1017
- private _track;
1018
- private _fill;
1019
- private _fillMask;
1020
- private _handle;
1021
- private _config;
1022
- private _value;
1023
- private _dragging;
1024
- onUpdate: ((value: number) => void) | null;
1025
- onChange: ((value: number) => void) | null;
1026
- constructor(config?: SliderConfig);
1027
- /** Current value */
1028
- get value(): number;
1029
- set value(v: number);
1030
- get min(): number;
1031
- get max(): number;
1032
- /** React reconciler update hook */
1033
- updateConfig(changed: Record<string, any>): void;
1034
- private _fraction;
1035
- private _applyStep;
1036
- private _updateVisuals;
1037
- private _valueFromPointer;
1038
- private _onPointerDown;
1039
- private _onPointerMove;
1040
- private _onPointerUp;
1041
- destroy(options?: boolean | {
1042
- children?: boolean;
1043
- texture?: boolean;
1044
- textureSource?: boolean;
1045
- }): void;
1046
- }
1047
-
1048
- interface ToggleConfig {
1049
- /** Initial state (default: false) */
1050
- value?: boolean;
1051
- /** Custom view for the ON state */
1052
- onView?: ViewInput;
1053
- /** Custom view for the OFF state */
1054
- offView?: ViewInput;
1055
- /** Width (for Graphics-based toggle, default: 52) */
1056
- width?: number;
1057
- /** Height (for Graphics-based toggle, default: 28) */
1058
- height?: number;
1059
- /** Track color when ON (ignored when custom views provided) */
1060
- onColor?: number;
1061
- /** Track color when OFF (ignored when custom views provided) */
1062
- offColor?: number;
1063
- /** Handle color (for Graphics-based toggle) */
1064
- handleColor?: number;
1065
- /** Handle radius (for Graphics-based toggle, default: auto) */
1066
- handleRadius?: number;
1067
- /** Animation duration in ms (default: 200) */
1068
- animationDuration?: number;
1069
- /** Called when value changes */
1070
- onChange?: (value: boolean) => void;
1071
- }
1072
- /**
1073
- * Toggle switch with two states.
1074
- *
1075
- * Supports custom ON/OFF views or auto-generated Graphics-based toggle.
1076
- * Click to toggle, or use `forceSwitch(value)` programmatically.
1077
- *
1078
- * @example
1079
- * ```ts
1080
- * const mute = new Toggle({
1081
- * value: false,
1082
- * onColor: 0x22cc22,
1083
- * onChange: (on) => audioManager.mute(!on),
1084
- * });
1085
- * ```
1086
- */
1087
- declare class Toggle extends Container {
1088
- readonly __uiComponent: true;
1089
- private _value;
1090
- private _onView;
1091
- private _offView;
1092
- private _handle;
1093
- private _trackGfx;
1094
- private _config;
1095
- private _useCustomViews;
1096
- onChange: ((value: boolean) => void) | null;
1097
- constructor(config?: ToggleConfig);
1098
- /** Current toggle state */
1099
- get value(): boolean;
1100
- set value(v: boolean);
1101
- /** Programmatically switch to a specific state with animation */
1102
- forceSwitch(value: boolean): void;
1103
- /** React reconciler update hook */
1104
- updateConfig(changed: Record<string, any>): void;
1105
- private _onTap;
1106
- private _animateToState;
1107
- private _drawTrack;
1108
- destroy(options?: boolean | {
1109
- children?: boolean;
1110
- texture?: boolean;
1111
- textureSource?: boolean;
1112
- }): void;
1113
- }
1114
-
1115
- export { BalanceDisplay, Button, FlexContainer, Label, LabelValue, Layout, Modal, Panel, ProgressBar, ScrollContainer, Slider, Toast, Toggle, WinDisplay, resolveView };
1116
- export type { AlignContent, AlignItems, AlignSelf, BalanceDisplayConfig, ButtonConfig, ButtonState, FlexContainerConfig, FlexDirection, FlexItemConfig, JustifyContent, LabelConfig, LabelValueAlign, LabelValueConfig, LayoutAlignment, LayoutAnchor, LayoutConfig, LayoutDirection, ModalConfig, PanelConfig, ProgressBarConfig, ScrollContainerConfig, ScrollDirection, SliderConfig, ToastConfig, ToastType, ToggleConfig, ViewInput, WinDisplayConfig };