@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/src/ui/Toast.ts DELETED
@@ -1,150 +0,0 @@
1
- import { Container, Graphics, Text } from 'pixi.js';
2
- import { Tween } from '../animation/Tween';
3
- import { Easing } from '../animation/Easing';
4
- import { resolveView } from './view';
5
- import type { ViewInput } from './view';
6
-
7
- export type ToastType = 'info' | 'success' | 'warning' | 'error';
8
-
9
- export interface ToastConfig {
10
- /** Auto-dismiss after this many ms (0 = manual dismiss only) */
11
- duration?: number;
12
- /** Toast position from bottom */
13
- bottomOffset?: number;
14
- /** Custom background view (string texture name, Texture, or Container). Sized to fit text. */
15
- backgroundView?: ViewInput;
16
- }
17
-
18
- const TOAST_COLORS: Record<ToastType, number> = {
19
- info: 0x3498db,
20
- success: 0x27ae60,
21
- warning: 0xf39c12,
22
- error: 0xe74c3c,
23
- };
24
-
25
- /**
26
- * Toast notification component for displaying transient messages.
27
- *
28
- * @example
29
- * ```ts
30
- * const toast = new Toast();
31
- * scene.container.addChild(toast);
32
- * await toast.show('Connection lost', 'error', 1920, 1080);
33
- * ```
34
- */
35
- export class Toast extends Container {
36
- readonly __uiComponent = true as const;
37
-
38
- private _bg: Container;
39
- private _customBg: boolean;
40
- private _text: Text;
41
- private _config: Required<Pick<ToastConfig, 'duration' | 'bottomOffset'>>;
42
- private _dismissPending = false;
43
-
44
- constructor(config: ToastConfig = {}) {
45
- super();
46
-
47
- this._config = {
48
- duration: config.duration ?? 3000,
49
- bottomOffset: config.bottomOffset ?? 60,
50
- };
51
-
52
- const customBg = resolveView(config.backgroundView);
53
- this._customBg = !!customBg;
54
- this._bg = customBg ?? new Graphics();
55
- this.addChild(this._bg);
56
-
57
- this._text = new Text({
58
- text: '',
59
- style: {
60
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
61
- fontSize: 16,
62
- fill: 0xffffff,
63
- },
64
- });
65
- this._text.anchor.set(0.5);
66
- this.addChild(this._text);
67
-
68
- this.visible = false;
69
- }
70
-
71
- /**
72
- * Show a toast message.
73
- */
74
- async show(
75
- message: string,
76
- type: ToastType = 'info',
77
- viewWidth?: number,
78
- viewHeight?: number,
79
- ): Promise<void> {
80
- // Cancel any pending dismiss
81
- Tween.killTweensOf(this);
82
- this._dismissPending = false;
83
-
84
- this._text.text = message;
85
-
86
- const padding = 20;
87
- const width = Math.max(200, this._text.width + padding * 2);
88
- const height = 44;
89
- const radius = 8;
90
-
91
- // Draw the background
92
- if (this._customBg) {
93
- this._bg.width = width;
94
- this._bg.height = height;
95
- this._bg.x = -width / 2;
96
- this._bg.y = -height / 2;
97
- } else {
98
- const g = this._bg as Graphics;
99
- g.clear();
100
- g.roundRect(-width / 2, -height / 2, width, height, radius);
101
- g.fill(TOAST_COLORS[type]);
102
- }
103
-
104
- // Position
105
- if (viewWidth && viewHeight) {
106
- this.x = viewWidth / 2;
107
- this.y = viewHeight - this._config.bottomOffset;
108
- }
109
-
110
- this.visible = true;
111
- this.alpha = 0;
112
- this.y += 20;
113
-
114
- await Tween.to(this, { alpha: 1, y: this.y - 20 }, 300, Easing.easeOutCubic);
115
-
116
- if (this._config.duration > 0) {
117
- this._dismissPending = true;
118
- await Tween.delay(this._config.duration);
119
- if (this._dismissPending) {
120
- this._dismissPending = false;
121
- await this.dismiss();
122
- }
123
- }
124
- }
125
-
126
- /**
127
- * Dismiss the toast.
128
- */
129
- async dismiss(): Promise<void> {
130
- if (!this.visible) return;
131
-
132
- this._dismissPending = false;
133
- Tween.killTweensOf(this);
134
-
135
- await Tween.to(this, { alpha: 0, y: this.y + 20 }, 200, Easing.easeInCubic);
136
- this.visible = false;
137
- }
138
-
139
- /** React reconciler update hook */
140
- updateConfig(changed: Record<string, any>): void {
141
- if ('duration' in changed) this._config.duration = changed.duration;
142
- if ('bottomOffset' in changed) this._config.bottomOffset = changed.bottomOffset;
143
- }
144
-
145
- override destroy(options?: boolean | { children?: boolean; texture?: boolean; textureSource?: boolean }): void {
146
- this._dismissPending = false;
147
- Tween.killTweensOf(this);
148
- super.destroy(options);
149
- }
150
- }
package/src/ui/Toggle.ts DELETED
@@ -1,201 +0,0 @@
1
- import { Container, Graphics } from 'pixi.js';
2
- import { Tween } from '../animation/Tween';
3
- import { resolveView } from './view';
4
- import type { ViewInput } from './view';
5
-
6
- export interface ToggleConfig {
7
- /** Initial state (default: false) */
8
- value?: boolean;
9
- /** Custom view for the ON state */
10
- onView?: ViewInput;
11
- /** Custom view for the OFF state */
12
- offView?: ViewInput;
13
- /** Width (for Graphics-based toggle, default: 52) */
14
- width?: number;
15
- /** Height (for Graphics-based toggle, default: 28) */
16
- height?: number;
17
- /** Track color when ON (ignored when custom views provided) */
18
- onColor?: number;
19
- /** Track color when OFF (ignored when custom views provided) */
20
- offColor?: number;
21
- /** Handle color (for Graphics-based toggle) */
22
- handleColor?: number;
23
- /** Handle radius (for Graphics-based toggle, default: auto) */
24
- handleRadius?: number;
25
- /** Animation duration in ms (default: 200) */
26
- animationDuration?: number;
27
-
28
- /** Called when value changes */
29
- onChange?: (value: boolean) => void;
30
- }
31
-
32
- /**
33
- * Toggle switch with two states.
34
- *
35
- * Supports custom ON/OFF views or auto-generated Graphics-based toggle.
36
- * Click to toggle, or use `forceSwitch(value)` programmatically.
37
- *
38
- * @example
39
- * ```ts
40
- * const mute = new Toggle({
41
- * value: false,
42
- * onColor: 0x22cc22,
43
- * onChange: (on) => audioManager.mute(!on),
44
- * });
45
- * ```
46
- */
47
- export class Toggle extends Container {
48
- readonly __uiComponent = true as const;
49
-
50
- private _value: boolean;
51
- private _onView: Container | null = null;
52
- private _offView: Container | null = null;
53
- private _handle: Container | null = null;
54
- private _trackGfx: Graphics | null = null;
55
- private _config: Required<Pick<ToggleConfig, 'width' | 'height' | 'onColor' | 'offColor' | 'handleColor' | 'handleRadius' | 'animationDuration'>>;
56
- private _useCustomViews: boolean;
57
-
58
- onChange: ((value: boolean) => void) | null = null;
59
-
60
- constructor(config: ToggleConfig = {}) {
61
- super();
62
-
63
- this._config = {
64
- width: config.width ?? 52,
65
- height: config.height ?? 28,
66
- onColor: config.onColor ?? 0x22cc22,
67
- offColor: config.offColor ?? 0x666666,
68
- handleColor: config.handleColor ?? 0xffffff,
69
- handleRadius: config.handleRadius ?? 0, // 0 = auto
70
- animationDuration: config.animationDuration ?? 200,
71
- };
72
-
73
- this._value = config.value ?? false;
74
- this.onChange = config.onChange ?? null;
75
-
76
- const customOn = resolveView(config.onView);
77
- const customOff = resolveView(config.offView);
78
- this._useCustomViews = !!(customOn || customOff);
79
-
80
- if (this._useCustomViews) {
81
- // Custom view mode: show/hide ON and OFF views
82
- if (customOn) {
83
- this._onView = customOn;
84
- this._onView.visible = this._value;
85
- this.addChild(this._onView);
86
- }
87
- if (customOff) {
88
- this._offView = customOff;
89
- this._offView.visible = !this._value;
90
- this.addChild(this._offView);
91
- }
92
- } else {
93
- // Graphics mode: track + sliding handle
94
- const { width, height, handleColor } = this._config;
95
- const handleRadius = this._config.handleRadius || (height / 2 - 3);
96
- this._config.handleRadius = handleRadius;
97
-
98
- this._trackGfx = new Graphics();
99
- this.addChild(this._trackGfx);
100
- this._drawTrack();
101
-
102
- const handle = new Graphics();
103
- handle.circle(0, 0, handleRadius).fill(handleColor);
104
- handle.y = height / 2;
105
- handle.x = this._value ? width - handleRadius - 3 : handleRadius + 3;
106
- this._handle = handle;
107
- this.addChild(handle);
108
- }
109
-
110
- // Interaction
111
- this.eventMode = 'static';
112
- this.cursor = 'pointer';
113
- this.on('pointertap', this._onTap, this);
114
- }
115
-
116
- /** Current toggle state */
117
- get value(): boolean {
118
- return this._value;
119
- }
120
-
121
- set value(v: boolean) {
122
- if (v === this._value) return;
123
- this.forceSwitch(v);
124
- }
125
-
126
- /** Programmatically switch to a specific state with animation */
127
- forceSwitch(value: boolean): void {
128
- this._value = value;
129
- this._animateToState();
130
- }
131
-
132
- /** React reconciler update hook */
133
- updateConfig(changed: Record<string, any>): void {
134
- if ('value' in changed) this.value = changed.value;
135
- if ('onChange' in changed) this.onChange = changed.onChange;
136
- if ('animationDuration' in changed) this._config.animationDuration = changed.animationDuration;
137
- }
138
-
139
- private _onTap(): void {
140
- this._value = !this._value;
141
- this._animateToState();
142
- this.onChange?.(this._value);
143
- }
144
-
145
- private _animateToState(): void {
146
- const duration = this._config.animationDuration;
147
-
148
- if (this._useCustomViews) {
149
- // Custom views: crossfade
150
- if (this._onView) {
151
- Tween.killTweensOf(this._onView);
152
- if (this._value) {
153
- this._onView.visible = true;
154
- Tween.to(this._onView, { alpha: 1 }, duration);
155
- } else {
156
- Tween.to(this._onView, { alpha: 0 }, duration).then(() => {
157
- if (this._onView) this._onView.visible = false;
158
- });
159
- }
160
- }
161
- if (this._offView) {
162
- Tween.killTweensOf(this._offView);
163
- if (!this._value) {
164
- this._offView.visible = true;
165
- Tween.to(this._offView, { alpha: 1 }, duration);
166
- } else {
167
- Tween.to(this._offView, { alpha: 0 }, duration).then(() => {
168
- if (this._offView) this._offView.visible = false;
169
- });
170
- }
171
- }
172
- } else {
173
- // Graphics mode: slide handle + recolor track
174
- this._drawTrack();
175
- if (this._handle) {
176
- const { width } = this._config;
177
- const handleRadius = this._config.handleRadius;
178
- const targetX = this._value ? width - handleRadius - 3 : handleRadius + 3;
179
- Tween.killTweensOf(this._handle);
180
- Tween.to(this._handle, { x: targetX }, duration);
181
- }
182
- }
183
- }
184
-
185
- private _drawTrack(): void {
186
- if (!this._trackGfx) return;
187
- const { width, height, onColor, offColor } = this._config;
188
- const radius = height / 2;
189
- this._trackGfx.clear();
190
- this._trackGfx.roundRect(0, 0, width, height, radius).fill(this._value ? onColor : offColor);
191
- }
192
-
193
- override destroy(options?: boolean | { children?: boolean; texture?: boolean; textureSource?: boolean }): void {
194
- this.off('pointertap', this._onTap, this);
195
- if (this._handle) Tween.killTweensOf(this._handle);
196
- if (this._onView) Tween.killTweensOf(this._onView);
197
- if (this._offView) Tween.killTweensOf(this._offView);
198
- this.onChange = null;
199
- super.destroy(options);
200
- }
201
- }
@@ -1,145 +0,0 @@
1
- import { Container } from 'pixi.js';
2
- import { Label } from './Label';
3
- import { Tween } from '../animation/Tween';
4
- import { Easing } from '../animation/Easing';
5
-
6
- export interface WinDisplayConfig {
7
- /** Text style overrides */
8
- style?: Record<string, unknown>;
9
- /** Currency code */
10
- currency?: string;
11
- /** Locale for number formatting */
12
- locale?: string;
13
- /** Countup duration in ms */
14
- countupDuration?: number;
15
- /** Scale pop animation on win */
16
- popScale?: number;
17
- }
18
-
19
- /**
20
- * Win amount display with countup animation.
21
- *
22
- * Shows a dramatic countup from 0 to the win amount, with optional
23
- * scale pop effect — typical of slot games. Uses engine Tween system.
24
- *
25
- * @example
26
- * ```ts
27
- * const winDisplay = new WinDisplay({ currency: 'USD' });
28
- * scene.container.addChild(winDisplay);
29
- * await winDisplay.showWin(150.50); // countup animation
30
- * winDisplay.hide();
31
- * ```
32
- */
33
- export class WinDisplay extends Container {
34
- readonly __uiComponent = true as const;
35
-
36
- private _label: Label;
37
- private _config: Required<Pick<WinDisplayConfig, 'currency' | 'locale' | 'countupDuration' | 'popScale'>>;
38
- /** Internal target for Tween countup */
39
- private _tweenTarget = { value: 0 };
40
-
41
- constructor(config: WinDisplayConfig = {}) {
42
- super();
43
-
44
- this._config = {
45
- currency: config.currency ?? 'USD',
46
- locale: config.locale ?? 'en-US',
47
- countupDuration: config.countupDuration ?? 1500,
48
- popScale: config.popScale ?? 1.2,
49
- };
50
-
51
- this._label = new Label({
52
- text: '',
53
- style: {
54
- fontSize: 48,
55
- fontWeight: 'bold',
56
- fill: 0xffd700,
57
- stroke: { color: 0x000000, width: 3 },
58
- ...(config.style as any),
59
- },
60
- });
61
- this.addChild(this._label);
62
-
63
- this.visible = false;
64
- }
65
-
66
- /**
67
- * Show a win with countup animation.
68
- *
69
- * @param amount - Win amount
70
- * @returns Promise that resolves when the animation completes
71
- */
72
- async showWin(amount: number): Promise<void> {
73
- this.visible = true;
74
- this.alpha = 1;
75
-
76
- // Cancel any running animation
77
- Tween.killTweensOf(this._tweenTarget);
78
- Tween.killTweensOf(this);
79
-
80
- // Setup countup
81
- this._tweenTarget.value = 0;
82
- this.scale.set(0.5);
83
-
84
- // Scale pop animation
85
- const scalePromise = Tween.to(
86
- this,
87
- { 'scale.x': 1, 'scale.y': 1 },
88
- 300,
89
- Easing.easeOutBack,
90
- );
91
-
92
- // Countup animation
93
- const countupPromise = Tween.to(
94
- this._tweenTarget,
95
- { value: amount },
96
- this._config.countupDuration,
97
- Easing.easeOutCubic,
98
- () => {
99
- this.displayAmount(this._tweenTarget.value);
100
- },
101
- );
102
-
103
- await Promise.all([scalePromise, countupPromise]);
104
-
105
- // Ensure final value is exact
106
- this.displayAmount(amount);
107
- this.scale.set(1);
108
- }
109
-
110
- /**
111
- * Skip the countup animation and show the final amount immediately.
112
- */
113
- skipCountup(amount: number): void {
114
- Tween.killTweensOf(this._tweenTarget);
115
- Tween.killTweensOf(this);
116
- this.displayAmount(amount);
117
- this.scale.set(1);
118
- }
119
-
120
- /**
121
- * Hide the win display.
122
- */
123
- hide(): void {
124
- Tween.killTweensOf(this._tweenTarget);
125
- Tween.killTweensOf(this);
126
- this.visible = false;
127
- this._label.text = '';
128
- }
129
-
130
- private displayAmount(amount: number): void {
131
- this._label.setCurrency(amount, this._config.currency, this._config.locale);
132
- }
133
-
134
- /** React reconciler update hook */
135
- updateConfig(changed: Record<string, any>): void {
136
- if ('currency' in changed) this._config.currency = changed.currency;
137
- if ('locale' in changed) this._config.locale = changed.locale;
138
- }
139
-
140
- override destroy(options?: boolean | { children?: boolean; texture?: boolean; textureSource?: boolean }): void {
141
- Tween.killTweensOf(this._tweenTarget);
142
- Tween.killTweensOf(this);
143
- super.destroy(options);
144
- }
145
- }
package/src/ui/index.ts DELETED
@@ -1,33 +0,0 @@
1
- // ─── View helpers ─────────────────────────────────────────
2
- export { resolveView } from './view';
3
- export type { ViewInput } from './view';
4
-
5
- // ─── Engine UI Components ─────────────────────────────────
6
- export { FlexContainer } from './FlexContainer';
7
- export type { FlexContainerConfig, FlexDirection, JustifyContent, AlignItems, AlignSelf, AlignContent, FlexItemConfig } from './FlexContainer';
8
- export { Button } from './Button';
9
- export type { ButtonConfig, ButtonState } from './Button';
10
- export { ProgressBar } from './ProgressBar';
11
- export type { ProgressBarConfig } from './ProgressBar';
12
- export { Label } from './Label';
13
- export type { LabelConfig } from './Label';
14
- export { LabelValue } from './LabelValue';
15
- export type { LabelValueConfig, LabelValueAlign } from './LabelValue';
16
- export { Panel } from './Panel';
17
- export type { PanelConfig } from './Panel';
18
- export { BalanceDisplay } from './BalanceDisplay';
19
- export type { BalanceDisplayConfig } from './BalanceDisplay';
20
- export { WinDisplay } from './WinDisplay';
21
- export type { WinDisplayConfig } from './WinDisplay';
22
- export { Modal } from './Modal';
23
- export type { ModalConfig } from './Modal';
24
- export { Toast } from './Toast';
25
- export type { ToastConfig, ToastType } from './Toast';
26
- export { Layout } from './Layout';
27
- export type { LayoutConfig, LayoutDirection, LayoutAlignment, LayoutAnchor } from './Layout';
28
- export { ScrollContainer } from './ScrollContainer';
29
- export type { ScrollContainerConfig, ScrollDirection } from './ScrollContainer';
30
- export { Slider } from './Slider';
31
- export type { SliderConfig } from './Slider';
32
- export { Toggle } from './Toggle';
33
- export type { ToggleConfig } from './Toggle';
package/src/ui/view.ts DELETED
@@ -1,28 +0,0 @@
1
- import { Container, Sprite, Texture } 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
- export type ViewInput = string | Texture | Container;
11
-
12
- /**
13
- * Resolve a ViewInput to a Container instance.
14
- *
15
- * @example
16
- * ```ts
17
- * resolveView('btn-idle') // → Sprite.from('btn-idle')
18
- * resolveView(someTexture) // → new Sprite(someTexture)
19
- * resolveView(myCustomContainer) // → myCustomContainer (as-is)
20
- * resolveView(undefined) // → null
21
- * ```
22
- */
23
- export function resolveView(input: ViewInput | undefined | null): Container | null {
24
- if (input == null) return null;
25
- if (typeof input === 'string') return Sprite.from(input);
26
- if (input instanceof Texture) return new Sprite(input);
27
- return input;
28
- }