inpt 0.0.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.
- package/LICENSE.md +21 -0
- package/README.md +89 -0
- package/dist/index.js +1182 -0
- package/dist/types/core/BoundAction.d.ts +8 -0
- package/dist/types/core/Disposable.d.ts +11 -0
- package/dist/types/core/Input.d.ts +46 -0
- package/dist/types/core/InputManager.d.ts +179 -0
- package/dist/types/core/InputManagerEventMap.d.ts +26 -0
- package/dist/types/core/KeyCode.d.ts +7 -0
- package/dist/types/core/Modifier.d.ts +6 -0
- package/dist/types/core/PointerButton.d.ts +19 -0
- package/dist/types/core/PointerLockBehavior.d.ts +6 -0
- package/dist/types/core/WheelRotation.d.ts +30 -0
- package/dist/types/core/index.d.ts +10 -0
- package/dist/types/events/ActionEvent.d.ts +12 -0
- package/dist/types/events/MovementEvent.d.ts +28 -0
- package/dist/types/events/index.d.ts +2 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/settings/Bindings.d.ts +125 -0
- package/dist/types/settings/InputSettings.d.ts +57 -0
- package/dist/types/settings/PointerSettings.d.ts +89 -0
- package/dist/types/settings/SettingsEventMap.d.ts +9 -0
- package/dist/types/settings/index.d.ts +4 -0
- package/package.json +92 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* inpt v0.0.0 build Sun Jan 18 2026
|
|
3
|
+
* https://github.com/vanruesc/input-manager
|
|
4
|
+
* Copyright 2026 Raoul van Rüschen
|
|
5
|
+
* @license Zlib
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// src/core/BoundAction.ts
|
|
9
|
+
function getEnabledFlagCount(bitmask) {
|
|
10
|
+
let n = bitmask - (bitmask >>> 1 & 1431655765);
|
|
11
|
+
n = (n & 858993459) + (n >>> 2 & 858993459);
|
|
12
|
+
return (n + (n >>> 4) & 252645135) * 16843009 >>> 24;
|
|
13
|
+
}
|
|
14
|
+
var BoundAction = class {
|
|
15
|
+
/**
|
|
16
|
+
* The action.
|
|
17
|
+
*/
|
|
18
|
+
action;
|
|
19
|
+
/**
|
|
20
|
+
* Required modifiers stored as a bitmask.
|
|
21
|
+
*/
|
|
22
|
+
modifiers;
|
|
23
|
+
/**
|
|
24
|
+
* The number of enabled modifier flags.
|
|
25
|
+
*/
|
|
26
|
+
modifierCount;
|
|
27
|
+
/**
|
|
28
|
+
* Constructs a new bound action.
|
|
29
|
+
*
|
|
30
|
+
* @param action - An action.
|
|
31
|
+
* @param modifiers - Required modifiers stored as a bitmask.
|
|
32
|
+
*/
|
|
33
|
+
constructor(action, modifiers) {
|
|
34
|
+
this.action = action;
|
|
35
|
+
this.modifiers = modifiers;
|
|
36
|
+
this.modifierCount = getEnabledFlagCount(modifiers);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// src/core/Input.ts
|
|
41
|
+
function modifiersToBitmask(modifiers) {
|
|
42
|
+
let flags = 0;
|
|
43
|
+
if (modifiers.includes("Alt")) {
|
|
44
|
+
flags = (flags | 1) >>> 0;
|
|
45
|
+
}
|
|
46
|
+
if (modifiers.includes("Ctrl")) {
|
|
47
|
+
flags = (flags | 2) >>> 0;
|
|
48
|
+
}
|
|
49
|
+
if (modifiers.includes("Meta")) {
|
|
50
|
+
flags = (flags | 4) >>> 0;
|
|
51
|
+
}
|
|
52
|
+
if (modifiers.includes("Shift")) {
|
|
53
|
+
flags = (flags | 8) >>> 0;
|
|
54
|
+
}
|
|
55
|
+
return flags;
|
|
56
|
+
}
|
|
57
|
+
var Input = class {
|
|
58
|
+
/**
|
|
59
|
+
* @see {@link value}
|
|
60
|
+
*/
|
|
61
|
+
_value;
|
|
62
|
+
/**
|
|
63
|
+
* @see {@link modifiers}
|
|
64
|
+
*/
|
|
65
|
+
_modifiers;
|
|
66
|
+
/**
|
|
67
|
+
* Constructs new input data.
|
|
68
|
+
*
|
|
69
|
+
* @param value - The primary input value.
|
|
70
|
+
* @param options - Additional options.
|
|
71
|
+
*/
|
|
72
|
+
constructor(value, { modifiers } = {}) {
|
|
73
|
+
this._value = value;
|
|
74
|
+
this._modifiers = 0;
|
|
75
|
+
if (modifiers !== void 0) {
|
|
76
|
+
this.modifiers = modifiers;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The primary input value.
|
|
81
|
+
*/
|
|
82
|
+
get value() {
|
|
83
|
+
return this._value;
|
|
84
|
+
}
|
|
85
|
+
set value(value) {
|
|
86
|
+
this._value = value;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The required modifiers, stored as a bitmask.
|
|
90
|
+
*
|
|
91
|
+
* Modifiers can be set directly as a bitmask or as a list of modifier keys.
|
|
92
|
+
*/
|
|
93
|
+
get modifiers() {
|
|
94
|
+
return this._modifiers;
|
|
95
|
+
}
|
|
96
|
+
set modifiers(value) {
|
|
97
|
+
if (typeof value === "number") {
|
|
98
|
+
this._modifiers = value;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this._modifiers = modifiersToBitmask(value);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// node_modules/.pnpm/synthetic-event@2.0.0/node_modules/synthetic-event/dist/index.js
|
|
106
|
+
var EventTarget = class {
|
|
107
|
+
/**
|
|
108
|
+
* A collection of event listener functions.
|
|
109
|
+
*/
|
|
110
|
+
listenerFunctions;
|
|
111
|
+
/**
|
|
112
|
+
* A collection of event listener objects.
|
|
113
|
+
*/
|
|
114
|
+
listenerObjects;
|
|
115
|
+
/**
|
|
116
|
+
* Constructs a new event target.
|
|
117
|
+
*/
|
|
118
|
+
constructor() {
|
|
119
|
+
this.listenerFunctions = /* @__PURE__ */ new Map();
|
|
120
|
+
this.listenerObjects = /* @__PURE__ */ new Map();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Registers an event handler of a specific event type on the event target.
|
|
124
|
+
*
|
|
125
|
+
* @param type - The event type to listen for.
|
|
126
|
+
* @param listener - An event listener or callback.
|
|
127
|
+
*/
|
|
128
|
+
addEventListener(type, listener) {
|
|
129
|
+
if (typeof listener === "function") {
|
|
130
|
+
if (this.listenerFunctions.has(type)) {
|
|
131
|
+
const listeners = this.listenerFunctions.get(type);
|
|
132
|
+
listeners.add(listener);
|
|
133
|
+
} else {
|
|
134
|
+
const listeners = /* @__PURE__ */ new Set([listener]);
|
|
135
|
+
this.listenerFunctions.set(type, listeners);
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (this.listenerObjects.has(type)) {
|
|
140
|
+
const listeners = this.listenerObjects.get(type);
|
|
141
|
+
listeners.add(listener);
|
|
142
|
+
} else {
|
|
143
|
+
const listeners = /* @__PURE__ */ new Set([listener]);
|
|
144
|
+
this.listenerObjects.set(type, listeners);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Removes an event handler of a specific event type from the event target.
|
|
149
|
+
*
|
|
150
|
+
* @param type - The event type to remove.
|
|
151
|
+
* @param listener - The event listener to remove.
|
|
152
|
+
*/
|
|
153
|
+
hasEventListener(type, listener) {
|
|
154
|
+
if (typeof listener === "function") {
|
|
155
|
+
if (!this.listenerFunctions.has(type)) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
const listeners2 = this.listenerFunctions.get(type);
|
|
159
|
+
return listeners2.has(listener);
|
|
160
|
+
}
|
|
161
|
+
if (!this.listenerObjects.has(type)) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
const listeners = this.listenerObjects.get(type);
|
|
165
|
+
return listeners.has(listener);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Removes an event handler of a specific event type from the event target.
|
|
169
|
+
*
|
|
170
|
+
* @param type - The event type to remove.
|
|
171
|
+
* @param listener - The event listener to remove.
|
|
172
|
+
*/
|
|
173
|
+
removeEventListener(type, listener) {
|
|
174
|
+
if (typeof listener === "function") {
|
|
175
|
+
if (!this.listenerFunctions.has(type)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const listeners2 = this.listenerFunctions.get(type);
|
|
179
|
+
if (listeners2.delete(listener) && listeners2.size === 0) {
|
|
180
|
+
this.listenerFunctions.delete(type);
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (!this.listenerObjects.has(type)) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const listeners = this.listenerObjects.get(type);
|
|
188
|
+
if (listeners.delete(listener) && listeners.size === 0) {
|
|
189
|
+
this.listenerObjects.delete(type);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Dispatches an event at the specified event target, invoking the affected event listeners in the appropriate order.
|
|
194
|
+
*
|
|
195
|
+
* Event listeners can safely be added and removed while an event is being dispatched.
|
|
196
|
+
*
|
|
197
|
+
* @see https://262.ecma-international.org/#sec-map.prototype.foreach for more information on the iteration behavior.
|
|
198
|
+
* @param event - The event to dispatch.
|
|
199
|
+
* @param target - An event target.
|
|
200
|
+
*/
|
|
201
|
+
dispatchEvent(event, target = this) {
|
|
202
|
+
const listenerFunctions = target.listenerFunctions;
|
|
203
|
+
const listenerObjects = target.listenerObjects;
|
|
204
|
+
event.target = target;
|
|
205
|
+
if (listenerFunctions.has(event.type)) {
|
|
206
|
+
const listeners = listenerFunctions.get(event.type);
|
|
207
|
+
for (const listener of listeners) {
|
|
208
|
+
listener.call(target, event);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (listenerObjects.has(event.type)) {
|
|
212
|
+
const listeners = listenerObjects.get(event.type);
|
|
213
|
+
for (const listener of listeners) {
|
|
214
|
+
listener.handleEvent(event);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Removes all listeners.
|
|
220
|
+
*/
|
|
221
|
+
clearEventListeners() {
|
|
222
|
+
this.listenerFunctions.clear();
|
|
223
|
+
this.listenerObjects.clear();
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// src/core/WheelRotation.ts
|
|
228
|
+
var WheelRotation = /* @__PURE__ */ ((WheelRotation2) => {
|
|
229
|
+
WheelRotation2["NEGATIVE_X"] = "-x";
|
|
230
|
+
WheelRotation2["POSITIVE_X"] = "+x";
|
|
231
|
+
WheelRotation2["NEGATIVE_Y"] = "-y";
|
|
232
|
+
WheelRotation2["POSITIVE_Y"] = "+y";
|
|
233
|
+
return WheelRotation2;
|
|
234
|
+
})(WheelRotation || {});
|
|
235
|
+
function getWheelRotation(event) {
|
|
236
|
+
if (event.deltaY !== 0) {
|
|
237
|
+
return event.deltaY < 0 ? "-y" /* NEGATIVE_Y */ : "+y" /* POSITIVE_Y */;
|
|
238
|
+
} else if (event.deltaX !== 0) {
|
|
239
|
+
return event.deltaX < 0 ? "-x" /* NEGATIVE_X */ : "+x" /* POSITIVE_X */;
|
|
240
|
+
}
|
|
241
|
+
return void 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/settings/Bindings.ts
|
|
245
|
+
function getModifiersFromEvent(event) {
|
|
246
|
+
let flags = 0;
|
|
247
|
+
if (event.altKey) {
|
|
248
|
+
flags = (flags | 1) >>> 0;
|
|
249
|
+
}
|
|
250
|
+
if (event.ctrlKey) {
|
|
251
|
+
flags = (flags | 2) >>> 0;
|
|
252
|
+
}
|
|
253
|
+
if (event.metaKey) {
|
|
254
|
+
flags = (flags | 4) >>> 0;
|
|
255
|
+
}
|
|
256
|
+
if (event.shiftKey) {
|
|
257
|
+
flags = (flags | 8) >>> 0;
|
|
258
|
+
}
|
|
259
|
+
return flags;
|
|
260
|
+
}
|
|
261
|
+
var Bindings = class _Bindings {
|
|
262
|
+
/**
|
|
263
|
+
* The default bindings.
|
|
264
|
+
*/
|
|
265
|
+
defaultActions;
|
|
266
|
+
/**
|
|
267
|
+
* A collection that maps inputs to actions.
|
|
268
|
+
*/
|
|
269
|
+
actions;
|
|
270
|
+
/**
|
|
271
|
+
* Constructs new input bindings.
|
|
272
|
+
*/
|
|
273
|
+
constructor() {
|
|
274
|
+
this.defaultActions = /* @__PURE__ */ new Map();
|
|
275
|
+
this.actions = /* @__PURE__ */ new Map();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Resets the current bindings to match the default bindings.
|
|
279
|
+
*
|
|
280
|
+
* @return This instance.
|
|
281
|
+
*/
|
|
282
|
+
reset() {
|
|
283
|
+
this.actions = new Map(this.defaultActions);
|
|
284
|
+
return this;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Resets the current bindings and establishes default bindings.
|
|
288
|
+
*
|
|
289
|
+
* @param actions - A collection that maps inputs to actions.
|
|
290
|
+
* @return This instance.
|
|
291
|
+
*/
|
|
292
|
+
setDefault(actions) {
|
|
293
|
+
this.actions.clear();
|
|
294
|
+
for (const entry of actions) {
|
|
295
|
+
this.set(entry[0], entry[1]);
|
|
296
|
+
}
|
|
297
|
+
this.defaultActions = new Map(this.actions);
|
|
298
|
+
return this;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Clears the default bindings.
|
|
302
|
+
*
|
|
303
|
+
* @return This instance.
|
|
304
|
+
*/
|
|
305
|
+
clearDefault() {
|
|
306
|
+
this.defaultActions.clear();
|
|
307
|
+
return this;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Clears the current bindings.
|
|
311
|
+
*
|
|
312
|
+
* @return This instance.
|
|
313
|
+
*/
|
|
314
|
+
clear() {
|
|
315
|
+
this.actions.clear();
|
|
316
|
+
return this;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Copies the given bindings, including the default bindings.
|
|
320
|
+
*
|
|
321
|
+
* @param bindings - Bindings.
|
|
322
|
+
* @return This instance.
|
|
323
|
+
*/
|
|
324
|
+
copy(bindings) {
|
|
325
|
+
this.defaultActions = new Map(bindings.defaultActions);
|
|
326
|
+
this.actions = new Map(bindings.actions);
|
|
327
|
+
return this;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Clones these bindings.
|
|
331
|
+
*
|
|
332
|
+
* @return The cloned bindings.
|
|
333
|
+
*/
|
|
334
|
+
clone() {
|
|
335
|
+
const clone = new _Bindings();
|
|
336
|
+
return clone.copy(this);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Checks if any actions are bound to the given input.
|
|
340
|
+
*
|
|
341
|
+
* @param input - An input.
|
|
342
|
+
* @return Whether the given input is bound to an action.
|
|
343
|
+
*/
|
|
344
|
+
has(input) {
|
|
345
|
+
if (input instanceof Input) {
|
|
346
|
+
const value = input.value;
|
|
347
|
+
const modifiers = input.modifiers;
|
|
348
|
+
return this.actions.get(value)?.some((x) => x.modifiers === modifiers) !== void 0;
|
|
349
|
+
}
|
|
350
|
+
return this.actions.has(input);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Returns the action that exactly matches the given input.
|
|
354
|
+
*
|
|
355
|
+
* @param input - An input.
|
|
356
|
+
* @return The action, or undefined if the input is not bound to any action.
|
|
357
|
+
*/
|
|
358
|
+
get(input) {
|
|
359
|
+
let value = input;
|
|
360
|
+
let modifiers = 0;
|
|
361
|
+
if (input instanceof Input) {
|
|
362
|
+
value = input.value;
|
|
363
|
+
modifiers = input.modifiers;
|
|
364
|
+
}
|
|
365
|
+
return this.actions.get(value)?.find((x) => x.modifiers === modifiers)?.action;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Binds an action to an input.
|
|
369
|
+
*
|
|
370
|
+
* @param input - An input.
|
|
371
|
+
* @param action - An action.
|
|
372
|
+
* @return This instance.
|
|
373
|
+
*/
|
|
374
|
+
set(input, action) {
|
|
375
|
+
let value = input;
|
|
376
|
+
let modifiers = 0;
|
|
377
|
+
if (input instanceof Input) {
|
|
378
|
+
value = input.value;
|
|
379
|
+
modifiers = input.modifiers;
|
|
380
|
+
}
|
|
381
|
+
if (this.actions.has(value)) {
|
|
382
|
+
const boundActions = this.actions.get(value);
|
|
383
|
+
if (!boundActions.some((x) => x.action === action && x.modifiers === modifiers)) {
|
|
384
|
+
boundActions.push(new BoundAction(action, modifiers));
|
|
385
|
+
}
|
|
386
|
+
} else {
|
|
387
|
+
this.actions.set(value, [new BoundAction(action, modifiers)]);
|
|
388
|
+
}
|
|
389
|
+
return this;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Unbinds an action.
|
|
393
|
+
*
|
|
394
|
+
* @param input - The input.
|
|
395
|
+
* @return Whether the binding existed.
|
|
396
|
+
*/
|
|
397
|
+
delete(input) {
|
|
398
|
+
let value = input;
|
|
399
|
+
let modifiers = 0;
|
|
400
|
+
if (input instanceof Input) {
|
|
401
|
+
value = input.value;
|
|
402
|
+
modifiers = input.modifiers;
|
|
403
|
+
}
|
|
404
|
+
const boundActions = this.actions.get(value);
|
|
405
|
+
const match = boundActions?.find((x) => x.modifiers === modifiers);
|
|
406
|
+
if (boundActions === void 0 || match === void 0) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
if (boundActions.length === 1) {
|
|
410
|
+
return this.actions.delete(value);
|
|
411
|
+
}
|
|
412
|
+
boundActions.splice(boundActions.indexOf(match), 1);
|
|
413
|
+
return true;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Returns all actions that match the given mouse event.
|
|
417
|
+
*
|
|
418
|
+
* @param event - A mouse event
|
|
419
|
+
* @return The matching actions sorted by specificity, DESC, or undefined if there is no bound action.
|
|
420
|
+
*/
|
|
421
|
+
matchMouseEvent(event) {
|
|
422
|
+
const value = event.button;
|
|
423
|
+
const modifiers = getModifiersFromEvent(event);
|
|
424
|
+
return this.match(value, modifiers);
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Returns all actions that match the given wheel event.
|
|
428
|
+
*
|
|
429
|
+
* @param event - A wheel event
|
|
430
|
+
* @return The matching actions sorted by specificity, DESC, or undefined if there is no bound action.
|
|
431
|
+
*/
|
|
432
|
+
matchWheelEvent(event) {
|
|
433
|
+
const value = getWheelRotation(event);
|
|
434
|
+
const modifiers = getModifiersFromEvent(event);
|
|
435
|
+
return this.match(value, modifiers);
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Returns all actions that match the given keyboard event.
|
|
439
|
+
*
|
|
440
|
+
* @param event - A keyboard event
|
|
441
|
+
* @return The matching actions sorted by specificity, DESC, or undefined if there is no bound action.
|
|
442
|
+
*/
|
|
443
|
+
matchKeyboardEvent(event) {
|
|
444
|
+
const value = event.code;
|
|
445
|
+
const modifiers = getModifiersFromEvent(event);
|
|
446
|
+
return this.match(value, modifiers);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Returns all actions that match the given input.
|
|
450
|
+
*
|
|
451
|
+
* @param input - An input.
|
|
452
|
+
* @param modifiers - A modifier bitmask. Default is `~0 >>> 0` which allows all modifiers.
|
|
453
|
+
* @return The matching actions sorted by specificity, DESC, or undefined if there is no bound action.
|
|
454
|
+
*/
|
|
455
|
+
match(input, modifiers = ~0 >>> 0) {
|
|
456
|
+
if (!this.actions.has(input)) {
|
|
457
|
+
return void 0;
|
|
458
|
+
}
|
|
459
|
+
return this.actions.get(input).filter((x) => (x.modifiers & modifiers) === x.modifiers).sort((a, b) => b.modifierCount - a.modifierCount).map((x) => x.action);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Copies the given JSON data.
|
|
463
|
+
*
|
|
464
|
+
* @param json - The JSON data.
|
|
465
|
+
* @return This instance.
|
|
466
|
+
*/
|
|
467
|
+
fromJSON(json) {
|
|
468
|
+
if (typeof json === "string") {
|
|
469
|
+
json = JSON.parse(json);
|
|
470
|
+
}
|
|
471
|
+
this.defaultActions = new Map(json.defaultActions);
|
|
472
|
+
this.actions = new Map(json.actions);
|
|
473
|
+
return this;
|
|
474
|
+
}
|
|
475
|
+
toJSON() {
|
|
476
|
+
return {
|
|
477
|
+
defaultActions: [...this.defaultActions],
|
|
478
|
+
actions: [...this.actions]
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
// src/settings/PointerSettings.ts
|
|
484
|
+
var PointerSettings = class _PointerSettings extends EventTarget {
|
|
485
|
+
// #region Backing Data
|
|
486
|
+
/**
|
|
487
|
+
* @see {@link sensitivityX}
|
|
488
|
+
*/
|
|
489
|
+
_sensitivityX;
|
|
490
|
+
/**
|
|
491
|
+
* @see {@link sensitivityY}
|
|
492
|
+
*/
|
|
493
|
+
_sensitivityY;
|
|
494
|
+
/**
|
|
495
|
+
* @see {@link lockBehavior}
|
|
496
|
+
*/
|
|
497
|
+
_lockBehavior;
|
|
498
|
+
// #endregion
|
|
499
|
+
/**
|
|
500
|
+
* Constructs new pointer settings.
|
|
501
|
+
*/
|
|
502
|
+
constructor() {
|
|
503
|
+
super();
|
|
504
|
+
this._sensitivityX = 1e-3;
|
|
505
|
+
this._sensitivityY = 1e-3;
|
|
506
|
+
this._lockBehavior = /* @__PURE__ */ new Map();
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* The horizontal sensitivity.
|
|
510
|
+
*
|
|
511
|
+
* This sensitivity acts as a baseline scale for pointer movement deltas.
|
|
512
|
+
*
|
|
513
|
+
* @defaultValue 1e-3
|
|
514
|
+
*/
|
|
515
|
+
get sensitivityX() {
|
|
516
|
+
return this._sensitivityX;
|
|
517
|
+
}
|
|
518
|
+
set sensitivityX(value) {
|
|
519
|
+
this._sensitivityX = value;
|
|
520
|
+
this.dispatchEvent({ type: "change" });
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* The vertical sensitivity.
|
|
524
|
+
*
|
|
525
|
+
* This sensitivity acts as a baseline scale for pointer movement deltas.
|
|
526
|
+
*
|
|
527
|
+
* @defaultValue 1e-3
|
|
528
|
+
*/
|
|
529
|
+
get sensitivityY() {
|
|
530
|
+
return this._sensitivityY;
|
|
531
|
+
}
|
|
532
|
+
set sensitivityY(value) {
|
|
533
|
+
this._sensitivityY = value;
|
|
534
|
+
this.dispatchEvent({ type: "change" });
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Sets the horizontal and vertical rotation sensitivity.
|
|
538
|
+
*
|
|
539
|
+
* This sensitivity acts as a baseline scale for pointer movement deltas.
|
|
540
|
+
*
|
|
541
|
+
* @defaultValue 1e-3
|
|
542
|
+
*/
|
|
543
|
+
set sensitivity(value) {
|
|
544
|
+
this._sensitivityX = value;
|
|
545
|
+
this._sensitivityY = value;
|
|
546
|
+
this.dispatchEvent({ type: "change" });
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Defines the pointer lock behavior.
|
|
550
|
+
*
|
|
551
|
+
* The behavior defaults to `none` if not set.
|
|
552
|
+
*
|
|
553
|
+
* @see {@link setLockBehavior} for changing the pointer behavior.
|
|
554
|
+
* @internal
|
|
555
|
+
*/
|
|
556
|
+
get lockBehavior() {
|
|
557
|
+
return this._lockBehavior;
|
|
558
|
+
}
|
|
559
|
+
set lockBehavior(value) {
|
|
560
|
+
this._lockBehavior = value;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Returns the pointer behavior for a specific button.
|
|
564
|
+
*
|
|
565
|
+
* @param button - A pointer button.
|
|
566
|
+
* @return The behavior.
|
|
567
|
+
*/
|
|
568
|
+
getLockBehavior(button) {
|
|
569
|
+
return this._lockBehavior.get(button) ?? "none";
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Sets the pointer behavior for a specific button.
|
|
573
|
+
*
|
|
574
|
+
* @param button - The button.
|
|
575
|
+
* @param behavior - The behavior.
|
|
576
|
+
*/
|
|
577
|
+
setLockBehavior(button, behavior) {
|
|
578
|
+
this._lockBehavior.set(button, behavior);
|
|
579
|
+
this.dispatchEvent({ type: "change" });
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Copies the given pointer settings.
|
|
583
|
+
*
|
|
584
|
+
* @param settings - Pointer settings.
|
|
585
|
+
* @return This instance.
|
|
586
|
+
*/
|
|
587
|
+
copy(settings) {
|
|
588
|
+
this.lockBehavior = new Map(settings.lockBehavior);
|
|
589
|
+
this.sensitivity = settings.sensitivity;
|
|
590
|
+
return this;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Clones this pointer settings instance.
|
|
594
|
+
*
|
|
595
|
+
* @return The cloned pointer settings.
|
|
596
|
+
*/
|
|
597
|
+
clone() {
|
|
598
|
+
const clone = new _PointerSettings();
|
|
599
|
+
return clone.copy(this);
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Copies the given JSON data.
|
|
603
|
+
*
|
|
604
|
+
* @param json - The JSON data.
|
|
605
|
+
* @return This instance.
|
|
606
|
+
*/
|
|
607
|
+
fromJSON(json) {
|
|
608
|
+
if (typeof json === "string") {
|
|
609
|
+
json = JSON.parse(json);
|
|
610
|
+
}
|
|
611
|
+
this.lockBehavior = new Map(json.lockBehavior);
|
|
612
|
+
this.sensitivity = json.sensitivity;
|
|
613
|
+
return this;
|
|
614
|
+
}
|
|
615
|
+
toJSON() {
|
|
616
|
+
return {
|
|
617
|
+
behaviour: Array.from(this.lockBehavior.entries()),
|
|
618
|
+
sensitivity: this.sensitivity
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
// src/settings/InputSettings.ts
|
|
624
|
+
var InputSettings = class _InputSettings extends EventTarget {
|
|
625
|
+
/**
|
|
626
|
+
* Key bindings.
|
|
627
|
+
*/
|
|
628
|
+
keyBindings;
|
|
629
|
+
/**
|
|
630
|
+
* Pointer bindings.
|
|
631
|
+
*/
|
|
632
|
+
pointerBindings;
|
|
633
|
+
/**
|
|
634
|
+
* Pointer settings.
|
|
635
|
+
*/
|
|
636
|
+
pointer;
|
|
637
|
+
/**
|
|
638
|
+
* Constructs new pointer settings.
|
|
639
|
+
*/
|
|
640
|
+
constructor() {
|
|
641
|
+
super();
|
|
642
|
+
this.keyBindings = new Bindings();
|
|
643
|
+
this.pointerBindings = new Bindings();
|
|
644
|
+
this.pointer = new PointerSettings();
|
|
645
|
+
this.pointer.addEventListener("change", (e) => this.dispatchEvent(e));
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Copies the given pointer settings.
|
|
649
|
+
*
|
|
650
|
+
* @param settings - Pointer settings.
|
|
651
|
+
* @return This instance.
|
|
652
|
+
*/
|
|
653
|
+
copy(settings) {
|
|
654
|
+
this.keyBindings.copy(settings.keyBindings);
|
|
655
|
+
this.pointerBindings.copy(settings.pointerBindings);
|
|
656
|
+
this.pointer.copy(settings.pointer);
|
|
657
|
+
return this;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Clones this pointer settings instance.
|
|
661
|
+
*
|
|
662
|
+
* @return The cloned pointer settings.
|
|
663
|
+
*/
|
|
664
|
+
clone() {
|
|
665
|
+
const clone = new _InputSettings();
|
|
666
|
+
return clone.copy(this);
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Copies the given JSON data.
|
|
670
|
+
*
|
|
671
|
+
* @param json - The JSON data.
|
|
672
|
+
* @return This instance.
|
|
673
|
+
*/
|
|
674
|
+
fromJSON(json) {
|
|
675
|
+
if (typeof json === "string") {
|
|
676
|
+
json = JSON.parse(json);
|
|
677
|
+
}
|
|
678
|
+
this.keyBindings.fromJSON(json.keyBindings);
|
|
679
|
+
this.pointerBindings.fromJSON(json.pointerBindings);
|
|
680
|
+
this.pointer.fromJSON(json.pointer);
|
|
681
|
+
return this;
|
|
682
|
+
}
|
|
683
|
+
toJSON() {
|
|
684
|
+
return {
|
|
685
|
+
keyBindings: this.keyBindings,
|
|
686
|
+
pointerBindings: this.pointerBindings,
|
|
687
|
+
pointer: this.pointer
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Exports these settings as a data blob.
|
|
692
|
+
*
|
|
693
|
+
* @return The settings blob.
|
|
694
|
+
*/
|
|
695
|
+
toBlob() {
|
|
696
|
+
return new Blob([JSON.stringify(this)], {
|
|
697
|
+
type: "text/json"
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// src/core/InputManager.ts
|
|
703
|
+
var screen = { x: 0, y: 0 };
|
|
704
|
+
var InputManager = class extends EventTarget {
|
|
705
|
+
// #region Backing Data
|
|
706
|
+
/**
|
|
707
|
+
* @see {@link domElement}
|
|
708
|
+
*/
|
|
709
|
+
_domElement;
|
|
710
|
+
/**
|
|
711
|
+
* @see {@link enabled}
|
|
712
|
+
*/
|
|
713
|
+
_enabled;
|
|
714
|
+
// #endregion
|
|
715
|
+
// #region Input State
|
|
716
|
+
/**
|
|
717
|
+
* A collection that organizes active pointer events by ID.
|
|
718
|
+
*/
|
|
719
|
+
pointerEvents;
|
|
720
|
+
/**
|
|
721
|
+
* A collection of deferred mouse events that are handled when the pointer lock state changes.
|
|
722
|
+
*/
|
|
723
|
+
deferredMouseEvents;
|
|
724
|
+
/**
|
|
725
|
+
* A collection of actions that are currently active.
|
|
726
|
+
*/
|
|
727
|
+
activeActions;
|
|
728
|
+
// #endregion
|
|
729
|
+
// #region Reusable Events
|
|
730
|
+
movementEvent;
|
|
731
|
+
// #endregion
|
|
732
|
+
/**
|
|
733
|
+
* The settings.
|
|
734
|
+
*/
|
|
735
|
+
settings;
|
|
736
|
+
/**
|
|
737
|
+
* Constructs a new input manager.
|
|
738
|
+
*
|
|
739
|
+
* @param options - The options.
|
|
740
|
+
*/
|
|
741
|
+
constructor({ settings = new InputSettings(), domElement = null } = {}) {
|
|
742
|
+
super();
|
|
743
|
+
this._domElement = null;
|
|
744
|
+
this._enabled = false;
|
|
745
|
+
this.pointerEvents = /* @__PURE__ */ new Map();
|
|
746
|
+
this.deferredMouseEvents = /* @__PURE__ */ new Set();
|
|
747
|
+
this.activeActions = /* @__PURE__ */ new Set();
|
|
748
|
+
this.movementEvent = {
|
|
749
|
+
type: "move",
|
|
750
|
+
pointerCount: 0,
|
|
751
|
+
deltaX: 0,
|
|
752
|
+
deltaY: 0,
|
|
753
|
+
x: 0,
|
|
754
|
+
y: 0
|
|
755
|
+
};
|
|
756
|
+
this.settings = settings;
|
|
757
|
+
settings.addEventListener("change", this);
|
|
758
|
+
this.domElement = domElement;
|
|
759
|
+
this.enabled = true;
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* A DOM element that acts as the primary event target.
|
|
763
|
+
*/
|
|
764
|
+
get domElement() {
|
|
765
|
+
return this._domElement;
|
|
766
|
+
}
|
|
767
|
+
set domElement(value) {
|
|
768
|
+
this.removeEventListeners();
|
|
769
|
+
this._domElement = value;
|
|
770
|
+
if (this.enabled) {
|
|
771
|
+
this.addEventListeners();
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Determines whether the input listeners are currently enabled.
|
|
776
|
+
*/
|
|
777
|
+
get enabled() {
|
|
778
|
+
return this._enabled;
|
|
779
|
+
}
|
|
780
|
+
set enabled(value) {
|
|
781
|
+
if (value === this.enabled) {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
this._enabled = value;
|
|
785
|
+
if (value) {
|
|
786
|
+
this.addEventListeners();
|
|
787
|
+
} else {
|
|
788
|
+
this.removeEventListeners();
|
|
789
|
+
this.resetInputState();
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Indicates whether the pointer is currently locked.
|
|
794
|
+
*/
|
|
795
|
+
get pointerLocked() {
|
|
796
|
+
return document.pointerLockElement === this.domElement;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Registers event listeners.
|
|
800
|
+
*/
|
|
801
|
+
addEventListeners() {
|
|
802
|
+
if (this.domElement === null || typeof document === "undefined") {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
const domElement = this.domElement;
|
|
806
|
+
domElement.style.touchAction = "none";
|
|
807
|
+
document.addEventListener("pointerlockchange", this);
|
|
808
|
+
document.addEventListener("pointerlockerror", this);
|
|
809
|
+
document.addEventListener("visibilitychange", this);
|
|
810
|
+
document.body.addEventListener("keyup", this);
|
|
811
|
+
document.body.addEventListener("keydown", this);
|
|
812
|
+
domElement.addEventListener("pointermove", this, { passive: true });
|
|
813
|
+
domElement.addEventListener("mousedown", this);
|
|
814
|
+
domElement.addEventListener("mouseup", this);
|
|
815
|
+
domElement.addEventListener("pointerdown", this);
|
|
816
|
+
domElement.addEventListener("pointerup", this);
|
|
817
|
+
domElement.addEventListener("pointercancel", this);
|
|
818
|
+
domElement.addEventListener("wheel", this);
|
|
819
|
+
domElement.addEventListener("contextmenu", this);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Unregisters event listeners.
|
|
823
|
+
*/
|
|
824
|
+
removeEventListeners() {
|
|
825
|
+
if (this.domElement === null || typeof document === "undefined") {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
const domElement = this.domElement;
|
|
829
|
+
domElement.style.touchAction = "";
|
|
830
|
+
document.removeEventListener("pointerlockchange", this);
|
|
831
|
+
document.removeEventListener("pointerlockerror", this);
|
|
832
|
+
document.removeEventListener("visibilitychange", this);
|
|
833
|
+
document.body.removeEventListener("keyup", this);
|
|
834
|
+
document.body.removeEventListener("keydown", this);
|
|
835
|
+
domElement.removeEventListener("pointermove", this);
|
|
836
|
+
domElement.removeEventListener("mousedown", this);
|
|
837
|
+
domElement.removeEventListener("mouseup", this);
|
|
838
|
+
domElement.removeEventListener("pointerdown", this);
|
|
839
|
+
domElement.removeEventListener("pointerup", this);
|
|
840
|
+
domElement.removeEventListener("pointercancel", this);
|
|
841
|
+
domElement.removeEventListener("wheel", this);
|
|
842
|
+
domElement.removeEventListener("contextmenu", this);
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Reset the input state.
|
|
846
|
+
*/
|
|
847
|
+
resetInputState() {
|
|
848
|
+
this.pointerEvents.clear();
|
|
849
|
+
this.deferredMouseEvents.clear();
|
|
850
|
+
this.activeActions.clear();
|
|
851
|
+
this.unlockPointer();
|
|
852
|
+
this.dispatchEvent({
|
|
853
|
+
type: "reset"
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Locks the pointer.
|
|
858
|
+
*
|
|
859
|
+
* @return A promise that resolves when the pointer has been locked.
|
|
860
|
+
*/
|
|
861
|
+
async lockPointer() {
|
|
862
|
+
if (this.domElement?.requestPointerLock === void 0 || this.pointerLocked) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
try {
|
|
866
|
+
await this.domElement.requestPointerLock();
|
|
867
|
+
} catch (e) {
|
|
868
|
+
console.warn(e);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
/**
|
|
872
|
+
* Unlocks the pointer.
|
|
873
|
+
*/
|
|
874
|
+
unlockPointer() {
|
|
875
|
+
if (document.exitPointerLock === void 0 || !this.pointerLocked) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
document.exitPointerLock();
|
|
879
|
+
}
|
|
880
|
+
// #region Event Handling
|
|
881
|
+
/**
|
|
882
|
+
* Handles pointer move events.
|
|
883
|
+
*
|
|
884
|
+
* @param event - A pointer event.
|
|
885
|
+
*/
|
|
886
|
+
onPointerMove(event) {
|
|
887
|
+
if (this.pointerEvents.has(event.pointerId)) {
|
|
888
|
+
this.pointerEvents.set(event.pointerId, event);
|
|
889
|
+
} else if (!this.pointerLocked) {
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
let { movementX, movementY } = event;
|
|
893
|
+
if (movementX === void 0 || movementY === void 0) {
|
|
894
|
+
movementX = event.screenX - screen.x;
|
|
895
|
+
movementY = event.screenY - screen.y;
|
|
896
|
+
screen.x = event.screenX;
|
|
897
|
+
screen.y = event.screenY;
|
|
898
|
+
}
|
|
899
|
+
const movementEvent = this.movementEvent;
|
|
900
|
+
const sensitivityX = this.settings.pointer.sensitivityX;
|
|
901
|
+
const sensitivityY = this.settings.pointer.sensitivityY;
|
|
902
|
+
movementEvent.pointerCount = this.pointerEvents.size;
|
|
903
|
+
movementEvent.deltaX = movementX * sensitivityX;
|
|
904
|
+
movementEvent.deltaY = movementY * sensitivityY;
|
|
905
|
+
movementEvent.x = event.screenX;
|
|
906
|
+
movementEvent.y = event.screenY;
|
|
907
|
+
this.dispatchEvent(movementEvent);
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Handles pointer lock change events.
|
|
911
|
+
*/
|
|
912
|
+
onPointerLockChange() {
|
|
913
|
+
if (this.pointerLocked) {
|
|
914
|
+
for (const event of this.deferredMouseEvents) {
|
|
915
|
+
this.onMouseDown(event);
|
|
916
|
+
}
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
for (const event of this.deferredMouseEvents) {
|
|
920
|
+
this.onMouseUp(event);
|
|
921
|
+
}
|
|
922
|
+
this.deferredMouseEvents.clear();
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Handles `mousedown` events.
|
|
926
|
+
*
|
|
927
|
+
* Mouse events are used because pointer events don't fire for other mouse buttons while a pointer is active.
|
|
928
|
+
*
|
|
929
|
+
* @param event - A mouse event.
|
|
930
|
+
*/
|
|
931
|
+
onMouseDownNative(event) {
|
|
932
|
+
const behavior = this.settings.pointer.getLockBehavior(event.button);
|
|
933
|
+
if (behavior === "lock") {
|
|
934
|
+
this.deferredMouseEvents.add(event);
|
|
935
|
+
void this.lockPointer();
|
|
936
|
+
if (this.pointerLocked) {
|
|
937
|
+
this.onMouseDown(event);
|
|
938
|
+
}
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
if (behavior === "lock-hold") {
|
|
942
|
+
void this.lockPointer();
|
|
943
|
+
}
|
|
944
|
+
this.onMouseDown(event);
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* Handles `mouseup` events.
|
|
948
|
+
*
|
|
949
|
+
* Mouse events are used because pointer events don't fire for other mouse buttons while a pointer is active.
|
|
950
|
+
*
|
|
951
|
+
* @param event - A mouse event.
|
|
952
|
+
*/
|
|
953
|
+
onMouseUpNative(event) {
|
|
954
|
+
if (this.settings.pointer.getLockBehavior(event.button) !== "lock") {
|
|
955
|
+
this.onMouseUp(event);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Handles `mousedown` events.
|
|
960
|
+
*
|
|
961
|
+
* @param event - A mouse event.
|
|
962
|
+
*/
|
|
963
|
+
onMouseDown(event) {
|
|
964
|
+
const actions = this.settings.pointerBindings.matchMouseEvent(event);
|
|
965
|
+
if (actions === void 0 || actions.length === 0) {
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
this.dispatchEvent({
|
|
969
|
+
type: "activate",
|
|
970
|
+
action: actions[0]
|
|
971
|
+
});
|
|
972
|
+
this.activeActions.add(actions[0]);
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* Handles `mouseup` events.
|
|
976
|
+
*
|
|
977
|
+
* @param event - A mouse event.
|
|
978
|
+
*/
|
|
979
|
+
onMouseUp(event) {
|
|
980
|
+
const actions = this.settings.pointerBindings.match(event.button);
|
|
981
|
+
if (actions === void 0 || actions.length === 0) {
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
for (const action of actions) {
|
|
985
|
+
if (!this.activeActions.has(action)) {
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
this.dispatchEvent({
|
|
989
|
+
type: "deactivate",
|
|
990
|
+
action
|
|
991
|
+
});
|
|
992
|
+
this.activeActions.delete(action);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
/**
|
|
996
|
+
* Handles `pointerdown` events.
|
|
997
|
+
*
|
|
998
|
+
* @param event - A pointer event.
|
|
999
|
+
*/
|
|
1000
|
+
onPointerDown(event) {
|
|
1001
|
+
this.pointerEvents.set(event.pointerId, event);
|
|
1002
|
+
screen.x = event.screenX;
|
|
1003
|
+
screen.y = event.screenY;
|
|
1004
|
+
if (!this.pointerLocked && this.settings.pointer.getLockBehavior(event.button) === "none") {
|
|
1005
|
+
this.domElement?.setPointerCapture(event.pointerId);
|
|
1006
|
+
}
|
|
1007
|
+
if (event.pointerType !== "mouse") {
|
|
1008
|
+
this.onMouseDown(event);
|
|
1009
|
+
event.preventDefault();
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Handles `pointerup` events.
|
|
1014
|
+
*
|
|
1015
|
+
* @param event - A pointer event.
|
|
1016
|
+
*/
|
|
1017
|
+
onPointerUp(event) {
|
|
1018
|
+
this.pointerEvents.delete(event.pointerId);
|
|
1019
|
+
if (event.pointerType !== "mouse") {
|
|
1020
|
+
this.onMouseUp(event);
|
|
1021
|
+
event.preventDefault();
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Handles `contextmenu` events.
|
|
1026
|
+
*
|
|
1027
|
+
* @param event - A pointer event.
|
|
1028
|
+
*/
|
|
1029
|
+
onContextMenu(event) {
|
|
1030
|
+
if (this.settings.pointerBindings.matchMouseEvent(event)?.length !== 0) {
|
|
1031
|
+
event.preventDefault();
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Handles `wheel` events.
|
|
1036
|
+
*
|
|
1037
|
+
* @param event - A wheel event.
|
|
1038
|
+
*/
|
|
1039
|
+
onWheel(event) {
|
|
1040
|
+
const actions = this.settings.pointerBindings.matchWheelEvent(event);
|
|
1041
|
+
if (actions === void 0 || actions.length === 0) {
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
event.preventDefault();
|
|
1045
|
+
this.dispatchEvent({
|
|
1046
|
+
type: "activate",
|
|
1047
|
+
action: actions[0]
|
|
1048
|
+
});
|
|
1049
|
+
this.activeActions.add(actions[0]);
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* Handles `keydown` events.
|
|
1053
|
+
*
|
|
1054
|
+
* @param event - A keyboard event.
|
|
1055
|
+
*/
|
|
1056
|
+
onKeyDown(event) {
|
|
1057
|
+
if (event.repeat) {
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
const actions = this.settings.keyBindings.matchKeyboardEvent(event);
|
|
1061
|
+
if (actions === void 0 || actions.length === 0) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
event.preventDefault();
|
|
1065
|
+
this.dispatchEvent({
|
|
1066
|
+
type: "activate",
|
|
1067
|
+
action: actions[0]
|
|
1068
|
+
});
|
|
1069
|
+
this.activeActions.add(actions[0]);
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Handles `keyup` events.
|
|
1073
|
+
*
|
|
1074
|
+
* @param event - A keyboard event.
|
|
1075
|
+
*/
|
|
1076
|
+
onKeyUp(event) {
|
|
1077
|
+
const actions = this.settings.keyBindings.match(event.code);
|
|
1078
|
+
if (actions === void 0 || actions.length === 0) {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
event.preventDefault();
|
|
1082
|
+
for (const action of actions) {
|
|
1083
|
+
if (!this.activeActions.has(action)) {
|
|
1084
|
+
continue;
|
|
1085
|
+
}
|
|
1086
|
+
this.dispatchEvent({
|
|
1087
|
+
type: "deactivate",
|
|
1088
|
+
action
|
|
1089
|
+
});
|
|
1090
|
+
this.activeActions.delete(action);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Handles `pointercancel` events.
|
|
1095
|
+
*
|
|
1096
|
+
* @param event - A pointer event.
|
|
1097
|
+
*/
|
|
1098
|
+
onPointerCancel(event) {
|
|
1099
|
+
this.resetInputState();
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* Cancels active interactions on visibility loss.
|
|
1103
|
+
*/
|
|
1104
|
+
onVisibilityChange() {
|
|
1105
|
+
if (document.hidden) {
|
|
1106
|
+
this.resetInputState();
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
handleEvent(event) {
|
|
1110
|
+
switch (event.type) {
|
|
1111
|
+
case "pointermove":
|
|
1112
|
+
this.onPointerMove(event);
|
|
1113
|
+
break;
|
|
1114
|
+
case "mousedown":
|
|
1115
|
+
this.onMouseDownNative(event);
|
|
1116
|
+
break;
|
|
1117
|
+
case "mouseup":
|
|
1118
|
+
this.onMouseUpNative(event);
|
|
1119
|
+
break;
|
|
1120
|
+
case "pointerdown":
|
|
1121
|
+
this.onPointerDown(event);
|
|
1122
|
+
break;
|
|
1123
|
+
case "pointerup":
|
|
1124
|
+
this.onPointerUp(event);
|
|
1125
|
+
break;
|
|
1126
|
+
case "pointercancel":
|
|
1127
|
+
this.onPointerCancel(event);
|
|
1128
|
+
break;
|
|
1129
|
+
case "pointerlockchange":
|
|
1130
|
+
this.onPointerLockChange();
|
|
1131
|
+
break;
|
|
1132
|
+
case "contextmenu":
|
|
1133
|
+
this.onContextMenu(event);
|
|
1134
|
+
break;
|
|
1135
|
+
case "wheel":
|
|
1136
|
+
this.onWheel(event);
|
|
1137
|
+
break;
|
|
1138
|
+
case "keydown":
|
|
1139
|
+
this.onKeyDown(event);
|
|
1140
|
+
break;
|
|
1141
|
+
case "keyup":
|
|
1142
|
+
this.onKeyUp(event);
|
|
1143
|
+
break;
|
|
1144
|
+
case "visibilitychange":
|
|
1145
|
+
this.onVisibilityChange();
|
|
1146
|
+
break;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
// #endregion
|
|
1150
|
+
dispose() {
|
|
1151
|
+
this.enabled = false;
|
|
1152
|
+
}
|
|
1153
|
+
};
|
|
1154
|
+
|
|
1155
|
+
// src/core/PointerButton.ts
|
|
1156
|
+
var PointerButton = /* @__PURE__ */ ((PointerButton2) => {
|
|
1157
|
+
PointerButton2[PointerButton2["MAIN"] = 0] = "MAIN";
|
|
1158
|
+
PointerButton2[PointerButton2["AUXILIARY"] = 1] = "AUXILIARY";
|
|
1159
|
+
PointerButton2[PointerButton2["SECONDARY"] = 2] = "SECONDARY";
|
|
1160
|
+
return PointerButton2;
|
|
1161
|
+
})(PointerButton || {});
|
|
1162
|
+
export {
|
|
1163
|
+
Bindings,
|
|
1164
|
+
BoundAction,
|
|
1165
|
+
Input,
|
|
1166
|
+
InputManager,
|
|
1167
|
+
InputSettings,
|
|
1168
|
+
PointerButton,
|
|
1169
|
+
PointerSettings,
|
|
1170
|
+
WheelRotation,
|
|
1171
|
+
getWheelRotation
|
|
1172
|
+
};
|
|
1173
|
+
/*! Bundled license information:
|
|
1174
|
+
|
|
1175
|
+
synthetic-event/dist/index.js:
|
|
1176
|
+
(**
|
|
1177
|
+
* synthetic-event v2.0.0 build Sat Jan 10 2026
|
|
1178
|
+
* https://github.com/vanruesc/synthetic-event
|
|
1179
|
+
* Copyright 2026 Raoul van Rüschen
|
|
1180
|
+
* @license Zlib
|
|
1181
|
+
*)
|
|
1182
|
+
*/
|