three-gamepad-controls 0.10.6 → 0.11.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 CHANGED
@@ -37,6 +37,7 @@ bun add three-gamepad-controls
37
37
  ## 📖 Documentation
38
38
 
39
39
  - [Core](./docs/core.md) — The fundamental building blocks.
40
+ - [GamepadInput](./docs/gamepad-input.md) - Gamepad input state reader for gameplay and menus.
40
41
  - [GamepadControls](./docs/gamepad-controls.md) — Abstract base class for custom gamepad controls.
41
42
  - [GamepadArcballControls](./docs/gamepad-arcball-controls.md) - Gamepad support for `ArcballControls`.
42
43
  - [GamepadDragControls](./docs/gamepad-drag-controls.md) - Gamepad support for `DragControls`.
@@ -103,6 +103,15 @@ var GamepadArcballControls = class extends GamepadControls {
103
103
  this.#wasInteracting = activeInput;
104
104
  if (!activeInput) this.#endInteraction();
105
105
  }
106
+ /**
107
+ * Applies gamepad stick rotation through Arcball's runtime rotation helper.
108
+ *
109
+ * @param deltaTime - Seconds since the last frame.
110
+ * @param rotateX - Horizontal rotation input after dead zone processing.
111
+ * @param rotateY - Vertical rotation input after dead zone processing.
112
+ * @param rotateSpeed - User-configured rotation speed multiplier.
113
+ * @returns `true` when a rotation was applied.
114
+ */
106
115
  #applyRotation(deltaTime, rotateX, rotateY, rotateSpeed) {
107
116
  if (rotateX === 0 && rotateY === 0) return false;
108
117
  const controls = this.#controls;
@@ -119,6 +128,13 @@ var GamepadArcballControls = class extends GamepadControls {
119
128
  }
120
129
  return changed;
121
130
  }
131
+ /**
132
+ * Applies an Arcball rotation around a specific world axis.
133
+ *
134
+ * @param axis - World axis to rotate around.
135
+ * @param angle - Rotation amount in radians.
136
+ * @returns `true` when ArcballControls produced and applied a transform.
137
+ */
122
138
  #applyRotationAroundAxis(axis, angle) {
123
139
  if (axis.lengthSq() === 0 || angle === 0) return false;
124
140
  const controls = this.#controls;
@@ -128,6 +144,15 @@ var GamepadArcballControls = class extends GamepadControls {
128
144
  if (changed) controls.object.up.copy(this.#previousUp).applyAxisAngle(axis, -angle);
129
145
  return changed;
130
146
  }
147
+ /**
148
+ * Applies gamepad pan by converting stick input to Arcball trackball points.
149
+ *
150
+ * @param deltaTime - Seconds since the last frame.
151
+ * @param panX - Horizontal pan input after dead zone processing.
152
+ * @param panY - Vertical pan input after dead zone processing.
153
+ * @param panSpeed - User-configured pan speed multiplier.
154
+ * @returns `true` when a pan transform was applied.
155
+ */
131
156
  #applyPan(deltaTime, panX, panY, panSpeed) {
132
157
  if (panX === 0 && panY === 0) return false;
133
158
  const controls = this.#controls;
@@ -137,6 +162,15 @@ var GamepadArcballControls = class extends GamepadControls {
137
162
  this.#panEnd.set(panX * distance, panY * distance, 0);
138
163
  return this.#applyTransform(controls.pan(this.#panStart, this.#panEnd));
139
164
  }
165
+ /**
166
+ * Applies trigger-driven zoom around Arcball's gizmo center.
167
+ *
168
+ * @param deltaTime - Seconds since the last frame.
169
+ * @param zoom - Signed zoom input from the configured trigger pair.
170
+ * @param zoomSpeed - User-configured zoom speed multiplier.
171
+ * @param deadzone - Trigger dead zone threshold.
172
+ * @returns `true` when a zoom transform was applied.
173
+ */
140
174
  #applyZoom(deltaTime, zoom, zoomSpeed, deadzone) {
141
175
  if (Math.abs(zoom) <= deadzone || this.#controls.scaleFactor <= 0) return false;
142
176
  const controls = this.#controls;
@@ -145,6 +179,15 @@ var GamepadArcballControls = class extends GamepadControls {
145
179
  controls.updateMatrixState();
146
180
  return this.#applyTransform(controls.scale(size, controls._gizmos.position));
147
181
  }
182
+ /**
183
+ * Applies shoulder-button rotation around the current camera view axis.
184
+ *
185
+ * @param deltaTime - Seconds since the last frame.
186
+ * @param zRotation - Signed z-rotation input from the configured buttons.
187
+ * @param zRotateSpeed - User-configured z-rotation speed multiplier.
188
+ * @param deadzone - Button value dead zone threshold.
189
+ * @returns `true` when a z-rotation transform was applied.
190
+ */
148
191
  #applyZRotation(deltaTime, zRotation, zRotateSpeed, deadzone) {
149
192
  if (Math.abs(zRotation) <= deadzone) return false;
150
193
  const controls = this.#controls;
@@ -156,6 +199,12 @@ var GamepadArcballControls = class extends GamepadControls {
156
199
  if (changed) controls.object.up.copy(this.#previousUp).applyAxisAngle(controls._rotationAxis, angle);
157
200
  return changed;
158
201
  }
202
+ /**
203
+ * Focuses ArcballControls on the given point when one was consumed.
204
+ *
205
+ * @param point - World-space focus point, or `null` when no focus is pending.
206
+ * @returns `true` when focus was applied.
207
+ */
159
208
  #applyFocus(point) {
160
209
  if (point === null) return false;
161
210
  const controls = this.#controls;
@@ -164,12 +213,25 @@ var GamepadArcballControls = class extends GamepadControls {
164
213
  controls.updateMatrixState();
165
214
  return true;
166
215
  }
216
+ /**
217
+ * Applies a transformation returned by an Arcball runtime helper.
218
+ *
219
+ * @param transformation - Arcball transformation matrices, if any.
220
+ * @returns `true` when a transformation was applied.
221
+ */
167
222
  #applyTransform(transformation) {
168
223
  if (transformation === void 0) return false;
169
224
  this.#controls.applyTransformMatrix(transformation);
170
225
  this.#controls.updateMatrixState();
171
226
  return true;
172
227
  }
228
+ /**
229
+ * Consumes a focus-button press and resolves the viewport center hit point.
230
+ *
231
+ * @param gamepad - Fresh gamepad snapshot to read from.
232
+ * @param buttonFocus - Button index configured for focus.
233
+ * @returns The center hit point, or `null` when focus should not run.
234
+ */
173
235
  #consumeFocusPoint(gamepad, buttonFocus) {
174
236
  const controls = this.#controls;
175
237
  const focusPressed = getGamepadButtonPressed(gamepad, buttonFocus);
@@ -178,6 +240,9 @@ var GamepadArcballControls = class extends GamepadControls {
178
240
  if (!shouldFocus || !controls.enabled || !controls.enablePan || !controls.enableFocus || controls.scene === null) return null;
179
241
  return controls.unprojectOnObj(this.#centerNdc, controls.object);
180
242
  }
243
+ /**
244
+ * Dispatches Arcball's `end` event when an active gamepad interaction stops.
245
+ */
181
246
  #endInteraction() {
182
247
  if (!this.#wasInteracting) return;
183
248
  this.#controls.dispatchEvent({ type: "end" });
@@ -12,12 +12,18 @@ type GamepadControlsEventMap = {
12
12
  * Fired when a gamepad is connected and set as the active gamepad.
13
13
  */
14
14
  connected: {
15
+ /**
16
+ * Gamepad snapshot that became active.
17
+ */
15
18
  gamepad: Gamepad;
16
19
  };
17
20
  /**
18
21
  * Fired when the active gamepad is disconnected.
19
22
  */
20
23
  disconnected: {
24
+ /**
25
+ * Gamepad snapshot that was active before disconnection.
26
+ */
21
27
  gamepad: Gamepad;
22
28
  };
23
29
  };
@@ -38,6 +44,9 @@ declare abstract class GamepadControls extends EventDispatcher<GamepadControlsEv
38
44
  * The currently active gamepad, or `null` if no gamepad is connected.
39
45
  */
40
46
  gamepad: Gamepad | null;
47
+ /**
48
+ * Creates the base gamepad lifecycle manager and attaches browser listeners.
49
+ */
41
50
  constructor();
42
51
  /**
43
52
  * Advances the controller by one frame. Call this inside your render loop.
@@ -18,21 +18,42 @@ var GamepadControls = class extends EventDispatcher {
18
18
  */
19
19
  gamepad = null;
20
20
  #manager;
21
+ /**
22
+ * Bound browser connection listener kept so it can be removed in {@link dispose}.
23
+ */
21
24
  #onGamepadConnected;
25
+ /**
26
+ * Bound browser disconnection listener kept so it can be removed in {@link dispose}.
27
+ */
22
28
  #onGamepadDisconnected;
29
+ /**
30
+ * Creates the base gamepad lifecycle manager and attaches browser listeners.
31
+ */
23
32
  constructor() {
24
33
  super();
25
34
  this.#manager = new GamepadManager();
26
- this.#onGamepadConnected = (event) => {
27
- this.onGamepadConnected(event.gamepad);
28
- };
29
- this.#onGamepadDisconnected = (event) => {
30
- this.onGamepadDisconnected(event.gamepad);
31
- };
35
+ this.#onGamepadConnected = this.#handleGamepadConnectedEvent.bind(this);
36
+ this.#onGamepadDisconnected = this.#handleGamepadDisconnectedEvent.bind(this);
32
37
  window.addEventListener("gamepadconnected", this.#onGamepadConnected);
33
38
  window.addEventListener("gamepaddisconnected", this.#onGamepadDisconnected);
34
39
  }
35
40
  /**
41
+ * Forwards a browser connection event to the overridable lifecycle hook.
42
+ *
43
+ * @param event - Browser event containing the connected gamepad snapshot.
44
+ */
45
+ #handleGamepadConnectedEvent(event) {
46
+ this.onGamepadConnected(event.gamepad);
47
+ }
48
+ /**
49
+ * Forwards a browser disconnection event to the overridable lifecycle hook.
50
+ *
51
+ * @param event - Browser event containing the disconnected gamepad snapshot.
52
+ */
53
+ #handleGamepadDisconnectedEvent(event) {
54
+ this.onGamepadDisconnected(event.gamepad);
55
+ }
56
+ /**
36
57
  * Advances the controller by one frame. Call this inside your render loop.
37
58
  *
38
59
  * @param deltaTime - Seconds since the last frame.
@@ -111,6 +111,12 @@ var GamepadDragControls = class extends GamepadControls {
111
111
  this.#clearHover();
112
112
  super.onGamepadDisconnected(gamepad);
113
113
  }
114
+ /**
115
+ * Updates the selected object from gamepad drag and rotation input.
116
+ *
117
+ * @param deltaTime - Seconds since the last frame.
118
+ * @param gamepad - Fresh gamepad snapshot to read from.
119
+ */
114
120
  #updateSelected(deltaTime, gamepad) {
115
121
  const selected = this.#selected;
116
122
  if (selected === null) return;
@@ -126,6 +132,15 @@ var GamepadDragControls = class extends GamepadControls {
126
132
  object: selected
127
133
  });
128
134
  }
135
+ /**
136
+ * Moves the selected object in the camera-facing plane.
137
+ *
138
+ * @param deltaTime - Seconds since the last frame.
139
+ * @param dragX - Horizontal drag input after dead zone processing.
140
+ * @param dragY - Vertical drag input after dead zone processing.
141
+ * @param dragSpeed - User-configured drag speed multiplier.
142
+ * @returns `true` when the selected object moved.
143
+ */
129
144
  #applyDrag(deltaTime, dragX, dragY, dragSpeed) {
130
145
  if (this.#selected === null || dragX === 0 && dragY === 0) return false;
131
146
  this.#updateCameraAxes();
@@ -136,6 +151,15 @@ var GamepadDragControls = class extends GamepadControls {
136
151
  this.#applySelectedWorldPosition();
137
152
  return true;
138
153
  }
154
+ /**
155
+ * Rotates the selected object around camera-relative world axes.
156
+ *
157
+ * @param deltaTime - Seconds since the last frame.
158
+ * @param rotateX - Horizontal rotation input after dead zone processing.
159
+ * @param rotateY - Vertical rotation input after dead zone processing.
160
+ * @param rotateSpeed - User-configured rotation speed multiplier.
161
+ * @returns `true` when the selected object rotated.
162
+ */
139
163
  #applyRotation(deltaTime, rotateX, rotateY, rotateSpeed) {
140
164
  const selected = this.#selected;
141
165
  if (selected === null || rotateX === 0 && rotateY === 0) return false;
@@ -145,6 +169,11 @@ var GamepadDragControls = class extends GamepadControls {
145
169
  if (rotateY !== 0) selected.rotateOnWorldAxis(this.#cameraRight, rotateY * scale);
146
170
  return true;
147
171
  }
172
+ /**
173
+ * Raycasts from the center of the viewport into DragControls objects.
174
+ *
175
+ * @returns The closest center hit, or `undefined` when nothing is hit.
176
+ */
148
177
  #intersectCenter() {
149
178
  const controls = this.#controls;
150
179
  this.#intersections.length = 0;
@@ -152,6 +181,11 @@ var GamepadDragControls = class extends GamepadControls {
152
181
  controls.raycaster.intersectObjects(controls.objects, controls.recursive, this.#intersections);
153
182
  return this.#intersections[0];
154
183
  }
184
+ /**
185
+ * Updates DragControls hover state for the object under the center reticle.
186
+ *
187
+ * @param object - Object currently under the reticle, or `null`.
188
+ */
155
189
  #updateHover(object) {
156
190
  if (this.#hovered === object) return;
157
191
  this.#clearHover();
@@ -162,6 +196,9 @@ var GamepadDragControls = class extends GamepadControls {
162
196
  object
163
197
  });
164
198
  }
199
+ /**
200
+ * Clears the current hover object and dispatches `hoveroff` when needed.
201
+ */
165
202
  #clearHover() {
166
203
  if (this.#hovered === null) return;
167
204
  const object = this.#hovered;
@@ -171,6 +208,11 @@ var GamepadDragControls = class extends GamepadControls {
171
208
  object
172
209
  });
173
210
  }
211
+ /**
212
+ * Selects an object and dispatches DragControls `dragstart`.
213
+ *
214
+ * @param object - Object hit by the center reticle.
215
+ */
174
216
  #grabObject(object) {
175
217
  const selected = this.#getSelectedObject(object);
176
218
  selected.updateWorldMatrix(true, false);
@@ -181,6 +223,9 @@ var GamepadDragControls = class extends GamepadControls {
181
223
  object: selected
182
224
  });
183
225
  }
226
+ /**
227
+ * Releases the selected object and dispatches DragControls `dragend`.
228
+ */
184
229
  #releaseSelected() {
185
230
  if (this.#selected === null) return;
186
231
  const selected = this.#selected;
@@ -190,10 +235,22 @@ var GamepadDragControls = class extends GamepadControls {
190
235
  object: selected
191
236
  });
192
237
  }
238
+ /**
239
+ * Resolves which object should be dragged for a reticle hit.
240
+ *
241
+ * @param object - Object hit by the center reticle.
242
+ * @returns The hit object, or its outermost group when group dragging is enabled.
243
+ */
193
244
  #getSelectedObject(object) {
194
245
  if (!this.#controls.transformGroup) return object;
195
246
  return this.#findOutermostGroup(object) ?? object;
196
247
  }
248
+ /**
249
+ * Finds the highest ancestor that is a Three.js `Group`.
250
+ *
251
+ * @param object - Object where the ancestor search starts.
252
+ * @returns The outermost group ancestor, or `null` when none exists.
253
+ */
197
254
  #findOutermostGroup(object) {
198
255
  let group = null;
199
256
  let current = object;
@@ -203,6 +260,9 @@ var GamepadDragControls = class extends GamepadControls {
203
260
  }
204
261
  return group;
205
262
  }
263
+ /**
264
+ * Writes the accumulated world-space selected position back to the object.
265
+ */
206
266
  #applySelectedWorldPosition() {
207
267
  const selected = this.#selected;
208
268
  if (selected === null) return;
@@ -217,12 +277,18 @@ var GamepadDragControls = class extends GamepadControls {
217
277
  selected.position.copy(this.#selectedLocalPosition);
218
278
  selected.updateMatrixWorld();
219
279
  }
280
+ /**
281
+ * Refreshes camera-relative axes used for dragging and rotation.
282
+ */
220
283
  #updateCameraAxes() {
221
284
  const camera = this.#controls.object;
222
285
  this.#cameraRight.set(1, 0, 0).applyQuaternion(camera.quaternion).normalize();
223
286
  this.#cameraUp.set(0, 1, 0).applyQuaternion(camera.quaternion).normalize();
224
287
  camera.getWorldDirection(this.#cameraForward).normalize();
225
288
  }
289
+ /**
290
+ * Computes the world-space viewport size at the selected object's depth.
291
+ */
226
292
  #updateViewSizeAtSelectedDepth() {
227
293
  const camera = this.#controls.object;
228
294
  if (this.#isOrthographicCamera(camera)) {
@@ -238,9 +304,21 @@ var GamepadDragControls = class extends GamepadControls {
238
304
  }
239
305
  this.#viewSize.set(1, 1);
240
306
  }
307
+ /**
308
+ * Narrows a Three.js camera to `PerspectiveCamera`.
309
+ *
310
+ * @param camera - Camera to inspect.
311
+ * @returns `true` when the camera is perspective.
312
+ */
241
313
  #isPerspectiveCamera(camera) {
242
314
  return camera.isPerspectiveCamera === true;
243
315
  }
316
+ /**
317
+ * Narrows a Three.js camera to `OrthographicCamera`.
318
+ *
319
+ * @param camera - Camera to inspect.
320
+ * @returns `true` when the camera is orthographic.
321
+ */
244
322
  #isOrthographicCamera(camera) {
245
323
  return camera.isOrthographicCamera === true;
246
324
  }
@@ -58,6 +58,18 @@ var GamepadFirstPersonControls = class extends GamepadControls {
58
58
  this.#applyMovement(deltaTime, gamepad, moveSpeed, deadzone, axisMoveForward, axisMoveRight, buttonMoveUp, buttonMoveDown);
59
59
  this.#applyLook(deltaTime, gamepad, lookSpeed, deadzone, axisLookX, axisLookY);
60
60
  }
61
+ /**
62
+ * Applies local translation input to FirstPersonControls' object.
63
+ *
64
+ * @param deltaTime - Seconds since the last frame.
65
+ * @param gamepad - Fresh gamepad snapshot to read from.
66
+ * @param moveSpeed - User-configured movement speed multiplier.
67
+ * @param deadzone - Axis and trigger dead zone threshold.
68
+ * @param axisMoveForward - Axis index for forward and backward movement.
69
+ * @param axisMoveRight - Axis index for right and left strafe movement.
70
+ * @param buttonMoveUp - Button index for upward movement.
71
+ * @param buttonMoveDown - Button index for downward movement.
72
+ */
61
73
  #applyMovement(deltaTime, gamepad, moveSpeed, deadzone, axisMoveForward, axisMoveRight, buttonMoveUp, buttonMoveDown) {
62
74
  const controls = this.#controls;
63
75
  const moveMult = deltaTime * controls.movementSpeed * moveSpeed;
@@ -77,6 +89,16 @@ var GamepadFirstPersonControls = class extends GamepadControls {
77
89
  if (up > deadzone) controls.object.translateY(up * moveMult);
78
90
  if (down > deadzone) controls.object.translateY(-down * moveMult);
79
91
  }
92
+ /**
93
+ * Applies camera look input while keeping FirstPersonControls state in sync.
94
+ *
95
+ * @param deltaTime - Seconds since the last frame.
96
+ * @param gamepad - Fresh gamepad snapshot to read from.
97
+ * @param lookSpeed - User-configured look speed multiplier.
98
+ * @param deadzone - Axis dead zone threshold.
99
+ * @param axisLookX - Axis index for yaw input.
100
+ * @param axisLookY - Axis index for pitch input.
101
+ */
80
102
  #applyLook(deltaTime, gamepad, lookSpeed, deadzone, axisLookX, axisLookY) {
81
103
  const lookX = applyGamepadDeadzone(gamepad.axes[axisLookX] ?? 0, deadzone);
82
104
  const lookY = applyGamepadDeadzone(gamepad.axes[axisLookY] ?? 0, deadzone);
@@ -98,6 +120,11 @@ var GamepadFirstPersonControls = class extends GamepadControls {
98
120
  controls._lat = lat;
99
121
  controls._lon = lon;
100
122
  }
123
+ /**
124
+ * Reads the current FirstPersonControls orientation, deriving it if needed.
125
+ *
126
+ * @returns Current latitude and longitude in degrees.
127
+ */
101
128
  #getOrientation() {
102
129
  const { _lat, _lon } = this.#controls;
103
130
  if (Number.isFinite(_lat) && Number.isFinite(_lon)) return {
@@ -0,0 +1,156 @@
1
+ import { EventDispatcher } from "three";
2
+
3
+ //#region src/gamepad-input.d.ts
4
+ /**
5
+ * Event map for {@link GamepadInput}.
6
+ */
7
+ type GamepadInputEventMap = {
8
+ /**
9
+ * Fired when a gamepad is connected and becomes active.
10
+ */
11
+ connected: {
12
+ /**
13
+ * Gamepad snapshot that became active.
14
+ */
15
+ gamepad: Gamepad;
16
+ };
17
+ /**
18
+ * Fired when the active gamepad is disconnected.
19
+ */
20
+ disconnected: {
21
+ /**
22
+ * Gamepad snapshot that was active before disconnection.
23
+ */
24
+ gamepad: Gamepad;
25
+ };
26
+ };
27
+ /**
28
+ * Configuration for {@link GamepadInput}.
29
+ */
30
+ type GamepadInputOptions = {
31
+ /**
32
+ * Default axis dead zone threshold in the range `[0, 1]`.
33
+ * @default 0.1
34
+ */
35
+ deadzone: number;
36
+ };
37
+ /**
38
+ * Options for axis and stick reads.
39
+ */
40
+ type GamepadAxisOptions = {
41
+ /**
42
+ * Axis dead zone threshold for this read.
43
+ */
44
+ deadzone?: number;
45
+ };
46
+ /**
47
+ * Two-dimensional stick input after dead zone processing.
48
+ */
49
+ type GamepadStick = {
50
+ /**
51
+ * Horizontal stick value.
52
+ */
53
+ x: number;
54
+ /**
55
+ * Vertical stick value.
56
+ */
57
+ y: number;
58
+ };
59
+ /**
60
+ * Gamepad input state reader for gameplay, menus, and custom actions.
61
+ *
62
+ * Call {@link update} once per frame before reading button transitions or axes.
63
+ */
64
+ declare class GamepadInput extends EventDispatcher<GamepadInputEventMap> {
65
+ #private;
66
+ /**
67
+ * When `false`, input polling is paused.
68
+ * @default true
69
+ */
70
+ enabled: boolean;
71
+ /**
72
+ * Creates a gamepad input reader.
73
+ *
74
+ * @param options - Optional overrides for the default input behavior.
75
+ */
76
+ constructor(options?: Partial<GamepadInputOptions>);
77
+ /**
78
+ * The currently active gamepad, or `null` if no gamepad is connected.
79
+ *
80
+ * @returns The active gamepad snapshot, or `null`.
81
+ */
82
+ get gamepad(): Gamepad | null;
83
+ /**
84
+ * Whether a gamepad is currently active.
85
+ *
86
+ * @returns `true` when a gamepad is active, otherwise `false`.
87
+ */
88
+ get connected(): boolean;
89
+ /**
90
+ * Mapping reported by the active gamepad, or `null` when none is active.
91
+ *
92
+ * @returns The active gamepad mapping, or `null`.
93
+ */
94
+ get mapping(): GamepadMappingType | null;
95
+ /**
96
+ * Raw active gamepad snapshot, or `null` if no gamepad is connected.
97
+ *
98
+ * @returns The raw active gamepad snapshot, or `null`.
99
+ */
100
+ get rawGamepad(): Gamepad | null;
101
+ /**
102
+ * Polls the gamepad and refreshes current and previous button state.
103
+ */
104
+ update(): void;
105
+ /**
106
+ * Removes all window-level event listeners attached by this input reader.
107
+ */
108
+ dispose(): void;
109
+ /**
110
+ * Returns whether a button is currently pressed.
111
+ *
112
+ * @param button - Button index to inspect.
113
+ * @returns `true` when the button is currently pressed, otherwise `false`.
114
+ */
115
+ isPressed(button: number): boolean;
116
+ /**
117
+ * Returns whether a button was pressed during the latest update.
118
+ *
119
+ * @param button - Button index to inspect.
120
+ * @returns `true` only on the frame where the button transitions to pressed.
121
+ */
122
+ wasPressed(button: number): boolean;
123
+ /**
124
+ * Returns whether a button was released during the latest update.
125
+ *
126
+ * @param button - Button index to inspect.
127
+ * @returns `true` only on the frame where the button transitions to released.
128
+ */
129
+ wasReleased(button: number): boolean;
130
+ /**
131
+ * Returns the current analog value for a button.
132
+ *
133
+ * @param button - Button index to inspect.
134
+ * @returns The button value, `1` for pressed digital buttons, or `0`.
135
+ */
136
+ buttonValue(button: number): number;
137
+ /**
138
+ * Returns the current value of an axis after dead zone processing.
139
+ *
140
+ * @param axis - Axis index to inspect.
141
+ * @param options - Optional per-read axis options.
142
+ * @returns Axis value after dead zone processing, or `0` when unavailable.
143
+ */
144
+ axis(axis: number, options?: GamepadAxisOptions): number;
145
+ /**
146
+ * Returns a two-axis stick after dead zone processing.
147
+ *
148
+ * @param xAxis - Horizontal axis index.
149
+ * @param yAxis - Vertical axis index.
150
+ * @param options - Optional per-read axis options.
151
+ * @returns Object containing processed `x` and `y` values.
152
+ */
153
+ stick(xAxis: number, yAxis: number, options?: GamepadAxisOptions): GamepadStick;
154
+ }
155
+ //#endregion
156
+ export { GamepadAxisOptions, GamepadInput, GamepadInputEventMap, GamepadInputOptions, GamepadStick };