three-gamepad-controls 0.10.5 → 0.10.6
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/dist/gamepad-arcball-controls.js +1 -1
- package/dist/gamepad-controls.js +28 -18
- package/dist/gamepad-drag-controls.js +1 -1
- package/dist/gamepad-first-person-controls.js +1 -1
- package/dist/gamepad-fly-controls.js +1 -1
- package/dist/gamepad-manager.js +104 -0
- package/dist/gamepad-orbit-controls.js +1 -1
- package/dist/gamepad-pointer-lock-controls.js +1 -1
- package/dist/gamepad-trackball-controls.js +1 -1
- package/dist/gamepad-transform-controls.js +1 -1
- package/dist/utils.js +1 -20
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone, getGamepadButtonPressed, getGamepadButtonValue } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone, getGamepadButtonPressed, getGamepadButtonValue } from "./utils.js";
|
|
4
4
|
import { Vector2, Vector3 } from "three";
|
|
5
5
|
//#region src/gamepad-arcball-controls.ts
|
|
6
6
|
/**
|
package/dist/gamepad-controls.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GamepadManager } from "./gamepad-manager.js";
|
|
2
2
|
import { EventDispatcher } from "three";
|
|
3
3
|
//#region src/gamepad-controls.ts
|
|
4
4
|
/**
|
|
@@ -17,10 +17,12 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
17
17
|
* The currently active gamepad, or `null` if no gamepad is connected.
|
|
18
18
|
*/
|
|
19
19
|
gamepad = null;
|
|
20
|
+
#manager;
|
|
20
21
|
#onGamepadConnected;
|
|
21
22
|
#onGamepadDisconnected;
|
|
22
23
|
constructor() {
|
|
23
24
|
super();
|
|
25
|
+
this.#manager = new GamepadManager();
|
|
24
26
|
this.#onGamepadConnected = (event) => {
|
|
25
27
|
this.onGamepadConnected(event.gamepad);
|
|
26
28
|
};
|
|
@@ -37,17 +39,20 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
37
39
|
*/
|
|
38
40
|
update(deltaTime) {
|
|
39
41
|
if (!this.enabled) return;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
43
|
+
const { gamepad, connected, disconnected } = this.#manager.update();
|
|
44
|
+
if (connected !== null) {
|
|
45
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
46
|
+
this.onGamepadConnected(connected);
|
|
47
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
48
|
+
} else if (disconnected !== null) {
|
|
49
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
50
|
+
this.onGamepadDisconnected(disconnected);
|
|
51
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
52
|
+
return;
|
|
43
53
|
} else {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (nextGamepad === null) {
|
|
47
|
-
this.onGamepadDisconnected(previousGamepad);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this.gamepad = nextGamepad;
|
|
54
|
+
this.gamepad = gamepad;
|
|
55
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
51
56
|
}
|
|
52
57
|
if (this.gamepad === null) return;
|
|
53
58
|
this.onUpdate(deltaTime, this.gamepad);
|
|
@@ -59,6 +64,7 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
59
64
|
window.removeEventListener("gamepadconnected", this.#onGamepadConnected);
|
|
60
65
|
window.removeEventListener("gamepaddisconnected", this.#onGamepadDisconnected);
|
|
61
66
|
this.gamepad = null;
|
|
67
|
+
this.#manager.activeGamepad = null;
|
|
62
68
|
this.enabled = false;
|
|
63
69
|
}
|
|
64
70
|
/**
|
|
@@ -70,11 +76,14 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
70
76
|
* @param gamepad - The gamepad that just connected.
|
|
71
77
|
*/
|
|
72
78
|
onGamepadConnected(gamepad) {
|
|
73
|
-
|
|
74
|
-
this.gamepad
|
|
79
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
80
|
+
if (!this.#manager.connect(gamepad)) return;
|
|
81
|
+
const connectedGamepad = this.#manager.activeGamepad;
|
|
82
|
+
if (connectedGamepad === null) return;
|
|
83
|
+
this.gamepad = connectedGamepad;
|
|
75
84
|
this.dispatchEvent({
|
|
76
85
|
type: "connected",
|
|
77
|
-
gamepad
|
|
86
|
+
gamepad: connectedGamepad
|
|
78
87
|
});
|
|
79
88
|
}
|
|
80
89
|
/**
|
|
@@ -86,12 +95,13 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
86
95
|
* @param gamepad - The gamepad that just disconnected.
|
|
87
96
|
*/
|
|
88
97
|
onGamepadDisconnected(gamepad) {
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
98
|
+
this.#manager.activeGamepad = this.gamepad;
|
|
99
|
+
const disconnectedGamepad = this.#manager.disconnect(gamepad);
|
|
100
|
+
if (disconnectedGamepad === null) return;
|
|
101
|
+
this.gamepad = this.#manager.activeGamepad;
|
|
92
102
|
this.dispatchEvent({
|
|
93
103
|
type: "disconnected",
|
|
94
|
-
gamepad:
|
|
104
|
+
gamepad: disconnectedGamepad
|
|
95
105
|
});
|
|
96
106
|
}
|
|
97
107
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone, getGamepadButtonPressed } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone, getGamepadButtonPressed } from "./utils.js";
|
|
4
4
|
import { Matrix4, Vector2, Vector3 } from "three";
|
|
5
5
|
//#region src/gamepad-drag-controls.ts
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone, getGamepadButtonValue } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone, getGamepadButtonValue } from "./utils.js";
|
|
4
4
|
import { MathUtils, Spherical, Vector3 } from "three";
|
|
5
5
|
//#region src/gamepad-first-person-controls.ts
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone, getGamepadButtonPressed, getGamepadButtonValue } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone, getGamepadButtonPressed, getGamepadButtonValue } from "./utils.js";
|
|
4
4
|
import { Quaternion } from "three";
|
|
5
5
|
//#region src/gamepad-fly-controls.ts
|
|
6
6
|
/**
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
//#region src/gamepad-manager.ts
|
|
2
|
+
const EMPTY_UPDATE_RESULT = {
|
|
3
|
+
gamepad: null,
|
|
4
|
+
connected: null,
|
|
5
|
+
disconnected: null
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Internal input core that owns active gamepad polling and snapshot refresh.
|
|
9
|
+
*
|
|
10
|
+
* This class intentionally tracks only one active gamepad. Higher-level
|
|
11
|
+
* multi-gamepad selection should be built on top of this lifecycle in a
|
|
12
|
+
* later phase.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
var GamepadManager = class {
|
|
17
|
+
/**
|
|
18
|
+
* The active gamepad snapshot, or `null` when none is active.
|
|
19
|
+
*/
|
|
20
|
+
activeGamepad = null;
|
|
21
|
+
/**
|
|
22
|
+
* Accepts a gamepad as active when no active gamepad exists.
|
|
23
|
+
*
|
|
24
|
+
* Additional connected gamepads are ignored so the current controls keep
|
|
25
|
+
* using the first active device by default.
|
|
26
|
+
*
|
|
27
|
+
* @param gamepad - Gamepad snapshot to activate.
|
|
28
|
+
* @returns `true` when the gamepad became active, otherwise `false`.
|
|
29
|
+
*/
|
|
30
|
+
connect(gamepad) {
|
|
31
|
+
if (this.activeGamepad !== null || !gamepad.connected) return false;
|
|
32
|
+
this.activeGamepad = gamepad;
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Clears the active gamepad when it matches the disconnecting gamepad index.
|
|
37
|
+
*
|
|
38
|
+
* @param gamepad - Gamepad snapshot that disconnected.
|
|
39
|
+
* @returns The previously active gamepad when it was cleared, otherwise `null`.
|
|
40
|
+
*/
|
|
41
|
+
disconnect(gamepad) {
|
|
42
|
+
if (this.activeGamepad?.index !== gamepad.index) return null;
|
|
43
|
+
const disconnectedGamepad = this.activeGamepad;
|
|
44
|
+
this.activeGamepad = null;
|
|
45
|
+
return disconnectedGamepad;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Polls the Gamepad API and refreshes the active gamepad snapshot.
|
|
49
|
+
*
|
|
50
|
+
* The browser exposes gamepad state as snapshots, so polling must replace
|
|
51
|
+
* the stored reference before controls read axes or buttons.
|
|
52
|
+
*
|
|
53
|
+
* @returns The active gamepad and any connect/disconnect transition found.
|
|
54
|
+
*/
|
|
55
|
+
update() {
|
|
56
|
+
if (this.activeGamepad === null) {
|
|
57
|
+
const connectedGamepad = this.#getFirstConnectedGamepad();
|
|
58
|
+
if (connectedGamepad === null) return EMPTY_UPDATE_RESULT;
|
|
59
|
+
this.activeGamepad = connectedGamepad;
|
|
60
|
+
return {
|
|
61
|
+
gamepad: connectedGamepad,
|
|
62
|
+
connected: connectedGamepad,
|
|
63
|
+
disconnected: null
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const previousGamepad = this.activeGamepad;
|
|
67
|
+
const nextGamepad = this.#getGamepadByIndex(previousGamepad.index);
|
|
68
|
+
if (nextGamepad === null) {
|
|
69
|
+
this.activeGamepad = null;
|
|
70
|
+
return {
|
|
71
|
+
gamepad: null,
|
|
72
|
+
connected: null,
|
|
73
|
+
disconnected: previousGamepad
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
this.activeGamepad = nextGamepad;
|
|
77
|
+
return {
|
|
78
|
+
gamepad: nextGamepad,
|
|
79
|
+
connected: null,
|
|
80
|
+
disconnected: null
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Reads the latest connected gamepad snapshot at a known index.
|
|
85
|
+
*
|
|
86
|
+
* @param index - Browser-assigned gamepad index to refresh.
|
|
87
|
+
* @returns A connected gamepad snapshot, or `null` if it is gone.
|
|
88
|
+
*/
|
|
89
|
+
#getGamepadByIndex(index) {
|
|
90
|
+
const gamepad = navigator.getGamepads()[index] ?? null;
|
|
91
|
+
return gamepad?.connected === true ? gamepad : null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Finds the first currently connected gamepad snapshot.
|
|
95
|
+
*
|
|
96
|
+
* @returns The first connected gamepad snapshot, or `null` if none exist.
|
|
97
|
+
*/
|
|
98
|
+
#getFirstConnectedGamepad() {
|
|
99
|
+
for (const gamepad of navigator.getGamepads()) if (gamepad?.connected === true) return gamepad;
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
//#endregion
|
|
104
|
+
export { GamepadManager };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone, getGamepadButtonValue } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone, getGamepadButtonValue } from "./utils.js";
|
|
4
4
|
//#region src/gamepad-orbit-controls.ts
|
|
5
5
|
/**
|
|
6
6
|
* Default options merged in the constructor when no explicit configuration is provided.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone } from "./utils.js";
|
|
4
4
|
import { Euler } from "three";
|
|
5
5
|
//#region src/gamepad-pointer-lock-controls.ts
|
|
6
6
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone, getGamepadButtonValue } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone, getGamepadButtonValue } from "./utils.js";
|
|
4
4
|
//#region src/gamepad-trackball-controls.ts
|
|
5
5
|
/**
|
|
6
6
|
* Default options merged in the constructor when no explicit configuration is provided.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
2
|
-
import { applyGamepadDeadzone, getGamepadButtonPressed } from "./utils.js";
|
|
3
2
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
3
|
+
import { applyGamepadDeadzone, getGamepadButtonPressed } from "./utils.js";
|
|
4
4
|
import { Matrix4, Quaternion, Vector2, Vector3 } from "three";
|
|
5
5
|
//#region src/gamepad-transform-controls.ts
|
|
6
6
|
/**
|
package/dist/utils.js
CHANGED
|
@@ -37,24 +37,5 @@ const getGamepadButtonValue = (gamepad, button) => {
|
|
|
37
37
|
if (gamepadButton.value !== 0) return gamepadButton.value;
|
|
38
38
|
return gamepadButton.pressed ? 1 : 0;
|
|
39
39
|
};
|
|
40
|
-
/**
|
|
41
|
-
* Returns a fresh connected gamepad snapshot by index.
|
|
42
|
-
*
|
|
43
|
-
* @param index - Gamepad index to look up.
|
|
44
|
-
* @returns The connected gamepad snapshot at the index, or `null` when unavailable.
|
|
45
|
-
*/
|
|
46
|
-
const getGamepadByIndex = (index) => {
|
|
47
|
-
const gamepad = navigator.getGamepads()[index] ?? null;
|
|
48
|
-
return gamepad?.connected === true ? gamepad : null;
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Returns the first currently connected gamepad snapshot.
|
|
52
|
-
*
|
|
53
|
-
* @returns The first connected gamepad snapshot, or `null` when none are connected.
|
|
54
|
-
*/
|
|
55
|
-
const getFirstConnectedGamepad = () => {
|
|
56
|
-
for (const gamepad of navigator.getGamepads()) if (gamepad?.connected === true) return gamepad;
|
|
57
|
-
return null;
|
|
58
|
-
};
|
|
59
40
|
//#endregion
|
|
60
|
-
export { applyGamepadDeadzone,
|
|
41
|
+
export { applyGamepadDeadzone, getGamepadButtonPressed, getGamepadButtonValue };
|
package/package.json
CHANGED