@al8b/input 0.1.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 (56) hide show
  1. package/README.md +25 -0
  2. package/dist/core/input-manager.d.mts +25 -0
  3. package/dist/core/input-manager.d.ts +25 -0
  4. package/dist/core/input-manager.js +724 -0
  5. package/dist/core/input-manager.js.map +1 -0
  6. package/dist/core/input-manager.mjs +701 -0
  7. package/dist/core/input-manager.mjs.map +1 -0
  8. package/dist/devices/gamepad.d.mts +24 -0
  9. package/dist/devices/gamepad.d.ts +24 -0
  10. package/dist/devices/gamepad.js +244 -0
  11. package/dist/devices/gamepad.js.map +1 -0
  12. package/dist/devices/gamepad.mjs +221 -0
  13. package/dist/devices/gamepad.mjs.map +1 -0
  14. package/dist/devices/keyboard.d.mts +16 -0
  15. package/dist/devices/keyboard.d.ts +16 -0
  16. package/dist/devices/keyboard.js +131 -0
  17. package/dist/devices/keyboard.js.map +1 -0
  18. package/dist/devices/keyboard.mjs +106 -0
  19. package/dist/devices/keyboard.mjs.map +1 -0
  20. package/dist/devices/mouse.d.mts +21 -0
  21. package/dist/devices/mouse.d.ts +21 -0
  22. package/dist/devices/mouse.js +207 -0
  23. package/dist/devices/mouse.js.map +1 -0
  24. package/dist/devices/mouse.mjs +182 -0
  25. package/dist/devices/mouse.mjs.map +1 -0
  26. package/dist/devices/touch.d.mts +22 -0
  27. package/dist/devices/touch.d.ts +22 -0
  28. package/dist/devices/touch.js +186 -0
  29. package/dist/devices/touch.js.map +1 -0
  30. package/dist/devices/touch.mjs +161 -0
  31. package/dist/devices/touch.mjs.map +1 -0
  32. package/dist/index.d.mts +6 -0
  33. package/dist/index.d.ts +6 -0
  34. package/dist/index.js +735 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/index.mjs +706 -0
  37. package/dist/index.mjs.map +1 -0
  38. package/dist/shared/constants.d.mts +6 -0
  39. package/dist/shared/constants.d.ts +6 -0
  40. package/dist/shared/constants.js +40 -0
  41. package/dist/shared/constants.js.map +1 -0
  42. package/dist/shared/constants.mjs +12 -0
  43. package/dist/shared/constants.mjs.map +1 -0
  44. package/dist/shared/utils.d.mts +9 -0
  45. package/dist/shared/utils.d.ts +9 -0
  46. package/dist/shared/utils.js +56 -0
  47. package/dist/shared/utils.js.map +1 -0
  48. package/dist/shared/utils.mjs +29 -0
  49. package/dist/shared/utils.mjs.map +1 -0
  50. package/dist/types/index.d.mts +41 -0
  51. package/dist/types/index.d.ts +41 -0
  52. package/dist/types/index.js +19 -0
  53. package/dist/types/index.js.map +1 -0
  54. package/dist/types/index.mjs +1 -0
  55. package/dist/types/index.mjs.map +1 -0
  56. package/package.json +34 -0
package/dist/index.js ADDED
@@ -0,0 +1,735 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ GamepadInput: () => GamepadInput,
25
+ Input: () => Input,
26
+ KeyboardInput: () => KeyboardInput,
27
+ MouseInput: () => MouseInput,
28
+ TouchInput: () => TouchInput,
29
+ default: () => Input
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/core/input-manager.ts
34
+ var import_diagnostics = require("@al8b/diagnostics");
35
+
36
+ // src/devices/gamepad.ts
37
+ var createState = /* @__PURE__ */ __name(() => ({
38
+ press: {},
39
+ release: {}
40
+ }), "createState");
41
+ var BUTTONS_MAP = {
42
+ 0: "A",
43
+ 1: "B",
44
+ 2: "X",
45
+ 3: "Y",
46
+ 4: "LB",
47
+ 5: "RB",
48
+ 8: "VIEW",
49
+ 9: "MENU",
50
+ 10: "LS",
51
+ 11: "RS",
52
+ 12: "DPAD_UP",
53
+ 13: "DPAD_DOWN",
54
+ 14: "DPAD_LEFT",
55
+ 15: "DPAD_RIGHT"
56
+ };
57
+ var TRIGGERS_MAP = {
58
+ 6: "LT",
59
+ 7: "RT"
60
+ };
61
+ var ensureState = /* @__PURE__ */ __name((state) => {
62
+ if (!state) {
63
+ return createState();
64
+ }
65
+ state.press ??= {};
66
+ state.release ??= {};
67
+ return state;
68
+ }, "ensureState");
69
+ var GamepadInput = class {
70
+ static {
71
+ __name(this, "GamepadInput");
72
+ }
73
+ status;
74
+ previous;
75
+ count = 0;
76
+ constructor() {
77
+ this.status = createState();
78
+ this.previous = {
79
+ global: createState()
80
+ };
81
+ }
82
+ update() {
83
+ const pads = this.getGamepads();
84
+ if (!pads) {
85
+ this.count = 0;
86
+ return;
87
+ }
88
+ let padCount = 0;
89
+ for (let i = 0; i < pads.length; i++) {
90
+ const pad = pads[i];
91
+ if (!pad) {
92
+ break;
93
+ }
94
+ padCount++;
95
+ this.status[i] = ensureState(this.status[i]);
96
+ this.previous[i] = ensureState(this.previous[i]);
97
+ for (const [index, name] of Object.entries(BUTTONS_MAP)) {
98
+ const idx = Number(index);
99
+ const button = pad.buttons[idx];
100
+ if (button) {
101
+ this.status[i][name] = button.pressed ? 1 : 0;
102
+ }
103
+ }
104
+ for (const [index, name] of Object.entries(TRIGGERS_MAP)) {
105
+ const idx = Number(index);
106
+ const trigger = pad.buttons[idx];
107
+ if (trigger) {
108
+ this.status[i][name] = trigger.value ?? 0;
109
+ }
110
+ }
111
+ if (pad.axes.length >= 2) {
112
+ this.updateStick(pad.axes[0], -pad.axes[1], this.status[i], "LEFT");
113
+ }
114
+ if (pad.axes.length >= 4) {
115
+ this.updateStick(pad.axes[2], -pad.axes[3], this.status[i], "RIGHT");
116
+ }
117
+ }
118
+ this.aggregateStatus(pads, padCount);
119
+ this.count = padCount;
120
+ this.updateChanges(this.status, this.previous.global);
121
+ for (let i = 0; i < padCount; i++) {
122
+ this.updateChanges(this.status[i], this.previous[i]);
123
+ }
124
+ for (let i = padCount; i < 4; i++) {
125
+ delete this.status[i];
126
+ delete this.previous[i];
127
+ }
128
+ }
129
+ getGamepads() {
130
+ if (typeof navigator === "undefined" || !navigator.getGamepads) {
131
+ return null;
132
+ }
133
+ try {
134
+ return navigator.getGamepads();
135
+ } catch {
136
+ return null;
137
+ }
138
+ }
139
+ updateStick(x, y, target, prefix) {
140
+ const radius = Math.sqrt(x * x + y * y);
141
+ const angle = Math.floor((Math.atan2(y, x) + Math.PI * 2) % (Math.PI * 2) / (Math.PI * 2) * 360);
142
+ target[`${prefix}_STICK_ANGLE`] = angle;
143
+ target[`${prefix}_STICK_AMOUNT`] = radius;
144
+ target[`${prefix}_STICK_UP`] = y > 0.5 ? 1 : 0;
145
+ target[`${prefix}_STICK_DOWN`] = y < -0.5 ? 1 : 0;
146
+ target[`${prefix}_STICK_LEFT`] = x < -0.5 ? 1 : 0;
147
+ target[`${prefix}_STICK_RIGHT`] = x > 0.5 ? 1 : 0;
148
+ }
149
+ aggregateStatus(pads, padCount) {
150
+ for (const [index, name] of Object.entries(BUTTONS_MAP)) {
151
+ this.status[name] = 0;
152
+ const idx = Number(index);
153
+ for (const pad of pads) {
154
+ if (!pad) break;
155
+ if (pad.buttons[idx]?.pressed) {
156
+ this.status[name] = 1;
157
+ break;
158
+ }
159
+ }
160
+ }
161
+ for (const [index, name] of Object.entries(TRIGGERS_MAP)) {
162
+ this.status[name] = 0;
163
+ const idx = Number(index);
164
+ for (const pad of pads) {
165
+ if (!pad) break;
166
+ const button = pad.buttons[idx];
167
+ if (button) {
168
+ this.status[name] = button.value ?? 0;
169
+ }
170
+ }
171
+ }
172
+ this.status.UP = 0;
173
+ this.status.DOWN = 0;
174
+ this.status.LEFT = 0;
175
+ this.status.RIGHT = 0;
176
+ this.status.LEFT_STICK_UP = 0;
177
+ this.status.LEFT_STICK_DOWN = 0;
178
+ this.status.LEFT_STICK_LEFT = 0;
179
+ this.status.LEFT_STICK_RIGHT = 0;
180
+ this.status.RIGHT_STICK_UP = 0;
181
+ this.status.RIGHT_STICK_DOWN = 0;
182
+ this.status.RIGHT_STICK_LEFT = 0;
183
+ this.status.RIGHT_STICK_RIGHT = 0;
184
+ this.status.LEFT_STICK_ANGLE = 0;
185
+ this.status.LEFT_STICK_AMOUNT = 0;
186
+ this.status.RIGHT_STICK_ANGLE = 0;
187
+ this.status.RIGHT_STICK_AMOUNT = 0;
188
+ this.status.RT = 0;
189
+ this.status.LT = 0;
190
+ for (let i = 0; i < padCount; i++) {
191
+ const padState = this.status[i];
192
+ if (!padState) continue;
193
+ padState.UP = padState.DPAD_UP || padState.LEFT_STICK_UP || padState.RIGHT_STICK_UP || 0 ? 1 : 0;
194
+ padState.DOWN = padState.DPAD_DOWN || padState.LEFT_STICK_DOWN || padState.RIGHT_STICK_DOWN || 0 ? 1 : 0;
195
+ padState.LEFT = padState.DPAD_LEFT || padState.LEFT_STICK_LEFT || padState.RIGHT_STICK_LEFT || 0 ? 1 : 0;
196
+ padState.RIGHT = padState.DPAD_RIGHT || padState.LEFT_STICK_RIGHT || padState.RIGHT_STICK_RIGHT || 0 ? 1 : 0;
197
+ if (padState.UP) this.status.UP = 1;
198
+ if (padState.DOWN) this.status.DOWN = 1;
199
+ if (padState.LEFT) this.status.LEFT = 1;
200
+ if (padState.RIGHT) this.status.RIGHT = 1;
201
+ if (padState.LEFT_STICK_UP) this.status.LEFT_STICK_UP = 1;
202
+ if (padState.LEFT_STICK_DOWN) this.status.LEFT_STICK_DOWN = 1;
203
+ if (padState.LEFT_STICK_LEFT) this.status.LEFT_STICK_LEFT = 1;
204
+ if (padState.LEFT_STICK_RIGHT) this.status.LEFT_STICK_RIGHT = 1;
205
+ if (padState.RIGHT_STICK_UP) this.status.RIGHT_STICK_UP = 1;
206
+ if (padState.RIGHT_STICK_DOWN) this.status.RIGHT_STICK_DOWN = 1;
207
+ if (padState.RIGHT_STICK_LEFT) this.status.RIGHT_STICK_LEFT = 1;
208
+ if (padState.RIGHT_STICK_RIGHT) this.status.RIGHT_STICK_RIGHT = 1;
209
+ if (padState.LT) this.status.LT = padState.LT;
210
+ if (padState.RT) this.status.RT = padState.RT;
211
+ if ((padState.LEFT_STICK_AMOUNT ?? 0) > (this.status.LEFT_STICK_AMOUNT ?? 0)) {
212
+ this.status.LEFT_STICK_AMOUNT = padState.LEFT_STICK_AMOUNT;
213
+ this.status.LEFT_STICK_ANGLE = padState.LEFT_STICK_ANGLE;
214
+ }
215
+ if ((padState.RIGHT_STICK_AMOUNT ?? 0) > (this.status.RIGHT_STICK_AMOUNT ?? 0)) {
216
+ this.status.RIGHT_STICK_AMOUNT = padState.RIGHT_STICK_AMOUNT;
217
+ this.status.RIGHT_STICK_ANGLE = padState.RIGHT_STICK_ANGLE;
218
+ }
219
+ }
220
+ }
221
+ updateChanges(current, previous) {
222
+ for (const key in current.press) {
223
+ current.press[key] = 0;
224
+ }
225
+ for (const key in current.release) {
226
+ current.release[key] = 0;
227
+ }
228
+ for (const key in previous) {
229
+ if (key === "press" || key === "release") continue;
230
+ if (previous[key] && !current[key]) {
231
+ current.release[key] = 1;
232
+ }
233
+ }
234
+ for (const key in current) {
235
+ if (key === "press" || key === "release") continue;
236
+ if (current[key] && !previous[key]) {
237
+ current.press[key] = 1;
238
+ }
239
+ }
240
+ for (const key in previous) {
241
+ if (key === "press" || key === "release") continue;
242
+ previous[key] = 0;
243
+ }
244
+ for (const key in current) {
245
+ if (key === "press" || key === "release") continue;
246
+ previous[key] = current[key];
247
+ }
248
+ }
249
+ };
250
+
251
+ // src/shared/constants.ts
252
+ var NORMALIZED_SCALE = 200;
253
+ var OUT_OF_BOUNDS = -1e4;
254
+ var PREVENT_DEFAULT_REGEX = /Escape|(F\d+)/;
255
+ var TOUCH_MOUSE_ID = "mouse";
256
+
257
+ // src/shared/utils.ts
258
+ var hasDocument = typeof document !== "undefined";
259
+ var computeRelativePosition = /* @__PURE__ */ __name((canvas, clientX, clientY) => {
260
+ const rect = canvas.getBoundingClientRect();
261
+ const min = Math.min(canvas.clientWidth, canvas.clientHeight) || 1;
262
+ const x = (clientX - rect.left - canvas.clientWidth / 2) / min * NORMALIZED_SCALE;
263
+ const y = (canvas.clientHeight / 2 - (clientY - rect.top)) / min * NORMALIZED_SCALE;
264
+ return {
265
+ x,
266
+ y
267
+ };
268
+ }, "computeRelativePosition");
269
+
270
+ // src/devices/keyboard.ts
271
+ var KeyboardInput = class {
272
+ static {
273
+ __name(this, "KeyboardInput");
274
+ }
275
+ state = {
276
+ press: {},
277
+ release: {},
278
+ UP: 0,
279
+ DOWN: 0,
280
+ LEFT: 0,
281
+ RIGHT: 0
282
+ };
283
+ previous = {};
284
+ // Track only keys that changed since last update() — avoids O(n) iteration of all keys
285
+ dirtyKeys = /* @__PURE__ */ new Set();
286
+ constructor(target = hasDocument ? document : void 0) {
287
+ if (!target) {
288
+ return;
289
+ }
290
+ target.addEventListener("keydown", (event) => this.handleKeyDown(event));
291
+ target.addEventListener("keyup", (event) => this.handleKeyUp(event));
292
+ }
293
+ convertCode(code) {
294
+ let res = "";
295
+ let low = false;
296
+ for (let i = 0; i < code.length; i++) {
297
+ const c = code.charAt(i);
298
+ if (c === c.toUpperCase() && low) {
299
+ res += "_";
300
+ low = false;
301
+ } else {
302
+ low = true;
303
+ }
304
+ res += c.toUpperCase();
305
+ }
306
+ return res;
307
+ }
308
+ handleKeyDown(event) {
309
+ if (!(event.altKey || event.ctrlKey || event.metaKey || PREVENT_DEFAULT_REGEX.test(event.key))) {
310
+ event.preventDefault();
311
+ }
312
+ const codeKey = this.convertCode(event.code);
313
+ const upperKey = event.key.toUpperCase();
314
+ this.state[codeKey] = 1;
315
+ this.state[upperKey] = 1;
316
+ this.dirtyKeys.add(codeKey);
317
+ this.dirtyKeys.add(upperKey);
318
+ this.updateDirectional();
319
+ }
320
+ handleKeyUp(event) {
321
+ const codeKey = this.convertCode(event.code);
322
+ const upperKey = event.key.toUpperCase();
323
+ this.state[codeKey] = 0;
324
+ this.state[upperKey] = 0;
325
+ this.dirtyKeys.add(codeKey);
326
+ this.dirtyKeys.add(upperKey);
327
+ this.updateDirectional();
328
+ }
329
+ updateDirectional() {
330
+ this.state.UP = this.state.KEY_W || this.state.ARROW_UP || 0;
331
+ this.state.DOWN = this.state.KEY_S || this.state.ARROW_DOWN || 0;
332
+ this.state.LEFT = this.state.KEY_A || this.state.ARROW_LEFT || 0;
333
+ this.state.RIGHT = this.state.KEY_D || this.state.ARROW_RIGHT || 0;
334
+ }
335
+ update() {
336
+ for (const key of this.dirtyKeys) {
337
+ if (this.state.press[key]) this.state.press[key] = 0;
338
+ if (this.state.release[key]) this.state.release[key] = 0;
339
+ }
340
+ for (const key of this.dirtyKeys) {
341
+ const current = this.state[key];
342
+ const prev = this.previous[key] || 0;
343
+ if (current && !prev) {
344
+ this.state.press[key] = 1;
345
+ } else if (!current && prev) {
346
+ this.state.release[key] = 1;
347
+ }
348
+ this.previous[key] = current;
349
+ }
350
+ this.dirtyKeys.clear();
351
+ }
352
+ reset() {
353
+ for (const key in this.state) {
354
+ if (key === "press" || key === "release") continue;
355
+ this.state[key] = 0;
356
+ }
357
+ for (const key in this.previous) {
358
+ this.previous[key] = 0;
359
+ }
360
+ this.dirtyKeys.clear();
361
+ }
362
+ };
363
+
364
+ // src/devices/mouse.ts
365
+ var MouseInput = class {
366
+ static {
367
+ __name(this, "MouseInput");
368
+ }
369
+ state = {
370
+ x: OUT_OF_BOUNDS,
371
+ y: OUT_OF_BOUNDS,
372
+ pressed: 0,
373
+ left: 0,
374
+ middle: 0,
375
+ right: 0,
376
+ press: 0,
377
+ release: 0,
378
+ wheel: 0
379
+ };
380
+ previousPressed = false;
381
+ wheel = 0;
382
+ canvas;
383
+ removeListeners;
384
+ constructor(canvas) {
385
+ if (canvas) {
386
+ this.setCanvas(canvas);
387
+ }
388
+ }
389
+ setCanvas(canvas) {
390
+ this.detach();
391
+ this.canvas = canvas;
392
+ this.attach();
393
+ }
394
+ syncFromTouch(x, y, touching) {
395
+ this.state.x = x;
396
+ this.state.y = y;
397
+ if (touching) {
398
+ this.state.left = 1;
399
+ this.state.middle = 0;
400
+ this.state.right = 0;
401
+ this.state.pressed = 1;
402
+ } else {
403
+ this.state.left = 0;
404
+ this.state.middle = 0;
405
+ this.state.right = 0;
406
+ this.state.pressed = 0;
407
+ }
408
+ }
409
+ update() {
410
+ if (this.state.pressed && !this.previousPressed) {
411
+ this.previousPressed = true;
412
+ this.state.press = 1;
413
+ } else {
414
+ this.state.press = 0;
415
+ }
416
+ if (!this.state.pressed && this.previousPressed) {
417
+ this.previousPressed = false;
418
+ this.state.release = 1;
419
+ } else {
420
+ this.state.release = 0;
421
+ }
422
+ this.state.wheel = this.wheel;
423
+ this.wheel = 0;
424
+ }
425
+ attach() {
426
+ if (!hasDocument) {
427
+ return;
428
+ }
429
+ const target = document;
430
+ const onDown = /* @__PURE__ */ __name((event) => this.handleMouseDown(event), "onDown");
431
+ const onMove = /* @__PURE__ */ __name((event) => this.handleMouseMove(event), "onMove");
432
+ const onUp = /* @__PURE__ */ __name((event) => this.handleMouseUp(event), "onUp");
433
+ const onWheel = /* @__PURE__ */ __name((event) => this.handleWheel(event), "onWheel");
434
+ const onDomWheel = /* @__PURE__ */ __name((event) => this.handleWheel(event), "onDomWheel");
435
+ target.addEventListener("mousedown", onDown, {
436
+ passive: false
437
+ });
438
+ target.addEventListener("mousemove", onMove, {
439
+ passive: false
440
+ });
441
+ target.addEventListener("mouseup", onUp, {
442
+ passive: false
443
+ });
444
+ target.addEventListener("mousewheel", onWheel, {
445
+ passive: false
446
+ });
447
+ target.addEventListener("DOMMouseScroll", onDomWheel, {
448
+ passive: false
449
+ });
450
+ this.removeListeners = () => {
451
+ target.removeEventListener("mousedown", onDown);
452
+ target.removeEventListener("mousemove", onMove);
453
+ target.removeEventListener("mouseup", onUp);
454
+ target.removeEventListener("mousewheel", onWheel);
455
+ target.removeEventListener("DOMMouseScroll", onDomWheel);
456
+ };
457
+ }
458
+ detach() {
459
+ this.removeListeners?.();
460
+ this.removeListeners = void 0;
461
+ this.canvas = void 0;
462
+ }
463
+ handleMouseDown(event) {
464
+ if (!this.canvas) return;
465
+ event.preventDefault();
466
+ const { x, y } = computeRelativePosition(this.canvas, event.clientX, event.clientY);
467
+ this.state.x = x;
468
+ this.state.y = y;
469
+ switch (event.button) {
470
+ case 0:
471
+ this.state.left = 1;
472
+ break;
473
+ case 1:
474
+ this.state.middle = 1;
475
+ break;
476
+ case 2:
477
+ this.state.right = 1;
478
+ break;
479
+ }
480
+ this.state.pressed = Math.min(1, this.state.left + this.state.right + this.state.middle);
481
+ }
482
+ handleMouseMove(event) {
483
+ if (!this.canvas) return;
484
+ event.preventDefault();
485
+ const { x, y } = computeRelativePosition(this.canvas, event.clientX, event.clientY);
486
+ this.state.x = x;
487
+ this.state.y = y;
488
+ }
489
+ handleMouseUp(event) {
490
+ if (!this.canvas) return;
491
+ event.preventDefault();
492
+ const { x, y } = computeRelativePosition(this.canvas, event.clientX, event.clientY);
493
+ this.state.x = x;
494
+ this.state.y = y;
495
+ switch (event.button) {
496
+ case 0:
497
+ this.state.left = 0;
498
+ break;
499
+ case 1:
500
+ this.state.middle = 0;
501
+ break;
502
+ case 2:
503
+ this.state.right = 0;
504
+ break;
505
+ }
506
+ this.state.pressed = Math.min(1, this.state.left + this.state.right + this.state.middle);
507
+ }
508
+ handleWheel(event) {
509
+ const wheelEvent = event;
510
+ if (typeof wheelEvent.deltaY === "number" && wheelEvent.deltaY !== 0) {
511
+ this.wheel = wheelEvent.deltaY > 0 ? -1 : 1;
512
+ } else if (typeof wheelEvent.wheelDelta === "number" && wheelEvent.wheelDelta !== 0) {
513
+ this.wheel = wheelEvent.wheelDelta < 0 ? -1 : 1;
514
+ } else if (typeof wheelEvent.detail === "number" && wheelEvent.detail !== 0) {
515
+ this.wheel = wheelEvent.detail > 0 ? -1 : 1;
516
+ } else {
517
+ this.wheel = 0;
518
+ }
519
+ event.preventDefault();
520
+ }
521
+ };
522
+
523
+ // src/devices/touch.ts
524
+ var TouchInput = class {
525
+ static {
526
+ __name(this, "TouchInput");
527
+ }
528
+ mouse;
529
+ state = {
530
+ touching: 0,
531
+ x: 0,
532
+ y: 0,
533
+ press: 0,
534
+ release: 0,
535
+ touches: []
536
+ };
537
+ touches = /* @__PURE__ */ new Map();
538
+ previousTouching = false;
539
+ canvas;
540
+ removeListeners;
541
+ constructor(mouse, canvas) {
542
+ this.mouse = mouse;
543
+ if (canvas) {
544
+ this.setCanvas(canvas);
545
+ }
546
+ }
547
+ setCanvas(canvas) {
548
+ this.detach();
549
+ this.canvas = canvas;
550
+ this.attach();
551
+ }
552
+ update() {
553
+ this.syncMouseTouch();
554
+ const list = [];
555
+ for (const [id, { x, y }] of this.touches.entries()) {
556
+ list.push({
557
+ id,
558
+ x,
559
+ y
560
+ });
561
+ this.state.x = x;
562
+ this.state.y = y;
563
+ }
564
+ this.state.touches = list;
565
+ this.state.touching = this.touches.size > 0 ? 1 : 0;
566
+ if (this.state.touching && !this.previousTouching) {
567
+ this.previousTouching = true;
568
+ this.state.press = 1;
569
+ } else {
570
+ this.state.press = 0;
571
+ }
572
+ if (!this.state.touching && this.previousTouching) {
573
+ this.previousTouching = false;
574
+ this.state.release = 1;
575
+ } else {
576
+ this.state.release = 0;
577
+ }
578
+ }
579
+ syncMouseTouch() {
580
+ const mouseState = this.mouse.state;
581
+ if (mouseState.pressed) {
582
+ this.touches.set(TOUCH_MOUSE_ID, {
583
+ x: mouseState.x,
584
+ y: mouseState.y
585
+ });
586
+ } else {
587
+ this.touches.delete(TOUCH_MOUSE_ID);
588
+ }
589
+ }
590
+ attach() {
591
+ if (!hasDocument) return;
592
+ const onStart = /* @__PURE__ */ __name((event) => this.handleTouchStart(event), "onStart");
593
+ const onMove = /* @__PURE__ */ __name((event) => this.handleTouchMove(event), "onMove");
594
+ const onEnd = /* @__PURE__ */ __name((event) => this.handleTouchEnd(event), "onEnd");
595
+ document.addEventListener("touchstart", onStart, {
596
+ passive: false
597
+ });
598
+ document.addEventListener("touchmove", onMove, {
599
+ passive: false
600
+ });
601
+ document.addEventListener("touchend", onEnd, {
602
+ passive: false
603
+ });
604
+ document.addEventListener("touchcancel", onEnd, {
605
+ passive: false
606
+ });
607
+ this.removeListeners = () => {
608
+ document.removeEventListener("touchstart", onStart);
609
+ document.removeEventListener("touchmove", onMove);
610
+ document.removeEventListener("touchend", onEnd);
611
+ document.removeEventListener("touchcancel", onEnd);
612
+ };
613
+ }
614
+ detach() {
615
+ this.removeListeners?.();
616
+ this.removeListeners = void 0;
617
+ this.canvas = void 0;
618
+ this.touches.clear();
619
+ }
620
+ handleTouchStart(event) {
621
+ if (!this.canvas) return;
622
+ event.preventDefault();
623
+ event.stopPropagation();
624
+ for (let i = 0; i < event.changedTouches.length; i++) {
625
+ const t = event.changedTouches[i];
626
+ const { x, y } = computeRelativePosition(this.canvas, t.clientX, t.clientY);
627
+ this.touches.set(t.identifier, {
628
+ x,
629
+ y
630
+ });
631
+ this.mouse.syncFromTouch(x, y, true);
632
+ }
633
+ }
634
+ handleTouchMove(event) {
635
+ if (!this.canvas) return;
636
+ event.preventDefault();
637
+ event.stopPropagation();
638
+ for (let i = 0; i < event.changedTouches.length; i++) {
639
+ const t = event.changedTouches[i];
640
+ if (!this.touches.has(t.identifier)) continue;
641
+ const { x, y } = computeRelativePosition(this.canvas, t.clientX, t.clientY);
642
+ this.touches.set(t.identifier, {
643
+ x,
644
+ y
645
+ });
646
+ this.mouse.syncFromTouch(x, y, true);
647
+ }
648
+ }
649
+ handleTouchEnd(event) {
650
+ if (!this.canvas) return;
651
+ event.preventDefault();
652
+ event.stopPropagation();
653
+ for (let i = 0; i < event.changedTouches.length; i++) {
654
+ const t = event.changedTouches[i];
655
+ this.touches.delete(t.identifier);
656
+ }
657
+ this.mouse.syncFromTouch(this.state.x, this.state.y, false);
658
+ }
659
+ };
660
+
661
+ // src/core/input-manager.ts
662
+ var Input = class {
663
+ static {
664
+ __name(this, "Input");
665
+ }
666
+ keyboard;
667
+ mouse;
668
+ touch;
669
+ gamepad;
670
+ runtime;
671
+ constructor(canvas, runtime) {
672
+ this.runtime = runtime;
673
+ this.keyboard = new KeyboardInput();
674
+ this.mouse = new MouseInput(canvas);
675
+ this.touch = new TouchInput(this.mouse, canvas);
676
+ this.gamepad = new GamepadInput();
677
+ }
678
+ /**
679
+ * Poll all devices for state updates.
680
+ */
681
+ update() {
682
+ this.keyboard.update();
683
+ this.mouse.update();
684
+ this.touch.update();
685
+ this.gamepad.update();
686
+ }
687
+ getKeyboard() {
688
+ if (!this.keyboard || !this.keyboard.state) {
689
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7052, {
690
+ error: "Keyboard state not available"
691
+ });
692
+ return {};
693
+ }
694
+ return this.keyboard.state;
695
+ }
696
+ getMouse() {
697
+ if (!this.mouse || !this.mouse.state) {
698
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7052, {
699
+ error: "Mouse state not available"
700
+ });
701
+ return {};
702
+ }
703
+ return this.mouse.state;
704
+ }
705
+ getTouch() {
706
+ if (!this.touch || !this.touch.state) {
707
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7052, {
708
+ error: "Touch state not available"
709
+ });
710
+ return {};
711
+ }
712
+ return this.touch.state;
713
+ }
714
+ getGamepad() {
715
+ if (!this.gamepad || !navigator.getGamepads) {
716
+ (0, import_diagnostics.reportRuntimeError)(this.runtime?.listener, import_diagnostics.APIErrorCode.E7051, {
717
+ device: "gamepad"
718
+ });
719
+ }
720
+ return this.gamepad;
721
+ }
722
+ setCanvas(canvas) {
723
+ this.mouse.setCanvas(canvas);
724
+ this.touch.setCanvas(canvas);
725
+ }
726
+ };
727
+ // Annotate the CommonJS export names for ESM import in node:
728
+ 0 && (module.exports = {
729
+ GamepadInput,
730
+ Input,
731
+ KeyboardInput,
732
+ MouseInput,
733
+ TouchInput
734
+ });
735
+ //# sourceMappingURL=index.js.map