canvasengine 2.0.0-beta.4 → 2.0.0-beta.40

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 (142) hide show
  1. package/dist/DebugRenderer-DgECR3yZ.js +172 -0
  2. package/dist/DebugRenderer-DgECR3yZ.js.map +1 -0
  3. package/dist/components/Button.d.ts +183 -0
  4. package/dist/components/Button.d.ts.map +1 -0
  5. package/dist/components/Canvas.d.ts +18 -0
  6. package/dist/components/Canvas.d.ts.map +1 -0
  7. package/dist/components/DOMElement.d.ts +44 -0
  8. package/dist/components/DOMElement.d.ts.map +1 -0
  9. package/dist/components/Graphic.d.ts +65 -0
  10. package/dist/components/Graphic.d.ts.map +1 -0
  11. package/dist/components/Joystick.d.ts +36 -0
  12. package/dist/components/Joystick.d.ts.map +1 -0
  13. package/dist/components/NineSliceSprite.d.ts +17 -0
  14. package/dist/components/NineSliceSprite.d.ts.map +1 -0
  15. package/dist/components/ParticleEmitter.d.ts +5 -0
  16. package/dist/components/ParticleEmitter.d.ts.map +1 -0
  17. package/dist/components/Scene.d.ts +2 -0
  18. package/dist/components/Scene.d.ts.map +1 -0
  19. package/dist/components/Text.d.ts +26 -0
  20. package/dist/components/Text.d.ts.map +1 -0
  21. package/dist/components/TilingSprite.d.ts +18 -0
  22. package/dist/components/TilingSprite.d.ts.map +1 -0
  23. package/dist/components/Video.d.ts +15 -0
  24. package/dist/components/Video.d.ts.map +1 -0
  25. package/dist/components/index.d.ts +18 -0
  26. package/dist/components/index.d.ts.map +1 -0
  27. package/dist/components/types/DisplayObject.d.ts +110 -0
  28. package/dist/components/types/DisplayObject.d.ts.map +1 -0
  29. package/dist/components/types/MouseEvent.d.ts +4 -0
  30. package/dist/components/types/MouseEvent.d.ts.map +1 -0
  31. package/dist/components/types/Spritesheet.d.ts +248 -0
  32. package/dist/components/types/Spritesheet.d.ts.map +1 -0
  33. package/dist/components/types/index.d.ts +5 -0
  34. package/dist/components/types/index.d.ts.map +1 -0
  35. package/dist/directives/Controls.d.ts +113 -0
  36. package/dist/directives/Controls.d.ts.map +1 -0
  37. package/dist/directives/ControlsBase.d.ts +198 -0
  38. package/dist/directives/ControlsBase.d.ts.map +1 -0
  39. package/dist/directives/Drag.d.ts +70 -0
  40. package/dist/directives/Drag.d.ts.map +1 -0
  41. package/dist/directives/Flash.d.ts +117 -0
  42. package/dist/directives/Flash.d.ts.map +1 -0
  43. package/dist/directives/GamepadControls.d.ts +225 -0
  44. package/dist/directives/GamepadControls.d.ts.map +1 -0
  45. package/dist/directives/JoystickControls.d.ts +172 -0
  46. package/dist/directives/JoystickControls.d.ts.map +1 -0
  47. package/dist/directives/KeyboardControls.d.ts +219 -0
  48. package/dist/directives/KeyboardControls.d.ts.map +1 -0
  49. package/dist/directives/Scheduler.d.ts +36 -0
  50. package/dist/directives/Scheduler.d.ts.map +1 -0
  51. package/dist/directives/Shake.d.ts +98 -0
  52. package/dist/directives/Shake.d.ts.map +1 -0
  53. package/dist/directives/Sound.d.ts +26 -0
  54. package/dist/directives/Sound.d.ts.map +1 -0
  55. package/dist/directives/Transition.d.ts +11 -0
  56. package/dist/directives/Transition.d.ts.map +1 -0
  57. package/dist/directives/ViewportCull.d.ts +12 -0
  58. package/dist/directives/ViewportCull.d.ts.map +1 -0
  59. package/dist/directives/ViewportFollow.d.ts +19 -0
  60. package/dist/directives/ViewportFollow.d.ts.map +1 -0
  61. package/dist/directives/index.d.ts +13 -0
  62. package/dist/directives/index.d.ts.map +1 -0
  63. package/dist/engine/animation.d.ts +73 -0
  64. package/dist/engine/animation.d.ts.map +1 -0
  65. package/dist/engine/bootstrap.d.ts +16 -0
  66. package/dist/engine/bootstrap.d.ts.map +1 -0
  67. package/dist/engine/directive.d.ts +14 -0
  68. package/dist/engine/directive.d.ts.map +1 -0
  69. package/dist/engine/reactive.d.ts +105 -0
  70. package/dist/engine/reactive.d.ts.map +1 -0
  71. package/dist/engine/signal.d.ts +72 -0
  72. package/dist/engine/signal.d.ts.map +1 -0
  73. package/dist/engine/trigger.d.ts +50 -0
  74. package/dist/engine/trigger.d.ts.map +1 -0
  75. package/dist/engine/utils.d.ts +90 -0
  76. package/dist/engine/utils.d.ts.map +1 -0
  77. package/dist/hooks/addContext.d.ts +2 -0
  78. package/dist/hooks/addContext.d.ts.map +1 -0
  79. package/dist/hooks/useProps.d.ts +42 -0
  80. package/dist/hooks/useProps.d.ts.map +1 -0
  81. package/dist/hooks/useRef.d.ts +5 -0
  82. package/dist/hooks/useRef.d.ts.map +1 -0
  83. package/dist/index-gb763Hyx.js +12560 -0
  84. package/dist/index-gb763Hyx.js.map +1 -0
  85. package/dist/index.d.ts +15 -1083
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.global.js +29 -0
  88. package/dist/index.global.js.map +1 -0
  89. package/dist/index.js +81 -3041
  90. package/dist/index.js.map +1 -1
  91. package/dist/utils/Ease.d.ts +17 -0
  92. package/dist/utils/Ease.d.ts.map +1 -0
  93. package/dist/utils/GlobalAssetLoader.d.ts +141 -0
  94. package/dist/utils/GlobalAssetLoader.d.ts.map +1 -0
  95. package/dist/utils/RadialGradient.d.ts +58 -0
  96. package/dist/utils/RadialGradient.d.ts.map +1 -0
  97. package/dist/utils/functions.d.ts +2 -0
  98. package/dist/utils/functions.d.ts.map +1 -0
  99. package/package.json +13 -7
  100. package/src/components/Button.ts +396 -0
  101. package/src/components/Canvas.ts +61 -45
  102. package/src/components/Container.ts +21 -2
  103. package/src/components/DOMContainer.ts +123 -0
  104. package/src/components/DOMElement.ts +421 -0
  105. package/src/components/DisplayObject.ts +350 -197
  106. package/src/components/Graphic.ts +200 -34
  107. package/src/components/Joystick.ts +361 -0
  108. package/src/components/Mesh.ts +222 -0
  109. package/src/components/NineSliceSprite.ts +4 -1
  110. package/src/components/ParticleEmitter.ts +12 -8
  111. package/src/components/Sprite.ts +306 -30
  112. package/src/components/Text.ts +125 -18
  113. package/src/components/Video.ts +110 -0
  114. package/src/components/Viewport.ts +59 -43
  115. package/src/components/index.ts +8 -2
  116. package/src/components/types/DisplayObject.ts +34 -0
  117. package/src/components/types/Spritesheet.ts +0 -118
  118. package/src/directives/Controls.ts +254 -0
  119. package/src/directives/ControlsBase.ts +266 -0
  120. package/src/directives/Drag.ts +357 -52
  121. package/src/directives/Flash.ts +409 -0
  122. package/src/directives/GamepadControls.ts +537 -0
  123. package/src/directives/JoystickControls.ts +396 -0
  124. package/src/directives/KeyboardControls.ts +66 -424
  125. package/src/directives/Shake.ts +282 -0
  126. package/src/directives/Sound.ts +94 -31
  127. package/src/directives/ViewportFollow.ts +35 -7
  128. package/src/directives/index.ts +12 -6
  129. package/src/engine/animation.ts +175 -21
  130. package/src/engine/bootstrap.ts +23 -3
  131. package/src/engine/directive.ts +2 -2
  132. package/src/engine/reactive.ts +780 -177
  133. package/src/engine/signal.ts +35 -4
  134. package/src/engine/trigger.ts +21 -4
  135. package/src/engine/utils.ts +19 -3
  136. package/src/hooks/useProps.ts +1 -1
  137. package/src/index.ts +4 -2
  138. package/src/utils/GlobalAssetLoader.ts +257 -0
  139. package/src/utils/functions.ts +7 -0
  140. package/testing/index.ts +12 -0
  141. package/tsconfig.json +17 -0
  142. package/vite.config.ts +39 -0
@@ -0,0 +1,396 @@
1
+ import { ControlsBase, Controls } from "./ControlsBase";
2
+
3
+ /**
4
+ * Joystick directions reported by the Joystick component
5
+ */
6
+ export type JoystickDirection =
7
+ | 'left'
8
+ | 'right'
9
+ | 'top'
10
+ | 'bottom'
11
+ | 'top_left'
12
+ | 'top_right'
13
+ | 'bottom_left'
14
+ | 'bottom_right';
15
+
16
+ /**
17
+ * Joystick change event payload
18
+ */
19
+ export interface JoystickChangeEvent {
20
+ angle: number;
21
+ direction: JoystickDirection;
22
+ power: number;
23
+ }
24
+
25
+ /**
26
+ * Joystick configuration interface
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const joystickConfig: JoystickConfig = {
31
+ * enabled: true,
32
+ * directionMapping: {
33
+ * 'top': 'up',
34
+ * 'bottom': 'down',
35
+ * 'left': 'left',
36
+ * 'right': 'right',
37
+ * 'top_left': ['up', 'left'],
38
+ * 'top_right': ['up', 'right'],
39
+ * 'bottom_left': ['down', 'left'],
40
+ * 'bottom_right': ['down', 'right']
41
+ * },
42
+ * moveInterval: 50,
43
+ * threshold: 0.1
44
+ * };
45
+ * ```
46
+ */
47
+ export interface JoystickConfig {
48
+ /** Whether joystick is enabled (default: true) */
49
+ enabled?: boolean;
50
+ /** Mapping of joystick direction names to control names (can be single string or array for diagonals) */
51
+ directionMapping?: {
52
+ [joystickDirection: string]: string | string[]; // e.g., 'top' -> 'up', 'top_left' -> ['up', 'left']
53
+ };
54
+ /** Interval in milliseconds for repeating movement actions (default: 50) */
55
+ moveInterval?: number;
56
+ /** Threshold for power value to trigger movement (default: 0.1) */
57
+ threshold?: number;
58
+ }
59
+
60
+ /**
61
+ * Default direction mapping
62
+ */
63
+ const DEFAULT_DIRECTION_MAPPING: { [direction: string]: string | string[] } = {
64
+ 'top': 'up',
65
+ 'bottom': 'down',
66
+ 'left': 'left',
67
+ 'right': 'right',
68
+ 'top_left': ['up', 'left'],
69
+ 'top_right': ['up', 'right'],
70
+ 'bottom_left': ['down', 'left'],
71
+ 'bottom_right': ['down', 'right']
72
+ };
73
+
74
+ /**
75
+ * Joystick input controls implementation
76
+ *
77
+ * Handles joystick input events from the Joystick component and maps them to control actions.
78
+ * Supports directional movement with configurable mappings, including diagonal directions.
79
+ *
80
+ * The joystick controls work by receiving change events from a Joystick component instance.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ * const joystickControls = new JoystickControls();
85
+ * joystickControls.setInputs({
86
+ * up: {
87
+ * repeat: true,
88
+ * bind: 'up',
89
+ * keyDown() {
90
+ * console.log('Up pressed');
91
+ * }
92
+ * }
93
+ * });
94
+ * joystickControls.updateJoystickConfig({
95
+ * enabled: true,
96
+ * directionMapping: {
97
+ * 'top': 'up'
98
+ * }
99
+ * });
100
+ * joystickControls.start();
101
+ *
102
+ * // Later, when joystick changes:
103
+ * joystickControls.handleJoystickChange({ angle: 90, direction: Direction.TOP, power: 0.8 });
104
+ * ```
105
+ */
106
+ export class JoystickControls extends ControlsBase {
107
+ private joystickEnabled: boolean = true;
108
+ private joystickConfig: JoystickConfig = {
109
+ enabled: true,
110
+ directionMapping: DEFAULT_DIRECTION_MAPPING,
111
+ moveInterval: 50,
112
+ threshold: 0.1
113
+ };
114
+ private joystickMoving: boolean = false;
115
+ private joystickDirections: { [direction: string]: boolean } = {};
116
+ private joystickLastUpdate: number = 0;
117
+ private joystickMoveInterval: any = null;
118
+ private currentPower: number = 0;
119
+
120
+ /**
121
+ * Setup joystick event listeners
122
+ * Note: Joystick events are handled via handleJoystickChange() method
123
+ */
124
+ protected setupListeners(): void {
125
+ // Joystick events are handled externally via handleJoystickChange()
126
+ // This method is kept for consistency with ControlsBase interface
127
+ }
128
+
129
+ /**
130
+ * Cleanup joystick intervals
131
+ */
132
+ protected cleanup(): void {
133
+ if (this.joystickMoveInterval) {
134
+ clearInterval(this.joystickMoveInterval);
135
+ this.joystickMoveInterval = null;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Process joystick inputs each step
141
+ * Continuous actions are handled by the interval; no inactivity timeout here.
142
+ */
143
+ protected preStep(): void {
144
+ if (this.stop) return;
145
+ // No-op: continuous movement is driven by processJoystickMovement interval
146
+ }
147
+
148
+ /**
149
+ * Handle joystick change event
150
+ * Called by the Joystick component when its position changes
151
+ *
152
+ * @param event - Joystick change event containing angle, direction, and power
153
+ */
154
+ handleJoystickChange(event: JoystickChangeEvent): void {
155
+ if (!this.joystickEnabled || !this.joystickConfig.enabled) return;
156
+ if (this.stop) return;
157
+
158
+ this.joystickLastUpdate = Date.now();
159
+ this.currentPower = event.power;
160
+
161
+ // Check threshold
162
+ if (event.power < (this.joystickConfig.threshold || 0.1)) {
163
+ // Power too low, stop all movements
164
+ this.stopAllMovements();
165
+ return;
166
+ }
167
+
168
+ const directionMapping = this.joystickConfig.directionMapping || DEFAULT_DIRECTION_MAPPING;
169
+ const directionKey = event.direction;
170
+ const mappedControls = directionMapping[directionKey];
171
+
172
+ if (!mappedControls) {
173
+ // No mapping for this direction, stop all movements
174
+ this.stopAllMovements();
175
+ return;
176
+ }
177
+
178
+ // Convert to array if single string
179
+ const controlNames = Array.isArray(mappedControls) ? mappedControls : [mappedControls];
180
+
181
+ // Determine which directions to activate and deactivate
182
+ const previousDirections = this.joystickDirections;
183
+ const newDirections: { [dir: string]: boolean } = {};
184
+ controlNames.forEach(controlName => {
185
+ newDirections[controlName] = true;
186
+ });
187
+
188
+ // Deactivate directions that are no longer active
189
+ const allDirections = new Set([
190
+ ...Object.keys(this.joystickDirections),
191
+ ...Object.keys(newDirections)
192
+ ]);
193
+
194
+ for (const dir of allDirections) {
195
+ const wasActive = this.joystickDirections[dir];
196
+ const shouldBeActive = newDirections[dir] || false;
197
+
198
+ if (wasActive && !shouldBeActive) {
199
+ // Deactivate this direction
200
+ this.applyControl(dir, false).catch(() => {
201
+ // Ignore errors
202
+ });
203
+ }
204
+ }
205
+
206
+ // Update active directions
207
+ this.joystickDirections = { ...newDirections };
208
+ this.joystickMoving = true;
209
+
210
+ // Activate new directions
211
+ const directionsToActivate = controlNames.filter((name) => !previousDirections[name]);
212
+ for (const controlName of directionsToActivate) {
213
+ this.applyControl(controlName, true, { power: event.power }).catch(() => {
214
+ // Ignore errors
215
+ });
216
+ }
217
+
218
+ // Start movement interval if not already running
219
+ if (!this.joystickMoveInterval) {
220
+ this.joystickMoveInterval = setInterval(() => {
221
+ this.processJoystickMovement();
222
+ }, this.joystickConfig.moveInterval || 50);
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Handle joystick start event
228
+ * Called when user starts interacting with the joystick
229
+ */
230
+ handleJoystickStart(): void {
231
+ if (!this.joystickEnabled || !this.joystickConfig.enabled) return;
232
+ if (this.stop) return;
233
+ // Start event doesn't need special handling, change event will handle activation
234
+ }
235
+
236
+ /**
237
+ * Handle joystick end event
238
+ * Called when user stops interacting with the joystick
239
+ */
240
+ handleJoystickEnd(): void {
241
+ if (!this.joystickEnabled || !this.joystickConfig.enabled) return;
242
+ this.stopAllMovements();
243
+ }
244
+
245
+ /**
246
+ * Stop all active joystick movements
247
+ */
248
+ private stopAllMovements(): void {
249
+ if (this.joystickMoveInterval) {
250
+ clearInterval(this.joystickMoveInterval);
251
+ this.joystickMoveInterval = null;
252
+ }
253
+
254
+ const allDirections = Object.keys(this.joystickDirections);
255
+ for (const dir of allDirections) {
256
+ this.applyControl(dir, false).catch(() => {
257
+ // Ignore errors
258
+ });
259
+ }
260
+
261
+ this.joystickDirections = {};
262
+ this.joystickMoving = false;
263
+ this.currentPower = 0;
264
+ }
265
+
266
+ /**
267
+ * Process continuous joystick movement
268
+ * Called at intervals to repeat movement actions while joystick is active
269
+ */
270
+ private processJoystickMovement(): void {
271
+ if (!this.joystickMoving) return;
272
+ if (this.stop) return;
273
+
274
+ for (const direction in this.joystickDirections) {
275
+ if (this.joystickDirections[direction]) {
276
+ this.applyControl(direction, true, { power: this.currentPower }).catch(() => {
277
+ // Ignore errors
278
+ });
279
+ }
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Update joystick configuration
285
+ * Merges provided config with defaults
286
+ *
287
+ * @param config - Partial joystick configuration
288
+ */
289
+ updateJoystickConfig(config: Partial<JoystickConfig>): void {
290
+ this.joystickConfig = {
291
+ enabled: config.enabled !== undefined ? config.enabled : true,
292
+ directionMapping: config.directionMapping || DEFAULT_DIRECTION_MAPPING,
293
+ moveInterval: config.moveInterval || 50,
294
+ threshold: config.threshold || 0.1
295
+ };
296
+ }
297
+
298
+ /**
299
+ * Extract joystick config from controls configuration and update
300
+ *
301
+ * @param inputs - Controls configuration that may contain a 'joystick' property
302
+ */
303
+ extractJoystickConfig(inputs: Controls & { joystick?: JoystickConfig }): void {
304
+ if (inputs.joystick) {
305
+ this.updateJoystickConfig(inputs.joystick);
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Get the current joystick configuration
311
+ *
312
+ * @returns The joystick configuration object
313
+ */
314
+ getJoystickConfig(): JoystickConfig {
315
+ return this.joystickConfig;
316
+ }
317
+
318
+ /**
319
+ * Apply a control action programmatically
320
+ * Uses the bound controls to trigger actions
321
+ *
322
+ * @param controlName - Name of the control
323
+ * @param isDown - Whether the control is pressed (true) or released (false)
324
+ * @returns Promise that resolves when the action is complete
325
+ */
326
+ async applyControl(controlName: string | number, isDown?: boolean, payload?: any): Promise<void> {
327
+ const control = this._controlsOptions[controlName];
328
+ if (!control) return;
329
+
330
+ // Find the bound key for this control
331
+ const boundKeys = Object.keys(this.boundKeys);
332
+ for (const keyName of boundKeys) {
333
+ const boundKey = this.boundKeys[keyName];
334
+ if (boundKey.actionName === String(controlName)) {
335
+ // Execute the control callback
336
+ if (isDown === undefined) {
337
+ // Press and release (simulate button press)
338
+ if (boundKey.options.keyDown) {
339
+ let parameters = payload ?? boundKey.parameters;
340
+ if (typeof parameters === "function") {
341
+ parameters = parameters();
342
+ }
343
+ boundKey.options.keyDown(boundKey, parameters);
344
+ }
345
+ // Release after a short delay (similar to keyboard)
346
+ return new Promise((resolve) => {
347
+ setTimeout(() => {
348
+ if (boundKey.options.keyUp) {
349
+ let parameters = payload ?? boundKey.parameters;
350
+ if (typeof parameters === "function") {
351
+ parameters = parameters();
352
+ }
353
+ boundKey.options.keyUp(boundKey, parameters);
354
+ }
355
+ resolve();
356
+ }, 200);
357
+ });
358
+ } else if (isDown) {
359
+ if (boundKey.options.keyDown) {
360
+ let parameters = payload ?? boundKey.parameters;
361
+ if (typeof parameters === "function") {
362
+ parameters = parameters();
363
+ }
364
+ boundKey.options.keyDown(boundKey, parameters);
365
+ }
366
+ } else {
367
+ if (boundKey.options.keyUp) {
368
+ let parameters = payload ?? boundKey.parameters;
369
+ if (typeof parameters === "function") {
370
+ parameters = parameters();
371
+ }
372
+ boundKey.options.keyUp(boundKey, parameters);
373
+ }
374
+ }
375
+ break;
376
+ }
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Override setInputs to extract joystick config
382
+ */
383
+ setInputs(inputs: Controls & { joystick?: JoystickConfig }): void {
384
+ super.setInputs(inputs);
385
+ this.extractJoystickConfig(inputs);
386
+ }
387
+
388
+ /**
389
+ * Check if joystick is currently active
390
+ *
391
+ * @returns true if joystick is moving, false otherwise
392
+ */
393
+ isActive(): boolean {
394
+ return this.joystickMoving;
395
+ }
396
+ }