three-gamepad-controls 0.13.1 → 0.15.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/README.md +1 -0
- package/dist/core.d.ts +14 -1
- package/dist/core.js +14 -1
- package/dist/gamepad-arcball-controls.d.ts +0 -1
- package/dist/gamepad-controls.d.ts +31 -3
- package/dist/gamepad-controls.js +37 -2
- package/dist/gamepad-drag-controls.d.ts +0 -1
- package/dist/gamepad-first-person-controls.d.ts +0 -1
- package/dist/gamepad-fly-controls.d.ts +0 -1
- package/dist/gamepad-haptics.js +88 -0
- package/dist/gamepad-input.d.ts +33 -4
- package/dist/gamepad-input.js +40 -3
- package/dist/gamepad-manager.js +3 -3
- package/dist/gamepad-map-controls.d.ts +0 -1
- package/dist/gamepad-orbit-controls.d.ts +0 -1
- package/dist/gamepad-pointer-lock-controls.d.ts +0 -1
- package/dist/gamepad-trackball-controls.d.ts +0 -1
- package/dist/gamepad-transform-controls.d.ts +0 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -55,6 +55,7 @@ bun add -d @types/three # optional: for TypeScript projects
|
|
|
55
55
|
|
|
56
56
|
- [Core](./docs/core.md) — The fundamental building blocks.
|
|
57
57
|
- [GamepadInput](./docs/gamepad-input.md) - Low-level reader for gamepad buttons, axes, sticks, and transitions.
|
|
58
|
+
- [Haptic Feedback](./docs/haptic-feedback.md) - Optional gamepad vibration effects with graceful degradation.
|
|
58
59
|
- [Multiple Gamepads](./docs/multiple-gamepads.md) - Assign different gamepads to controls, players, and gameplay inputs.
|
|
59
60
|
- [GamepadControls](./docs/gamepad-controls.md) — Abstract base class for custom gamepad controls.
|
|
60
61
|
- [GamepadArcballControls](./docs/gamepad-arcball-controls.md) - Gamepad support for `ArcballControls`.
|
package/dist/core.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
//#region src/core.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Smallest valid browser-assigned gamepad index.
|
|
4
|
+
*
|
|
5
|
+
* Gamepad slots cannot be negative.
|
|
6
|
+
*/
|
|
7
|
+
declare const MIN_GAMEPAD_INDEX = 0;
|
|
8
|
+
/**
|
|
9
|
+
* Largest valid browser-assigned gamepad index.
|
|
10
|
+
*
|
|
11
|
+
* `Gamepad.index` is a Web IDL `long`, a signed 32-bit integer. Because
|
|
12
|
+
* gamepad slots cannot be negative, the largest valid index is 2^31 - 1.
|
|
13
|
+
*/
|
|
14
|
+
declare const MAX_GAMEPAD_INDEX = 2147483647;
|
|
2
15
|
/**
|
|
3
16
|
* Button indices for the W3C Standard Gamepad mapping.
|
|
4
17
|
* @see https://www.w3.org/TR/gamepad/#dfn-standard-gamepad
|
|
@@ -49,4 +62,4 @@ type GamepadAxisKey = keyof typeof GAMEPAD_AXIS;
|
|
|
49
62
|
*/
|
|
50
63
|
type GamepadAxisValue = (typeof GAMEPAD_AXIS)[keyof typeof GAMEPAD_AXIS];
|
|
51
64
|
//#endregion
|
|
52
|
-
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue };
|
|
65
|
+
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX };
|
package/dist/core.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
//#region src/core.ts
|
|
2
2
|
/**
|
|
3
|
+
* Smallest valid browser-assigned gamepad index.
|
|
4
|
+
*
|
|
5
|
+
* Gamepad slots cannot be negative.
|
|
6
|
+
*/
|
|
7
|
+
const MIN_GAMEPAD_INDEX = 0;
|
|
8
|
+
/**
|
|
9
|
+
* Largest valid browser-assigned gamepad index.
|
|
10
|
+
*
|
|
11
|
+
* `Gamepad.index` is a Web IDL `long`, a signed 32-bit integer. Because
|
|
12
|
+
* gamepad slots cannot be negative, the largest valid index is 2^31 - 1.
|
|
13
|
+
*/
|
|
14
|
+
const MAX_GAMEPAD_INDEX = 2147483647;
|
|
15
|
+
/**
|
|
3
16
|
* Button indices for the W3C Standard Gamepad mapping.
|
|
4
17
|
* @see https://www.w3.org/TR/gamepad/#dfn-standard-gamepad
|
|
5
18
|
*/
|
|
@@ -33,4 +46,4 @@ const GAMEPAD_AXIS = {
|
|
|
33
46
|
RightY: 3
|
|
34
47
|
};
|
|
35
48
|
//#endregion
|
|
36
|
-
export { GAMEPAD_AXIS, GAMEPAD_BUTTON };
|
|
49
|
+
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GamepadInput, GamepadInputOptions } from "./gamepad-input.js";
|
|
2
2
|
import { EventDispatcher } from "three";
|
|
3
|
-
|
|
4
3
|
//#region src/gamepad-controls.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Event map for {@link GamepadControls}.
|
|
@@ -53,8 +52,8 @@ declare abstract class GamepadControls extends EventDispatcher<GamepadControlsEv
|
|
|
53
52
|
* Creates the base input reader and attaches lifecycle listeners.
|
|
54
53
|
*
|
|
55
54
|
* @param options - Shared gamepad selection options.
|
|
56
|
-
* @throws {RangeError} When `gamepadIndex` is not an integer
|
|
57
|
-
*
|
|
55
|
+
* @throws {RangeError} When `gamepadIndex` is not an integer from
|
|
56
|
+
* `MIN_GAMEPAD_INDEX` through `MAX_GAMEPAD_INDEX`.
|
|
58
57
|
*/
|
|
59
58
|
constructor(options?: GamepadControlsOptions);
|
|
60
59
|
/**
|
|
@@ -63,12 +62,41 @@ declare abstract class GamepadControls extends EventDispatcher<GamepadControlsEv
|
|
|
63
62
|
* @returns The shared input reader for the active gamepad.
|
|
64
63
|
*/
|
|
65
64
|
protected get gamepadInput(): GamepadInput;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the active gamepad exposes a callable primary vibration actuator.
|
|
67
|
+
*
|
|
68
|
+
* This does not guarantee support for every {@link GamepadHapticEffectType}.
|
|
69
|
+
*
|
|
70
|
+
* @returns `true` when vibration effects can be requested.
|
|
71
|
+
*/
|
|
72
|
+
get vibrationSupported(): boolean;
|
|
66
73
|
/**
|
|
67
74
|
* Advances the controller by one frame. Call this inside your render loop.
|
|
68
75
|
*
|
|
69
76
|
* @param deltaTime - Seconds since the last frame.
|
|
70
77
|
*/
|
|
71
78
|
update(deltaTime: number): void;
|
|
79
|
+
/**
|
|
80
|
+
* Plays an effect through the active gamepad's primary vibration actuator.
|
|
81
|
+
*
|
|
82
|
+
* Missing browser, gamepad, or effect support is treated as a safe no-op.
|
|
83
|
+
* Environmental failures such as a hidden document are also ignored.
|
|
84
|
+
* Invalid parameters and unexpected failures remain rejected.
|
|
85
|
+
*
|
|
86
|
+
* @param type - Haptic effect type to play.
|
|
87
|
+
* @param parameters - Optional parameters describing the effect.
|
|
88
|
+
* @returns The browser result, or `null` when the effect is ignored.
|
|
89
|
+
*/
|
|
90
|
+
playVibrationEffect(type: GamepadHapticEffectType, parameters?: GamepadEffectParameters): Promise<GamepadHapticsResult | null>;
|
|
91
|
+
/**
|
|
92
|
+
* Stops the active effect on the gamepad's primary vibration actuator.
|
|
93
|
+
*
|
|
94
|
+
* Missing or temporarily unavailable haptics are treated as a safe no-op.
|
|
95
|
+
* Unexpected failures remain rejected.
|
|
96
|
+
*
|
|
97
|
+
* @returns The browser result, or `null` when reset is ignored.
|
|
98
|
+
*/
|
|
99
|
+
resetVibration(): Promise<GamepadHapticsResult | null>;
|
|
72
100
|
/**
|
|
73
101
|
* Removes all event listeners attached by this controller. Call when no longer needed.
|
|
74
102
|
*/
|
package/dist/gamepad-controls.js
CHANGED
|
@@ -24,8 +24,8 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
24
24
|
* Creates the base input reader and attaches lifecycle listeners.
|
|
25
25
|
*
|
|
26
26
|
* @param options - Shared gamepad selection options.
|
|
27
|
-
* @throws {RangeError} When `gamepadIndex` is not an integer
|
|
28
|
-
*
|
|
27
|
+
* @throws {RangeError} When `gamepadIndex` is not an integer from
|
|
28
|
+
* `MIN_GAMEPAD_INDEX` through `MAX_GAMEPAD_INDEX`.
|
|
29
29
|
*/
|
|
30
30
|
constructor(options) {
|
|
31
31
|
super();
|
|
@@ -44,6 +44,16 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
44
44
|
return this.#gamepadInput;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
+
* Whether the active gamepad exposes a callable primary vibration actuator.
|
|
48
|
+
*
|
|
49
|
+
* This does not guarantee support for every {@link GamepadHapticEffectType}.
|
|
50
|
+
*
|
|
51
|
+
* @returns `true` when vibration effects can be requested.
|
|
52
|
+
*/
|
|
53
|
+
get vibrationSupported() {
|
|
54
|
+
return this.#gamepadInput.vibrationSupported;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
47
57
|
* Forwards an input connection event to the overridable lifecycle hook.
|
|
48
58
|
*
|
|
49
59
|
* @param event - Input event containing the connected gamepad snapshot.
|
|
@@ -74,6 +84,31 @@ var GamepadControls = class extends EventDispatcher {
|
|
|
74
84
|
this.onUpdate(deltaTime);
|
|
75
85
|
}
|
|
76
86
|
/**
|
|
87
|
+
* Plays an effect through the active gamepad's primary vibration actuator.
|
|
88
|
+
*
|
|
89
|
+
* Missing browser, gamepad, or effect support is treated as a safe no-op.
|
|
90
|
+
* Environmental failures such as a hidden document are also ignored.
|
|
91
|
+
* Invalid parameters and unexpected failures remain rejected.
|
|
92
|
+
*
|
|
93
|
+
* @param type - Haptic effect type to play.
|
|
94
|
+
* @param parameters - Optional parameters describing the effect.
|
|
95
|
+
* @returns The browser result, or `null` when the effect is ignored.
|
|
96
|
+
*/
|
|
97
|
+
playVibrationEffect(type, parameters) {
|
|
98
|
+
return this.#gamepadInput.playVibrationEffect(type, parameters);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Stops the active effect on the gamepad's primary vibration actuator.
|
|
102
|
+
*
|
|
103
|
+
* Missing or temporarily unavailable haptics are treated as a safe no-op.
|
|
104
|
+
* Unexpected failures remain rejected.
|
|
105
|
+
*
|
|
106
|
+
* @returns The browser result, or `null` when reset is ignored.
|
|
107
|
+
*/
|
|
108
|
+
resetVibration() {
|
|
109
|
+
return this.#gamepadInput.resetVibration();
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
77
112
|
* Removes all event listeners attached by this controller. Call when no longer needed.
|
|
78
113
|
*/
|
|
79
114
|
dispose() {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GamepadControls, GamepadControlsOptions } from "./gamepad-controls.js";
|
|
2
2
|
import { FirstPersonControls } from "three/addons/controls/FirstPersonControls.js";
|
|
3
|
-
|
|
4
3
|
//#region src/gamepad-first-person-controls.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Configuration for {@link GamepadFirstPersonControls}.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
//#region src/gamepad-haptics.ts
|
|
2
|
+
/**
|
|
3
|
+
* Returns the primary vibration actuator exposed by a gamepad at runtime.
|
|
4
|
+
*
|
|
5
|
+
* The DOM types follow the specification and declare `vibrationActuator` as
|
|
6
|
+
* always present, while browsers without haptic support may omit it entirely.
|
|
7
|
+
* Access failures are treated as lack of support.
|
|
8
|
+
*
|
|
9
|
+
* @param gamepad - Active gamepad snapshot, or `null`.
|
|
10
|
+
* @returns The runtime actuator, or `null` when unavailable.
|
|
11
|
+
*/
|
|
12
|
+
const getGamepadVibrationActuator = (gamepad) => {
|
|
13
|
+
if (gamepad === null) return null;
|
|
14
|
+
try {
|
|
15
|
+
return gamepad.vibrationActuator ?? null;
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Identifies environmental haptics failures that should degrade to a no-op.
|
|
22
|
+
*
|
|
23
|
+
* `NotSupportedError` means the actuator cannot play the requested effect.
|
|
24
|
+
* `InvalidStateError` means the document cannot currently issue the effect,
|
|
25
|
+
* such as while it is hidden. Parameter errors intentionally remain visible.
|
|
26
|
+
*
|
|
27
|
+
* @param error - Rejection reason returned by the browser.
|
|
28
|
+
* @returns Whether the failure should be ignored as unavailable haptics.
|
|
29
|
+
*/
|
|
30
|
+
const isIgnorableHapticsError = (error) => {
|
|
31
|
+
if (typeof error !== "object" || error === null || !("name" in error)) return false;
|
|
32
|
+
const { name } = error;
|
|
33
|
+
return name === "NotSupportedError" || name === "InvalidStateError";
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Returns whether the active gamepad exposes the current vibration API.
|
|
37
|
+
*
|
|
38
|
+
* This detects actuator and method availability, not support for a particular
|
|
39
|
+
* haptic effect type.
|
|
40
|
+
*
|
|
41
|
+
* @param gamepad - Active gamepad snapshot, or `null`.
|
|
42
|
+
* @returns `true` when `vibrationActuator.playEffect` is callable.
|
|
43
|
+
*/
|
|
44
|
+
const isGamepadVibrationSupported = (gamepad) => {
|
|
45
|
+
return typeof getGamepadVibrationActuator(gamepad)?.playEffect === "function";
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Plays a haptic effect through the current primary vibration actuator.
|
|
49
|
+
*
|
|
50
|
+
* Unsupported or temporarily unavailable haptics resolve to `null`. Invalid
|
|
51
|
+
* parameters and other unexpected failures remain rejected.
|
|
52
|
+
*
|
|
53
|
+
* @param gamepad - Active gamepad snapshot, or `null`.
|
|
54
|
+
* @param type - Haptic effect type to play.
|
|
55
|
+
* @param parameters - Optional parameters describing the effect.
|
|
56
|
+
* @returns The browser result, or `null` when the effect is ignored.
|
|
57
|
+
*/
|
|
58
|
+
const playGamepadVibrationEffect = async (gamepad, type, parameters) => {
|
|
59
|
+
const actuator = getGamepadVibrationActuator(gamepad);
|
|
60
|
+
if (typeof actuator?.playEffect !== "function") return null;
|
|
61
|
+
try {
|
|
62
|
+
return await actuator.playEffect(type, parameters);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (isIgnorableHapticsError(error)) return null;
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Stops the active effect on the current primary vibration actuator.
|
|
70
|
+
*
|
|
71
|
+
* Unsupported or temporarily unavailable haptics resolve to `null`.
|
|
72
|
+
* Unexpected failures remain rejected.
|
|
73
|
+
*
|
|
74
|
+
* @param gamepad - Active gamepad snapshot, or `null`.
|
|
75
|
+
* @returns The browser result, or `null` when reset is ignored.
|
|
76
|
+
*/
|
|
77
|
+
const resetGamepadVibration = async (gamepad) => {
|
|
78
|
+
const actuator = getGamepadVibrationActuator(gamepad);
|
|
79
|
+
if (typeof actuator?.reset !== "function") return null;
|
|
80
|
+
try {
|
|
81
|
+
return await actuator.reset();
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (isIgnorableHapticsError(error)) return null;
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { isGamepadVibrationSupported, playGamepadVibrationEffect, resetGamepadVibration };
|
package/dist/gamepad-input.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { EventDispatcher } from "three";
|
|
2
|
-
|
|
3
2
|
//#region src/gamepad-input.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Event map for {@link GamepadInput}.
|
|
@@ -37,7 +36,8 @@ type GamepadInputOptions = {
|
|
|
37
36
|
* Browser-assigned gamepad slot to use.
|
|
38
37
|
*
|
|
39
38
|
* When omitted, the connected gamepad with the lowest index is selected.
|
|
40
|
-
* The index must be an integer
|
|
39
|
+
* The index must be an integer from `MIN_GAMEPAD_INDEX` through
|
|
40
|
+
* `MAX_GAMEPAD_INDEX`.
|
|
41
41
|
* A valid but empty slot keeps this input disconnected without falling back
|
|
42
42
|
* to another gamepad.
|
|
43
43
|
*/
|
|
@@ -81,8 +81,8 @@ declare class GamepadInput extends EventDispatcher<GamepadInputEventMap> {
|
|
|
81
81
|
* Creates a gamepad input reader.
|
|
82
82
|
*
|
|
83
83
|
* @param options - Optional overrides for the default input behavior.
|
|
84
|
-
* @throws {RangeError} When `gamepadIndex` is not an integer
|
|
85
|
-
*
|
|
84
|
+
* @throws {RangeError} When `gamepadIndex` is not an integer from
|
|
85
|
+
* `MIN_GAMEPAD_INDEX` through `MAX_GAMEPAD_INDEX`.
|
|
86
86
|
*/
|
|
87
87
|
constructor(options?: Partial<GamepadInputOptions>);
|
|
88
88
|
/**
|
|
@@ -109,6 +109,14 @@ declare class GamepadInput extends EventDispatcher<GamepadInputEventMap> {
|
|
|
109
109
|
* @returns The raw active gamepad snapshot, or `null`.
|
|
110
110
|
*/
|
|
111
111
|
get rawGamepad(): Gamepad | null;
|
|
112
|
+
/**
|
|
113
|
+
* Whether the active gamepad exposes a callable primary vibration actuator.
|
|
114
|
+
*
|
|
115
|
+
* This does not guarantee support for every {@link GamepadHapticEffectType}.
|
|
116
|
+
*
|
|
117
|
+
* @returns `true` when vibration effects can be requested.
|
|
118
|
+
*/
|
|
119
|
+
get vibrationSupported(): boolean;
|
|
112
120
|
/**
|
|
113
121
|
* Polls the gamepad and refreshes current and previous button state.
|
|
114
122
|
*/
|
|
@@ -162,6 +170,27 @@ declare class GamepadInput extends EventDispatcher<GamepadInputEventMap> {
|
|
|
162
170
|
* @returns Object containing processed `x` and `y` values.
|
|
163
171
|
*/
|
|
164
172
|
stick(xAxis: number, yAxis: number, options?: GamepadAxisOptions): GamepadStick;
|
|
173
|
+
/**
|
|
174
|
+
* Plays an effect through the active gamepad's primary vibration actuator.
|
|
175
|
+
*
|
|
176
|
+
* Missing browser, gamepad, or effect support is treated as a safe no-op.
|
|
177
|
+
* Environmental failures such as a hidden document are also ignored.
|
|
178
|
+
* Invalid parameters and unexpected failures remain rejected.
|
|
179
|
+
*
|
|
180
|
+
* @param type - Haptic effect type to play.
|
|
181
|
+
* @param parameters - Optional parameters describing the effect.
|
|
182
|
+
* @returns The browser result, or `null` when the effect is ignored.
|
|
183
|
+
*/
|
|
184
|
+
playVibrationEffect(type: GamepadHapticEffectType, parameters?: GamepadEffectParameters): Promise<GamepadHapticsResult | null>;
|
|
185
|
+
/**
|
|
186
|
+
* Stops the active effect on the gamepad's primary vibration actuator.
|
|
187
|
+
*
|
|
188
|
+
* Missing or temporarily unavailable haptics are treated as a safe no-op.
|
|
189
|
+
* Unexpected failures remain rejected.
|
|
190
|
+
*
|
|
191
|
+
* @returns The browser result, or `null` when reset is ignored.
|
|
192
|
+
*/
|
|
193
|
+
resetVibration(): Promise<GamepadHapticsResult | null>;
|
|
165
194
|
}
|
|
166
195
|
//#endregion
|
|
167
196
|
export { GamepadAxisOptions, GamepadInput, GamepadInputEventMap, GamepadInputOptions, GamepadStick };
|
package/dist/gamepad-input.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isGamepadVibrationSupported, playGamepadVibrationEffect, resetGamepadVibration } from "./gamepad-haptics.js";
|
|
1
2
|
import { GamepadManager } from "./gamepad-manager.js";
|
|
2
3
|
import { EventDispatcher } from "three";
|
|
3
4
|
//#region src/gamepad-input.ts
|
|
@@ -65,8 +66,8 @@ var GamepadInput = class extends EventDispatcher {
|
|
|
65
66
|
* Creates a gamepad input reader.
|
|
66
67
|
*
|
|
67
68
|
* @param options - Optional overrides for the default input behavior.
|
|
68
|
-
* @throws {RangeError} When `gamepadIndex` is not an integer
|
|
69
|
-
*
|
|
69
|
+
* @throws {RangeError} When `gamepadIndex` is not an integer from
|
|
70
|
+
* `MIN_GAMEPAD_INDEX` through `MAX_GAMEPAD_INDEX`.
|
|
70
71
|
*/
|
|
71
72
|
constructor(options) {
|
|
72
73
|
super();
|
|
@@ -131,6 +132,16 @@ var GamepadInput = class extends EventDispatcher {
|
|
|
131
132
|
return this.#gamepad;
|
|
132
133
|
}
|
|
133
134
|
/**
|
|
135
|
+
* Whether the active gamepad exposes a callable primary vibration actuator.
|
|
136
|
+
*
|
|
137
|
+
* This does not guarantee support for every {@link GamepadHapticEffectType}.
|
|
138
|
+
*
|
|
139
|
+
* @returns `true` when vibration effects can be requested.
|
|
140
|
+
*/
|
|
141
|
+
get vibrationSupported() {
|
|
142
|
+
return isGamepadVibrationSupported(this.#gamepad);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
134
145
|
* Polls the gamepad and refreshes current and previous button state.
|
|
135
146
|
*/
|
|
136
147
|
update() {
|
|
@@ -213,7 +224,8 @@ var GamepadInput = class extends EventDispatcher {
|
|
|
213
224
|
* @returns Axis value after dead zone processing, or `0` when unavailable.
|
|
214
225
|
*/
|
|
215
226
|
axis(axis, options) {
|
|
216
|
-
|
|
227
|
+
const value = this.#gamepad?.axes[axis] ?? 0;
|
|
228
|
+
return applyGamepadDeadzone(value, this.#getDeadzone(options));
|
|
217
229
|
}
|
|
218
230
|
/**
|
|
219
231
|
* Returns a two-axis stick after dead zone processing.
|
|
@@ -230,6 +242,31 @@ var GamepadInput = class extends EventDispatcher {
|
|
|
230
242
|
};
|
|
231
243
|
}
|
|
232
244
|
/**
|
|
245
|
+
* Plays an effect through the active gamepad's primary vibration actuator.
|
|
246
|
+
*
|
|
247
|
+
* Missing browser, gamepad, or effect support is treated as a safe no-op.
|
|
248
|
+
* Environmental failures such as a hidden document are also ignored.
|
|
249
|
+
* Invalid parameters and unexpected failures remain rejected.
|
|
250
|
+
*
|
|
251
|
+
* @param type - Haptic effect type to play.
|
|
252
|
+
* @param parameters - Optional parameters describing the effect.
|
|
253
|
+
* @returns The browser result, or `null` when the effect is ignored.
|
|
254
|
+
*/
|
|
255
|
+
playVibrationEffect(type, parameters) {
|
|
256
|
+
return playGamepadVibrationEffect(this.#gamepad, type, parameters);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Stops the active effect on the gamepad's primary vibration actuator.
|
|
260
|
+
*
|
|
261
|
+
* Missing or temporarily unavailable haptics are treated as a safe no-op.
|
|
262
|
+
* Unexpected failures remain rejected.
|
|
263
|
+
*
|
|
264
|
+
* @returns The browser result, or `null` when reset is ignored.
|
|
265
|
+
*/
|
|
266
|
+
resetVibration() {
|
|
267
|
+
return resetGamepadVibration(this.#gamepad);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
233
270
|
* Handles a browser connection event and adopts the gamepad when possible.
|
|
234
271
|
*
|
|
235
272
|
* Button state is seeded as both current and previous so an already-held
|
package/dist/gamepad-manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { MAX_GAMEPAD_INDEX } from "./core.js";
|
|
1
2
|
//#region src/gamepad-manager.ts
|
|
2
|
-
const MAX_GAMEPAD_INDEX = 2147483647;
|
|
3
3
|
const EMPTY_UPDATE_RESULT = {
|
|
4
4
|
gamepad: null,
|
|
5
5
|
connected: null,
|
|
@@ -151,11 +151,11 @@ var GamepadManager = class {
|
|
|
151
151
|
* @param gamepadIndex - Browser-assigned gamepad index option.
|
|
152
152
|
* @returns Internal active-gamepad selection mode.
|
|
153
153
|
* @throws {RangeError} When the explicit index is not an integer in the
|
|
154
|
-
* inclusive range
|
|
154
|
+
* inclusive range [{@link MIN_GAMEPAD_INDEX}, {@link MAX_GAMEPAD_INDEX}].
|
|
155
155
|
*/
|
|
156
156
|
#resolveSelection(gamepadIndex) {
|
|
157
157
|
if (gamepadIndex === void 0) return { type: "first-available" };
|
|
158
|
-
if (!Number.isInteger(gamepadIndex) || gamepadIndex < 0 || gamepadIndex >
|
|
158
|
+
if (!Number.isInteger(gamepadIndex) || gamepadIndex < 0 || gamepadIndex > 2147483647) throw new RangeError(`gamepadIndex must be an integer between 0 and ${MAX_GAMEPAD_INDEX}.`);
|
|
159
159
|
return {
|
|
160
160
|
type: "index",
|
|
161
161
|
index: gamepadIndex
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GamepadControls, GamepadControlsOptions } from "./gamepad-controls.js";
|
|
2
2
|
import { PointerLockControls } from "three/addons/controls/PointerLockControls.js";
|
|
3
|
-
|
|
4
3
|
//#region src/gamepad-pointer-lock-controls.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Configuration for {@link GamepadPointerLockControls}.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GamepadControls, GamepadControlsOptions } from "./gamepad-controls.js";
|
|
2
2
|
import { TrackballControls } from "three/addons/controls/TrackballControls.js";
|
|
3
|
-
|
|
4
3
|
//#region src/gamepad-trackball-controls.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Configuration for {@link GamepadTrackballControls}.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GamepadControls, GamepadControlsOptions } from "./gamepad-controls.js";
|
|
2
2
|
import { TransformControls } from "three/addons/controls/TransformControls.js";
|
|
3
|
-
|
|
4
3
|
//#region src/gamepad-transform-controls.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Configuration for {@link GamepadTransformControls}.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue } from "./core.js";
|
|
1
|
+
import { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX } from "./core.js";
|
|
2
2
|
import { GamepadAxisOptions, GamepadInput, GamepadInputEventMap, GamepadInputOptions, GamepadStick } from "./gamepad-input.js";
|
|
3
3
|
import { GamepadControls, GamepadControlsEventMap, GamepadControlsOptions } from "./gamepad-controls.js";
|
|
4
4
|
import { GamepadArcballControls, GamepadArcballControlsOptions } from "./gamepad-arcball-controls.js";
|
|
@@ -10,4 +10,4 @@ import { GamepadMapControls } from "./gamepad-map-controls.js";
|
|
|
10
10
|
import { GamepadPointerLockControls, GamepadPointerLockControlsOptions } from "./gamepad-pointer-lock-controls.js";
|
|
11
11
|
import { GamepadTrackballControls, GamepadTrackballControlsOptions } from "./gamepad-trackball-controls.js";
|
|
12
12
|
import { GamepadTransformControls, GamepadTransformControlsOptions } from "./gamepad-transform-controls.js";
|
|
13
|
-
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadArcballControlsOptions, GamepadAxisKey, GamepadAxisOptions, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, GamepadControls, GamepadControlsEventMap, GamepadControlsOptions, GamepadDragControls, GamepadDragControlsOptions, GamepadFirstPersonControls, GamepadFirstPersonControlsOptions, GamepadFlyControls, GamepadFlyControlsOptions, GamepadInput, GamepadInputEventMap, GamepadInputOptions, GamepadMapControls, GamepadOrbitControls, GamepadOrbitControlsOptions, GamepadPointerLockControls, GamepadPointerLockControlsOptions, GamepadStick, GamepadTrackballControls, GamepadTrackballControlsOptions, GamepadTransformControls, GamepadTransformControlsOptions };
|
|
13
|
+
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadArcballControlsOptions, GamepadAxisKey, GamepadAxisOptions, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, GamepadControls, GamepadControlsEventMap, GamepadControlsOptions, GamepadDragControls, GamepadDragControlsOptions, GamepadFirstPersonControls, GamepadFirstPersonControlsOptions, GamepadFlyControls, GamepadFlyControlsOptions, GamepadInput, GamepadInputEventMap, GamepadInputOptions, GamepadMapControls, GamepadOrbitControls, GamepadOrbitControlsOptions, GamepadPointerLockControls, GamepadPointerLockControlsOptions, GamepadStick, GamepadTrackballControls, GamepadTrackballControlsOptions, GamepadTransformControls, GamepadTransformControlsOptions, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GAMEPAD_AXIS, GAMEPAD_BUTTON } from "./core.js";
|
|
1
|
+
import { GAMEPAD_AXIS, GAMEPAD_BUTTON, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX } from "./core.js";
|
|
2
2
|
import { GamepadInput } from "./gamepad-input.js";
|
|
3
3
|
import { GamepadControls } from "./gamepad-controls.js";
|
|
4
4
|
import { GamepadArcballControls } from "./gamepad-arcball-controls.js";
|
|
@@ -10,4 +10,4 @@ import { GamepadMapControls } from "./gamepad-map-controls.js";
|
|
|
10
10
|
import { GamepadPointerLockControls } from "./gamepad-pointer-lock-controls.js";
|
|
11
11
|
import { GamepadTrackballControls } from "./gamepad-trackball-controls.js";
|
|
12
12
|
import { GamepadTransformControls } from "./gamepad-transform-controls.js";
|
|
13
|
-
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadControls, GamepadDragControls, GamepadFirstPersonControls, GamepadFlyControls, GamepadInput, GamepadMapControls, GamepadOrbitControls, GamepadPointerLockControls, GamepadTrackballControls, GamepadTransformControls };
|
|
13
|
+
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadArcballControls, GamepadControls, GamepadDragControls, GamepadFirstPersonControls, GamepadFlyControls, GamepadInput, GamepadMapControls, GamepadOrbitControls, GamepadPointerLockControls, GamepadTrackballControls, GamepadTransformControls, MAX_GAMEPAD_INDEX, MIN_GAMEPAD_INDEX };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "three-gamepad-controls",
|
|
3
3
|
"description": "Gamepad support for Three.js controls.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"homepage": "https://github.com/luckasnix/three-gamepad-controls#readme",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Kasnix",
|
|
@@ -46,16 +46,16 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@biomejs/biome": "2.5.
|
|
50
|
-
"@commitlint/cli": "21.2.
|
|
49
|
+
"@biomejs/biome": "2.5.4",
|
|
50
|
+
"@commitlint/cli": "21.2.1",
|
|
51
51
|
"@commitlint/config-conventional": "21.2.0",
|
|
52
52
|
"@commitlint/types": "21.2.0",
|
|
53
|
-
"@types/node": "24.13.
|
|
53
|
+
"@types/node": "24.13.3",
|
|
54
54
|
"@types/three": "0.184.0",
|
|
55
55
|
"husky": "9.1.7",
|
|
56
56
|
"three": "0.184.0",
|
|
57
|
-
"tsdown": "0.22.
|
|
58
|
-
"typescript": "
|
|
57
|
+
"tsdown": "0.22.8",
|
|
58
|
+
"typescript": "7.0.2"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@types/three": ">=0.184.0",
|