three-gamepad-controls 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.
- package/LICENSE +21 -0
- package/README.md +8 -0
- package/dist/core.d.ts +52 -0
- package/dist/core.js +36 -0
- package/dist/gamepad-controls.d.ts +79 -0
- package/dist/gamepad-controls.js +90 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lucas Alves Costa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Three.js Gamepad Controls
|
|
2
|
+
|
|
3
|
+
Gamepad support for [Three.js](https://threejs.org) controls, built on top of [Web Gamepad API](https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API).
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- [Core](./docs/core.md) — The fundamental building blocks.
|
|
8
|
+
- [GamepadControls](./docs/gamepad-controls.md) — Abstract base class for custom gamepad controls.
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/core.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Button indices for the W3C Standard Gamepad mapping.
|
|
4
|
+
* @see https://www.w3.org/TR/gamepad/#dfn-standard-gamepad
|
|
5
|
+
*/
|
|
6
|
+
declare const GAMEPAD_BUTTON: {
|
|
7
|
+
readonly South: 0;
|
|
8
|
+
readonly East: 1;
|
|
9
|
+
readonly West: 2;
|
|
10
|
+
readonly North: 3;
|
|
11
|
+
readonly LeftShoulder: 4;
|
|
12
|
+
readonly RightShoulder: 5;
|
|
13
|
+
readonly LeftTrigger: 6;
|
|
14
|
+
readonly RightTrigger: 7;
|
|
15
|
+
readonly Select: 8;
|
|
16
|
+
readonly Start: 9;
|
|
17
|
+
readonly LeftStick: 10;
|
|
18
|
+
readonly RightStick: 11;
|
|
19
|
+
readonly DPadUp: 12;
|
|
20
|
+
readonly DPadDown: 13;
|
|
21
|
+
readonly DPadLeft: 14;
|
|
22
|
+
readonly DPadRight: 15;
|
|
23
|
+
readonly Home: 16;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Axis indices for the W3C Standard Gamepad mapping.
|
|
27
|
+
* @see https://www.w3.org/TR/gamepad/#dfn-standard-gamepad
|
|
28
|
+
*/
|
|
29
|
+
declare const GAMEPAD_AXIS: {
|
|
30
|
+
readonly LeftX: 0;
|
|
31
|
+
readonly LeftY: 1;
|
|
32
|
+
readonly RightX: 2;
|
|
33
|
+
readonly RightY: 3;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Union type of all valid {@link GAMEPAD_BUTTON} keys.
|
|
37
|
+
*/
|
|
38
|
+
type GamepadButtonKey = keyof typeof GAMEPAD_BUTTON;
|
|
39
|
+
/**
|
|
40
|
+
* Union type of all valid {@link GAMEPAD_BUTTON} values.
|
|
41
|
+
*/
|
|
42
|
+
type GamepadButtonValue = (typeof GAMEPAD_BUTTON)[keyof typeof GAMEPAD_BUTTON];
|
|
43
|
+
/**
|
|
44
|
+
* Union type of all valid {@link GAMEPAD_AXIS} keys.
|
|
45
|
+
*/
|
|
46
|
+
type GamepadAxisKey = keyof typeof GAMEPAD_AXIS;
|
|
47
|
+
/**
|
|
48
|
+
* Union type of all valid {@link GAMEPAD_AXIS} values.
|
|
49
|
+
*/
|
|
50
|
+
type GamepadAxisValue = (typeof GAMEPAD_AXIS)[keyof typeof GAMEPAD_AXIS];
|
|
51
|
+
//#endregion
|
|
52
|
+
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue };
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/core.ts
|
|
2
|
+
/**
|
|
3
|
+
* Button indices for the W3C Standard Gamepad mapping.
|
|
4
|
+
* @see https://www.w3.org/TR/gamepad/#dfn-standard-gamepad
|
|
5
|
+
*/
|
|
6
|
+
const GAMEPAD_BUTTON = {
|
|
7
|
+
South: 0,
|
|
8
|
+
East: 1,
|
|
9
|
+
West: 2,
|
|
10
|
+
North: 3,
|
|
11
|
+
LeftShoulder: 4,
|
|
12
|
+
RightShoulder: 5,
|
|
13
|
+
LeftTrigger: 6,
|
|
14
|
+
RightTrigger: 7,
|
|
15
|
+
Select: 8,
|
|
16
|
+
Start: 9,
|
|
17
|
+
LeftStick: 10,
|
|
18
|
+
RightStick: 11,
|
|
19
|
+
DPadUp: 12,
|
|
20
|
+
DPadDown: 13,
|
|
21
|
+
DPadLeft: 14,
|
|
22
|
+
DPadRight: 15,
|
|
23
|
+
Home: 16
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Axis indices for the W3C Standard Gamepad mapping.
|
|
27
|
+
* @see https://www.w3.org/TR/gamepad/#dfn-standard-gamepad
|
|
28
|
+
*/
|
|
29
|
+
const GAMEPAD_AXIS = {
|
|
30
|
+
LeftX: 0,
|
|
31
|
+
LeftY: 1,
|
|
32
|
+
RightX: 2,
|
|
33
|
+
RightY: 3
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { GAMEPAD_AXIS, GAMEPAD_BUTTON };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { EventDispatcher } from "three";
|
|
2
|
+
|
|
3
|
+
//#region src/gamepad-controls.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Event map for {@link GamepadControls}.
|
|
6
|
+
*
|
|
7
|
+
* Each key is an event name, and its value is the extra data included in the event object
|
|
8
|
+
* alongside the standard `type` and `target` fields.
|
|
9
|
+
*/
|
|
10
|
+
type GamepadControlsEventMap = {
|
|
11
|
+
/**
|
|
12
|
+
* Fired when a gamepad is connected and set as the active gamepad.
|
|
13
|
+
*/
|
|
14
|
+
connected: {
|
|
15
|
+
gamepad: Gamepad;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Fired when the active gamepad is disconnected.
|
|
19
|
+
*/
|
|
20
|
+
disconnected: {
|
|
21
|
+
gamepad: Gamepad;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Abstract base class for Three.js gamepad controls.
|
|
26
|
+
*
|
|
27
|
+
* Handles the gamepad connection lifecycle and input polling so subclasses
|
|
28
|
+
* only need to implement {@link onUpdate}.
|
|
29
|
+
*/
|
|
30
|
+
declare abstract class GamepadControls extends EventDispatcher<GamepadControlsEventMap> {
|
|
31
|
+
#private;
|
|
32
|
+
/**
|
|
33
|
+
* When `false`, all input processing is paused.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
enabled: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The currently active gamepad, or `null` if no gamepad is connected.
|
|
39
|
+
*/
|
|
40
|
+
gamepad: Gamepad | null;
|
|
41
|
+
constructor();
|
|
42
|
+
/**
|
|
43
|
+
* Advances the controller by one frame. Call this inside your render loop.
|
|
44
|
+
*
|
|
45
|
+
* @param deltaTime - Seconds since the last frame.
|
|
46
|
+
*/
|
|
47
|
+
update(deltaTime: number): void;
|
|
48
|
+
/**
|
|
49
|
+
* Removes all event listeners attached by this controller. Call when no longer needed.
|
|
50
|
+
*/
|
|
51
|
+
dispose(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Called every frame when a gamepad is available and `enabled` is `true`.
|
|
54
|
+
*
|
|
55
|
+
* @param deltaTime - Seconds since the last frame.
|
|
56
|
+
* @param gamepad - A fresh snapshot of the currently active gamepad.
|
|
57
|
+
*/
|
|
58
|
+
protected abstract onUpdate(deltaTime: number, gamepad: Gamepad): void;
|
|
59
|
+
/**
|
|
60
|
+
* Called when any gamepad fires a `gamepadconnected` event.
|
|
61
|
+
*
|
|
62
|
+
* The default accepts the first gamepad that connects and dispatches `connected`.
|
|
63
|
+
* Override to customize selection behavior.
|
|
64
|
+
*
|
|
65
|
+
* @param gamepad - The gamepad that just connected.
|
|
66
|
+
*/
|
|
67
|
+
protected onGamepadConnected(gamepad: Gamepad): void;
|
|
68
|
+
/**
|
|
69
|
+
* Called when any gamepad fires a `gamepaddisconnected` event.
|
|
70
|
+
*
|
|
71
|
+
* The default clears `this.gamepad` and dispatches `disconnected` if the
|
|
72
|
+
* disconnecting gamepad was the active one. Override to add custom cleanup.
|
|
73
|
+
*
|
|
74
|
+
* @param gamepad - The gamepad that just disconnected.
|
|
75
|
+
*/
|
|
76
|
+
protected onGamepadDisconnected(gamepad: Gamepad): void;
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
export { GamepadControls, GamepadControlsEventMap };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { EventDispatcher } from "three";
|
|
2
|
+
//#region src/gamepad-controls.ts
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for Three.js gamepad controls.
|
|
5
|
+
*
|
|
6
|
+
* Handles the gamepad connection lifecycle and input polling so subclasses
|
|
7
|
+
* only need to implement {@link onUpdate}.
|
|
8
|
+
*/
|
|
9
|
+
var GamepadControls = class extends EventDispatcher {
|
|
10
|
+
/**
|
|
11
|
+
* When `false`, all input processing is paused.
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
enabled = true;
|
|
15
|
+
/**
|
|
16
|
+
* The currently active gamepad, or `null` if no gamepad is connected.
|
|
17
|
+
*/
|
|
18
|
+
gamepad = null;
|
|
19
|
+
#onGamepadConnected;
|
|
20
|
+
#onGamepadDisconnected;
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this.#onGamepadConnected = (event) => {
|
|
24
|
+
this.onGamepadConnected(event.gamepad);
|
|
25
|
+
};
|
|
26
|
+
this.#onGamepadDisconnected = (event) => {
|
|
27
|
+
this.onGamepadDisconnected(event.gamepad);
|
|
28
|
+
};
|
|
29
|
+
window.addEventListener("gamepadconnected", this.#onGamepadConnected);
|
|
30
|
+
window.addEventListener("gamepaddisconnected", this.#onGamepadDisconnected);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Advances the controller by one frame. Call this inside your render loop.
|
|
34
|
+
*
|
|
35
|
+
* @param deltaTime - Seconds since the last frame.
|
|
36
|
+
*/
|
|
37
|
+
update(deltaTime) {
|
|
38
|
+
if (!this.enabled) return;
|
|
39
|
+
if (this.gamepad !== null) {
|
|
40
|
+
const gamepads = navigator.getGamepads();
|
|
41
|
+
this.gamepad = gamepads[this.gamepad.index] ?? null;
|
|
42
|
+
}
|
|
43
|
+
if (this.gamepad === null) return;
|
|
44
|
+
this.onUpdate(deltaTime, this.gamepad);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Removes all event listeners attached by this controller. Call when no longer needed.
|
|
48
|
+
*/
|
|
49
|
+
dispose() {
|
|
50
|
+
window.removeEventListener("gamepadconnected", this.#onGamepadConnected);
|
|
51
|
+
window.removeEventListener("gamepaddisconnected", this.#onGamepadDisconnected);
|
|
52
|
+
this.gamepad = null;
|
|
53
|
+
this.enabled = false;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Called when any gamepad fires a `gamepadconnected` event.
|
|
57
|
+
*
|
|
58
|
+
* The default accepts the first gamepad that connects and dispatches `connected`.
|
|
59
|
+
* Override to customize selection behavior.
|
|
60
|
+
*
|
|
61
|
+
* @param gamepad - The gamepad that just connected.
|
|
62
|
+
*/
|
|
63
|
+
onGamepadConnected(gamepad) {
|
|
64
|
+
if (this.gamepad !== null) return;
|
|
65
|
+
this.gamepad = gamepad;
|
|
66
|
+
this.dispatchEvent({
|
|
67
|
+
type: "connected",
|
|
68
|
+
gamepad
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Called when any gamepad fires a `gamepaddisconnected` event.
|
|
73
|
+
*
|
|
74
|
+
* The default clears `this.gamepad` and dispatches `disconnected` if the
|
|
75
|
+
* disconnecting gamepad was the active one. Override to add custom cleanup.
|
|
76
|
+
*
|
|
77
|
+
* @param gamepad - The gamepad that just disconnected.
|
|
78
|
+
*/
|
|
79
|
+
onGamepadDisconnected(gamepad) {
|
|
80
|
+
if (this.gamepad?.index !== gamepad.index) return;
|
|
81
|
+
const disconnected = this.gamepad;
|
|
82
|
+
this.gamepad = null;
|
|
83
|
+
this.dispatchEvent({
|
|
84
|
+
type: "disconnected",
|
|
85
|
+
gamepad: disconnected
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
//#endregion
|
|
90
|
+
export { GamepadControls };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue } from "./core.js";
|
|
2
|
+
import { GamepadControls, GamepadControlsEventMap } from "./gamepad-controls.js";
|
|
3
|
+
export { GAMEPAD_AXIS, GAMEPAD_BUTTON, GamepadAxisKey, GamepadAxisValue, GamepadButtonKey, GamepadButtonValue, GamepadControls, GamepadControlsEventMap };
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "three-gamepad-controls",
|
|
3
|
+
"description": "Gamepad support for Three.js controls.",
|
|
4
|
+
"author": "Kasnix",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/luckasnix/three-gamepad-controls.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"javascript",
|
|
25
|
+
"typescript",
|
|
26
|
+
"three",
|
|
27
|
+
"controls",
|
|
28
|
+
"gamepad"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=24.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@biomejs/biome": "2.4.15",
|
|
39
|
+
"@commitlint/cli": "21.0.1",
|
|
40
|
+
"@commitlint/config-conventional": "21.0.1",
|
|
41
|
+
"@commitlint/types": "21.0.1",
|
|
42
|
+
"@types/node": "24.12.4",
|
|
43
|
+
"@types/three": "0.184.1",
|
|
44
|
+
"husky": "9.1.7",
|
|
45
|
+
"three": "0.184.0",
|
|
46
|
+
"tsdown": "0.22.0",
|
|
47
|
+
"typescript": "6.0.3"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@types/three": ">=0.184.1",
|
|
51
|
+
"three": ">=0.184.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc && tsdown",
|
|
55
|
+
"type:check": "tsc --noEmit",
|
|
56
|
+
"format:check": "biome format",
|
|
57
|
+
"format:write": "biome format --write",
|
|
58
|
+
"lint:check": "biome lint",
|
|
59
|
+
"lint:write": "biome lint --write",
|
|
60
|
+
"check-all": "biome check",
|
|
61
|
+
"write-all": "biome check --write",
|
|
62
|
+
"check-ci": "biome ci"
|
|
63
|
+
}
|
|
64
|
+
}
|