pixijs-input-devices 0.5.8 → 0.6.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
@@ -4,10 +4,10 @@
4
4
 
5
5
  | | |
6
6
  | ------ | ------ |
7
- | 🎮 Interface [keyboards](#keyboarddevice), [gamepads](#gamepaddevice), and [more](#custom-devices)! | 🚀 Flexible [update](#real-time) and [event-driven](#keyboarddevice-events) APIs |
8
- | ⚡ Optimized for [INP performance](https://web.dev/articles/inp) | 🪄 Built-in [named binds](#named-binds) |
9
- | 🔮 Highly configurable | 🌐 Built-in [international keyboard](#keyboard-layout---detection) support |
10
- | ✅ Cross-platform &amp; mobile-friendly <sup>[[1]](https://caniuse.com/mdn-api_keyboardlayoutmap) [[2]](https://caniuse.com/mdn-api_gamepad_vibrationactuator) [[3]](https://chromestatus.com/feature/5989275208253440)</sup> | 🧭 Built-in [UI navigation](#uinavigation-api) _(optional)_ |
7
+ | 🎮 Handle [keyboard](#keyboarddevice), [gamepads](#gamepaddevice), and [more](#custom-devices)! | 🚀 [Real-time](#real-time) &amp; [event-driven](#keyboarddevice-events) APIs |
8
+ | ⚡ Highly-optimized for [performance](https://web.dev/articles/inp) | 🧭 Built-in [UI navigation](#uinavigation-api) |
9
+ | 🔮 Highly configurable (with sensible defaults) | 🪄 Supports [input binding](#named-binds) |
10
+ | ✅ Cross-platform &amp; mobile-friendly <sup>[[1]](https://caniuse.com/mdn-api_keyboardlayoutmap) [[2]](https://caniuse.com/mdn-api_gamepad_vibrationactuator) [[3]](https://chromestatus.com/feature/5989275208253440)</sup> | 🌐 Automatic [Intl layouts](#keyboard-layout---detection) detection |
11
11
  | 🍃 Zero dependencies & tree-shakeable | ✨ Supports PixiJS v8, v7, v6.3+ |
12
12
 
13
13
 
@@ -16,29 +16,28 @@
16
16
  *Handle device inputs with ease.*
17
17
 
18
18
  ```ts
19
- import { InputDevice, GamepadDevice } from "pixijs-input-devices";
19
+ import { InputDevice, GamepadDevice } from "pixijs-input-devices"
20
20
 
21
21
 
22
22
  // Set named binds
23
- KeyboardDevice.global.configureBinds({
24
- jump: [ "Space" ]
25
- })
26
-
27
23
  GamepadDevice.configureDefaultBinds({
28
- jump: [ "A", "LeftStickUp" ]
24
+ jump: [ "Face1" ]
25
+ })
26
+ InputDevice.keyboard.configureBinds({
27
+ jump: [ "ArrowUp", "Space" ]
29
28
  })
30
29
 
31
30
  // Use binds
32
- for ( const device of InputDevice.devices ) {
33
- if ( device.pressedBind("jump") ) // ...
31
+ for (const device of InputDevice.devices) {
32
+ if (device.bindDown("jump")) // ...
34
33
  }
35
34
 
36
35
  // Event-driven
37
- InputDevice.onBind( "jump", ({ device }) => {
38
- if ( device.type === "gamepad" ) {
36
+ InputDevice.onBindDown("jump", ({ device }) => {
37
+ if (device.type === "gamepad") {
39
38
  device.playVibration({ duration: 50 })
40
39
  }
41
- });
40
+ })
42
41
  ```
43
42
 
44
43
  ## Getting Started with PixiJS Input Devices
@@ -76,10 +75,11 @@ yarn add pixijs-input-devices --dev
76
75
  **2.** Register the update loop:
77
76
 
78
77
  ```ts
79
- import { Ticker } from 'pixi.js';
80
- import { InputDevice } from 'pixijs-input-devices';
78
+ import { Ticker } from 'pixi.js'
79
+ import { InputDevice } from 'pixijs-input-devices'
81
80
 
82
- Ticker.shared.add(ticker => InputDevice.update());
81
+
82
+ Ticker.shared.add(() => InputDevice.update())
83
83
  ```
84
84
 
85
85
  > [!TIP]
@@ -88,14 +88,15 @@ Ticker.shared.add(ticker => InputDevice.update());
88
88
  **3.** (Optional) enable the UINavigation API
89
89
 
90
90
  ```ts
91
- import * as PIXI from 'pixi.js';
92
- import { UINavigation, registerPixiJSNavigationMixin } from 'pixijs-input-devices';
91
+ import * as PIXI from 'pixi.js'
92
+ import { UINavigation, registerPixiJSNavigationMixin } from 'pixijs-input-devices'
93
+
93
94
 
94
95
  const app = new PIXI.Application(/*…*/)
95
96
 
96
97
  // enable the navigation API
97
- UINavigation.configureWithRoot( app.stage )
98
- registerPixiJSNavigationMixin( PIXI.Container )
98
+ UINavigation.configureWithRoot(app.stage)
99
+ registerPixiJSNavigationMixin(PIXI.Container)
99
100
  ```
100
101
 
101
102
  ✨ You are now ready to use inputs!
@@ -108,46 +109,65 @@ The `InputDevice` singleton controls all device discovery.
108
109
 
109
110
  ```ts
110
111
  InputDevice.keyboard // KeyboardDevice
111
- InputDevice.gamepads // Array<GamepadDevice>
112
- InputDevice.custom // Array<CustomDevice>
112
+ InputDevice.gamepads // GamepadDevice[]
113
+ InputDevice.custom // Device[]
113
114
  ```
114
115
 
115
116
  You can access all **active/connected** devices using `.devices`:
116
117
 
117
118
  ```ts
118
- for ( const device of InputDevice.devices ) { // …
119
+ for (const device of InputDevice.devices) { // …
119
120
  ```
120
121
 
121
122
  #### InputDevice - properties
122
123
 
124
+ The `InputDevice` manager provides the following **context capability** properties:
125
+
123
126
  | Property | Type | Description |
124
127
  |---|---|---|
125
- | `InputDevice.isMobile` | `boolean` | Whether the context is mobile (including tablets). |
126
- | `InputDevice.isTouchCapable` | `boolean` | Whether the context has touchscreen capability. |
128
+ | `InputDevice.hasMouseLikePointer` | `boolean` | Whether the context has a mouse/trackpad. |
129
+ | `InputDevice.isMobile` | `boolean` | Whether the context is mobile capable. |
130
+ | `InputDevice.isTouchCapable` | `boolean` | Whether the context is touchscreen capable. |
131
+
132
+ As well as shortcuts to **connected devices**:
133
+
134
+ | Accessor | Type | Description |
135
+ |---|---|---|
127
136
  | `InputDevice.lastInteractedDevice` | `Device?` | The most recently interacted device (or first if multiple). |
128
137
  | `InputDevice.devices` | `Device[]` | All active, connected devices. |
129
138
  | `InputDevice.keyboard` | `KeyboardDevice` | The global keyboard. |
130
139
  | `InputDevice.gamepads` | `GamepadDevice[]` | Connected gamepads. |
131
- | `InputDevice.custom` | `CustomDevice[]` | Custom devices. |
140
+ | `InputDevice.custom` | `CustomDevice[]` | Any custom devices. |
132
141
 
133
142
  #### InputDevice - on() Events
134
143
 
135
144
  Access global events directly through the manager:
136
145
 
137
146
  ```ts
138
- InputDevice.on( "deviceadded", ({ device }) => {
139
- // a device was connected
147
+ InputDevice.on("deviceadded", ({ device }) => {
148
+ // new device was connected or became available
140
149
  // do additional setup here, show a dialog, etc.
141
150
  })
142
151
 
143
- InputDevice.off( "deviceadded" ) // stop listening
152
+ InputDevice.off("deviceadded") // stop listening
144
153
  ```
145
154
 
146
155
  | Event | Description | Payload |
147
156
  |---|---|---|
148
157
  | `"deviceadded"` | `{device}` | A device has been added. |
149
158
  | `"deviceremoved"` | `{device}` | A device has been removed. |
159
+ | `"lastdevicechanged"` | `{device}` | The _last interacted device_ has changed. |
160
+
161
+
162
+ #### InputDevice - onBindDown() Events
150
163
 
164
+ You may also subscribe globally to **named bind** events:
165
+
166
+ ```ts
167
+ InputDevice.onBindDown("my_custom_bind", (event) => {
168
+ // a bound input waas triggered
169
+ })
170
+ ```
151
171
 
152
172
  ### KeyboardDevice
153
173
 
@@ -156,7 +176,7 @@ Unlike gamepads & custom devices, there is a single global keyboard device.
156
176
  ```ts
157
177
  let keyboard = InputDevice.keyboard
158
178
 
159
- if ( keyboard.key.ControlLeft ) { // …
179
+ if (keyboard.key.ControlLeft) { // …
160
180
  ```
161
181
 
162
182
  > [!NOTE]
@@ -168,7 +188,7 @@ if ( keyboard.key.ControlLeft ) { // …
168
188
  ```ts
169
189
  keyboard.layout // "AZERTY" | "JCUKEN" | "QWERTY" | "QWERTZ"
170
190
 
171
- keyboard.getKeyLabel( "KeyZ" ) // Я
191
+ keyboard.getKeyLabel("KeyZ") // Я
172
192
  ```
173
193
 
174
194
  > [!NOTE]
@@ -176,7 +196,7 @@ keyboard.getKeyLabel( "KeyZ" ) // Я
176
196
  > Almost every keyboard is one of these four (or a regional derivative &ndash; e.g. Hangeul,
177
197
  > Kana). There is no built-in detection for specialist or esoteric layouts (e.g. Dvorak, Colemak, BÉPO).
178
198
  >
179
- > The `keyboard.getKeyLabel( key )` uses the [KeyboardLayoutMap API](https://caniuse.com/mdn-api_keyboardlayoutmap)
199
+ > The `keyboard.getKeyLabel(key)` uses the [KeyboardLayoutMap API](https://caniuse.com/mdn-api_keyboardlayoutmap)
180
200
  > when available, before falling back to default AZERTY, JCUKEN, QWERTY or QWERTZ key values.
181
201
 
182
202
  The keyboard layout is automatically detected from (in order):
@@ -191,7 +211,7 @@ You can also manually force the layout:
191
211
  // force layout
192
212
  InputDevice.keyboard.layout = "JCUKEN"
193
213
 
194
- InputDevice.keyboard.getKeyLabel( "KeyW" ) // "Ц"
214
+ InputDevice.keyboard.getKeyLabel("KeyW") // "Ц"
195
215
  InputDevice.keyboard.layoutSource // "manual"
196
216
  ```
197
217
 
@@ -200,7 +220,7 @@ InputDevice.keyboard.layoutSource // "manual"
200
220
  | Event | Description | Payload |
201
221
  |---|---|---|
202
222
  | `"layoutdetected"` | `{layout,layoutSource,device}` | The keyboard layout (`"QWERTY"`, `"QWERTZ"`, `"AZERTY"`, or `"JCUKEN"`) has been detected, either from the native API or from keypresses. |
203
- | `"bind"` | `{name,event,keyCode,keyLabel,device}` | A **named bind** key was pressed. |
223
+ | `"binddown"` | `{name,event,keyCode,keyLabel,device}` | A **named bind** key was pressed. |
204
224
  | **Key presses:** | | |
205
225
  | `"KeyA"` | `{event,keyCode,keyLabel,device}` | The `"KeyA"` was pressed. |
206
226
  | `"KeyB"` | `{event,keyCode,keyLabel,device}` | The `"KeyB"` was pressed. |
@@ -215,11 +235,22 @@ Gamepads are automatically detected via the browser API when first interacted wi
215
235
  Gamepad accessors are modelled around the "Standard Controller Layout":
216
236
 
217
237
  ```ts
218
- let gamepad = InputDevice.gamepads[0]
238
+ const gamepad = InputDevice.gamepads[0];
239
+
240
+ if (gamepad.button.DpadDown)
241
+ {
242
+ // button pressed
243
+ }
219
244
 
220
- if ( gamepad.button.Start ) { // …
221
- if ( gamepad.leftTrigger > 0.25 ) { // …
222
- if ( gamepad.leftJoystick.x > 0.5 ) { // …
245
+ if (gamepad.leftTrigger > 0.25)
246
+ {
247
+ // trigger pulled
248
+ }
249
+
250
+ if (gamepad.leftJoystick.x < -0.33)
251
+ {
252
+ // joystick moved
253
+ }
223
254
  ```
224
255
 
225
256
  > [!TIP]
@@ -243,24 +274,24 @@ gamepad.playVibration({
243
274
 
244
275
  The gamepad buttons reference **Standard Controller Layout**:
245
276
 
246
- | Button Index | GamepadCode | Description | Xbox | Playstation | Nintendo<sup>[[?]](#gamepad---nintendo-layout-remapping)</sup> |
277
+ | Button # | GamepadCode | Description | Xbox Series X | Playstation 5 DualSense® | Nintendo Switch™ Pro |
247
278
  |:---:|:---|:---|:---:|:---:|:---:|
248
- | `0` | `"A"` | **Face Button 0** | A | Cross | A |
249
- | `1` | `"B"` | **Face Button 1** | B | Circle | X* |
250
- | `2` | `"X"` | **Face Button 2** | X | Square | B* |
251
- | `3` | `"Y"` | **Face Button 3** | Y | Triangle | Y |
279
+ | `0` | `"Face1"` | **Face Button 1** | A | Cross | B |
280
+ | `1` | `"Face2"` | **Face Button 2** | B | Circle | A |
281
+ | `2` | `"Face3"` | **Face Button 3** | X | Square | Y |
282
+ | `3` | `"Face4"` | **Face Button 4** | Y | Triangle | X |
252
283
  | `4` | `"LeftShoulder"` | **Left Shoulder** | LB | L1 | L |
253
284
  | `5` | `"RightShoulder"` | **Right Shoulder** | RB | R1 | R |
254
285
  | `6` | `"LeftTrigger"` | **Left Trigger** | LT | L2 | ZL |
255
286
  | `7` | `"RightTrigger"` | **Right Trigger** | RT | R2 | ZR |
256
- | `8` | `"Back"` | **Back** | Back | Options | Minus |
257
- | `9` | `"Start"` | **Start** | Start | Select | Plus |
258
- | `10` | `"LeftStickClick"` | **Left Stick Click** | LSB | L3 | L3 |
259
- | `11` | `"RightStickClick"` | **Right Stick Click** | RSB | R3 | R3 |
260
- | `12` | `"DPadUp"` | **D-Pad Up** | ⬆️ | ⬆️ | ⬆️ |
261
- | `13` | `"DPadDown"` | **D-Pad Down** | ⬇️ | ⬇️ | ⬇️ |
262
- | `14` | `"DPadLeft"` | **D-Pad Left** | ⬅️ | ⬅️ | ⬅️ |
263
- | `15` | `"DPadRight"` | **D-Pad Right** | ➡️ | ➡️ | ➡️ |
287
+ | `8` | `"Back"` | **Back** | View | Options | Minus |
288
+ | `9` | `"Start"` | **Start** | Menu | Select | Plus |
289
+ | `10` | `"LeftStickClick"` | **Left Stick (Click)** | LSB | L3 | L3 |
290
+ | `11` | `"RightStickClick"` | **Right Stick (Click)** | RSB | R3 | R3 |
291
+ | `12` | `"DpadUp"` | **D-Pad Up** | ⬆️ | ⬆️ | ⬆️ |
292
+ | `13` | `"DpadDown"` | **D-Pad Down** | ⬇️ | ⬇️ | ⬇️ |
293
+ | `14` | `"DpadLeft"` | **D-Pad Left** | ⬅️ | ⬅️ | ⬅️ |
294
+ | `15` | `"DpadRight"` | **D-Pad Right** | ➡️ | ➡️ | ➡️ |
264
295
 
265
296
  #### Gamepad Axis Codes
266
297
 
@@ -268,71 +299,32 @@ Bindable helpers are available for the joysticks too:
268
299
 
269
300
  | Axis # | GamepadCode | Standard | Layout
270
301
  |:---:|:---:|:---:|:---:|
271
- | `0` | `"LeftStickLeft"`<br/>`"LeftStickRight"` | **Left Stick (Left/Right)** | ⬅️➡️ |
272
- | `1` | `"LeftStickUp"`<br/>`"LeftStickDown"` | **Left Stick (Up/Down)** | ⬆️⬇️ |
273
- | `2` | `"RightStickLeft"`<br/>`"RightStickRight"` | **Right Stick (Left/Right)** | ⬅️➡️ |
274
- | `3` | `"RightStickUp"`<br/>`"RightStickDown"` | **Right Stick (Up/Down)** | ⬆️⬇️ |
302
+ | `0` | `"LeftStickLeft"`<br/>`"LeftStickRight"` | **Left Stick (X-Axis)** | ⬅️➡️ |
303
+ | `1` | `"LeftStickUp"`<br/>`"LeftStickDown"` | **Left Stick (Y-Axis)** | ⬆️⬇️ |
304
+ | `2` | `"RightStickLeft"`<br/>`"RightStickRight"` | **Right Stick (X-Axis)** | ⬅️➡️ |
305
+ | `3` | `"RightStickUp"`<br/>`"RightStickDown"` | **Right Stick (Y-Axis)** | ⬆️⬇️ |
275
306
 
276
307
  > [!TIP]
277
- > Set the `joystick.threshold` option in `GamepadDevice.defaultOptions` to control when this is triggered.
308
+ > Set the `joystick.pressThreshold` option in `GamepadDevice.defaultOptions` to adjust event sensitivity.
278
309
 
279
310
  #### Gamepad Layouts
280
311
 
281
312
  ```ts
282
- gamepad.layout // "nintendo" | "xbox" | "playstation" | "logitech" | "steam" | "standard"
313
+ gamepad.layout // "xbox_one"
283
314
  ```
284
315
 
285
- Layout detection is **highly non-standard** across major browsers, it should generally be used for aesthetic
286
- improvements (e.g. showing [device-specific icons](https://thoseawesomeguys.com/prompts/)).
287
-
288
- There is some limited layout remapping support built-in for Nintendo controllers, which appear to be the
289
- only major brand controller that deviates from the standard.
290
-
291
- ##### Gamepad - Nintendo Layout Remapping
292
-
293
- > [!CAUTION]
294
- > ***Nintendo:** Both the labels and physical positions of the A,B,X,Y buttons are different
295
- > on Nintendo controllers.
296
- >
297
- > Set `GamepadDevice.defaultOptions.nintendoRemapMode` to apply the remapping as required.
298
- >
299
- > - `"physical"` _**(default)**_ &ndash; The A,B,X,Y button codes will refer the standard face button positions (Left=X, Top=Y, Bottom=A, Right=B).
300
- > - `"accurate"` &ndash; The A,B,X,Y button codes will refer to the exact Nintendo labels (Left=Y, Top=X, Bottom=B, Right=A).
301
- > - `"none"` &ndash; The A,B,X,Y button codes mapping stay at the default indices (Left=Y, Top=B, Bottom=X, Right=A).
302
- >
303
- > ```
304
- > standard nintendo nintendo nintendo
305
- > layout "physical" "accurate" "none"
306
- > reference (default)
307
- >
308
- > Y Y X B
309
- > X B X B Y A Y A
310
- > A A B X
311
- >
312
- > 3 3 2 1
313
- > 2 1 2 1 3 0 3 0
314
- > 0 0 1 2
315
- > ```
316
-
317
- You can manually override this per-gamepad, or for all gamepads:
318
-
319
- ```ts
320
- // set default
321
- GamepadDevice.defaultOptions.nintendoRemapMode = "none"
322
-
323
- // set for a single gamepad
324
- gamepad.options.nintendoRemapMode = "accurate"
325
- ```
316
+ Gamepad device layout reporting is a non-standard API, and should only be used for aesthetic
317
+ enhancements improvements (i.e. [display layout-specific icons](https://thoseawesomeguys.com/prompts/)).
326
318
 
327
319
  #### GamepadDevice Events
328
320
 
329
321
  | Event | Description | Payload |
330
322
  |---|---|---|
331
- | `"bind"` | `{name,button,buttonCode,device}` | A **named bind** button was pressed. |
323
+ | `"binddown"` | `{name,button,buttonCode,device}` | A **named bind** button was pressed. |
332
324
  | **Button presses:** | | |
333
- | `"A"` | `{button,buttonCode,device}` | Standard layout button `"A"` was pressed. Equivalent to `0`. |
334
- | `"B"` | `{button,buttonCode,device}` | Standard layout button `"B"` was pressed. Equivalent to `1`. |
335
- | `"X"` | `{button,buttonCode,device}` | Standard layout button `"X"` was pressed. Equivalent to `2`. |
325
+ | `"Face1"` | `{button,buttonCode,device}` | Standard layout button `"Face1"` was pressed. Equivalent to `0`. |
326
+ | `"Face2"` | `{button,buttonCode,device}` | Standard layout button `"Face2"` was pressed. Equivalent to `1`. |
327
+ | `"Face3"` | `{button,buttonCode,device}` | Standard layout button `"Face3"` was pressed. Equivalent to `2`. |
336
328
  | … | … | … |
337
329
  | **Button presses (no label):** | | |
338
330
  | `0` or `Button.A` | `{button,buttonCode,device}` | Button at offset `0` was pressed. |
@@ -347,17 +339,16 @@ You can add custom devices to the device manager so it will be polled togehter a
347
339
  ```ts
348
340
  import { type CustomDevice, InputDevice } from "pixijs-input-devices"
349
341
 
350
- export const myDevice: CustomDevice = {
351
- id: "on-screen-buttons",
342
+ export const onScreenButtonsDevice: CustomDevice = {
352
343
  type: "custom",
344
+ id: "OnScreen",
353
345
  meta: {},
354
-
355
- update: ( now: number ) => {
346
+ update: (now: number) => {
356
347
  // polling update
357
348
  }
358
- }
349
+ };
359
350
 
360
- InputDevice.add( myDevice )
351
+ InputDevice.add(onScreenButtonsDevice);
361
352
  ```
362
353
 
363
354
  ## Named Binds
@@ -376,8 +367,8 @@ InputDevice.keyboard.configureBinds({
376
367
 
377
368
  // all gamepads:
378
369
  GamepadDevice.configureDefaultBinds({
379
- jump: [ "A", "LeftStickUp" ],
380
- crouch: [ "B", "X", "RightTrigger" ],
370
+ jump: [ "Face1", "LeftStickUp" ],
371
+ crouch: [ "Face2", "Face3", "RightTrigger" ],
381
372
  toggleGraphics: [ "RightStickUp", "RightStickDown" ],
382
373
  })
383
374
  ```
@@ -388,11 +379,11 @@ These can then be used with either the real-time and event-based APIs.
388
379
 
389
380
  ```ts
390
381
  // listen to all devices:
391
- InputDevice.onBind( "toggleGraphics", ( e ) => toggleGraphics() )
382
+ InputDevice.onBindDown("toggleGraphics", (e) => toggleGraphics())
392
383
 
393
384
  // listen to specific devices:
394
- InputDevice.keyboard.onBind( "jump", ( e ) => doJump() )
395
- InputDevice.gamepads[0].onBind( "jump", ( e ) => doJump() )
385
+ InputDevice.keyboard.onBindDown("jump", (e) => doJump())
386
+ InputDevice.gamepads[0].onBindDown("jump", (e) => doJump())
396
387
  ```
397
388
 
398
389
  #### Real-time:
@@ -401,19 +392,19 @@ InputDevice.gamepads[0].onBind( "jump", ( e ) => doJump() )
401
392
  let jump = false, crouch = false, moveX = 0
402
393
 
403
394
  const keyboard = InputDevice.keyboard
404
- if ( keyboard.pressedBind( "jump" ) ) jump = true
405
- if ( keyboard.pressedBind( "crouch" ) ) crouch = true
406
- if ( keyboard.key.ArrowLeft ) moveX = -1
407
- else if ( keyboard.key.ArrowRight ) moveX = 1
395
+ if (keyboard.bindDown("jump")) jump = true
396
+ if (keyboard.bindDown("crouch")) crouch = true
397
+ if (keyboard.key.ArrowLeft) moveX = -1
398
+ else if (keyboard.key.ArrowRight) moveX = 1
408
399
 
409
- for ( const gamepad of InputDevice.gamepads ) {
410
- if ( gamepad.pressedBind( "jump" ) ) jump = true
411
- if ( gamepad.pressedBind( "crouch" ) ) crouch = true
400
+ for (const gamepad of InputDevice.gamepads) {
401
+ if (gamepad.bindDown("jump")) jump = true
402
+ if (gamepad.bindDown("crouch")) crouch = true
412
403
 
413
404
  // gamepads have additional analog inputs
414
405
  // we're going to apply these only if touched
415
- if ( gamepad.leftJoystick.x != 0 ) moveX = gamepad.leftJoystick.x
416
- if ( gamepad.leftTrigger > 0 ) moveX *= ( 1 - gamepad.leftTrigger )
406
+ if (gamepad.leftJoystick.x != 0) moveX = gamepad.leftJoystick.x
407
+ if (gamepad.leftTrigger > 0) moveX *= (1 - gamepad.leftTrigger)
417
408
  }
418
409
  ```
419
410
 
@@ -426,8 +417,8 @@ _Traverse a UI using input devices._
426
417
  Set up navigation once using:
427
418
 
428
419
  ```ts
429
- UINavigation.configureWithRoot( app.stage ) // any root container
430
- registerPixiJSNavigationMixin( PIXI.Container )
420
+ UINavigation.configureWithRoot(app.stage) // any root container
421
+ registerPixiJSNavigationMixin(PIXI.Container)
431
422
  ```
432
423
 
433
424
  Navigation should now work automatically if your buttons handle these events:
@@ -494,7 +485,7 @@ Containers are extended with a few properties/accessors:
494
485
  > [!WARNING]
495
486
  > **Fallback Hover Effect:** If there is no `"pointerover"` or `"mouseover"` handler detected on a container, `UINavigation`
496
487
  > will apply abasic alpha effect to the selected item to indicate which container is currently the navigation target. This
497
- > can be disabled by setting `UINavigation.options.useFallbackHoverEffect` to `false`.
488
+ > can be disabled by setting `UINavigation.options.enableFallbackOverEffect` to `false`.
498
489
 
499
490
  ### Default Binds
500
491
 
@@ -502,12 +493,12 @@ The keyboard and gamepad devices are preconfigured with the following binds, fee
502
493
 
503
494
  Navigation Intent Bind | Keyboard | Gamepad
504
495
  ---|---|---
505
- `"navigate.left"` | "ArrowLeft", "KeyA" | "DPadLeft", "LeftStickLeft"
506
- `"navigate.right"` | "ArrowRight", "KeyD" | "DPadRight", "LeftStickRight"
507
- `"navigate.up"` | "ArrowUp", "KeyW" | "DPadUp", "LeftStickUp"
508
- `"navigate.down"` | "ArrowDown", "KeyS" | "DPadDown", "LeftStickDown"
509
- `"navigate.trigger"` | "Enter", "Space" | "A"
510
- `"navigate.back"` | "Escape", "Backspace" | "B", "Back"
496
+ `"navigate.left"` | "ArrowLeft", "KeyA" | "DpadLeft", "LeftStickLeft"
497
+ `"navigate.right"` | "ArrowRight", "KeyD" | "DpadRight", "LeftStickRight"
498
+ `"navigate.up"` | "ArrowUp", "KeyW" | "DpadUp", "LeftStickUp"
499
+ `"navigate.down"` | "ArrowDown", "KeyS" | "DpadDown", "LeftStickDown"
500
+ `"navigate.trigger"` | "Enter", "Space" | "Face1"
501
+ `"navigate.back"` | "Escape", "Backspace" | "Face2", "Back"
511
502
 
512
503
  ### Manual control for submenus & modal views
513
504
 
@@ -515,7 +506,7 @@ You can manually take control of navigation using:
515
506
 
516
507
  ```ts
517
508
  // take control
518
- UINavigation.pushResponder( myModalView )
509
+ UINavigation.pushResponder(myModalView)
519
510
 
520
511
  // relinquish control
521
512
  UINavigation.popResponder()
@@ -535,9 +526,9 @@ InputDevice.on("deviceconnected", ({ device }) =>
535
526
  device.meta.localPlayerId = 123
536
527
  )
537
528
 
538
- for ( const device of InputDevice.devices )
529
+ for (const device of InputDevice.devices)
539
530
  {
540
- if ( device.meta.localPlayerId === 123 )
531
+ if (device.meta.localPlayerId === 123)
541
532
  {
542
533
  // use assigned input device!
543
534
  }
@@ -550,26 +541,29 @@ You can easily map an on-screen input device using the `CustomDevice` interface.
550
541
 
551
542
  ```ts
552
543
  export class OnScreenInputContainer extends Container implements CustomDevice {
553
- id = "onscreen";
554
- type = "custom" as const;
555
- meta: Record<string, any> = {};
544
+ id = "onscreen"
545
+ type = "custom" as const
546
+ meta: Record<string, any> = {}
556
547
 
557
548
  inputs = {
558
549
  moveX: 0.0
559
550
  jump: false,
560
551
  }
561
552
 
562
- update( now )
553
+ update(now)
563
554
  {
564
- this.moveX = this._virtualJoystick.x
565
- this.jump = this._jumpButton.isTouching()
555
+ this.inputs.moveX = this._virtualJoystick.x
556
+ this.inputs.jump = this._jumpButton.isTouching()
566
557
  }
558
+
559
+ // e.g. disable named binds for onscreen joysticks:
560
+ bindDown(name){ return false }
567
561
  }
568
562
 
569
- const onscreen = new OnScreenInputContainer();
563
+ const onscreen = new OnScreenInputContainer()
570
564
 
571
- InputDevice.add( onscreen )
572
- InputDevice.remove( onscreen )
565
+ InputDevice.add(onscreen)
566
+ InputDevice.remove(onscreen)
573
567
  ```
574
568
 
575
569
  ### Two Users; One Keyboard
@@ -591,32 +585,32 @@ InputDevice.keyboard.configureBinds({
591
585
  p2_jump: [ "ArrowUp" ],
592
586
  p2_defend: [ "ArrowDown" ],
593
587
  p2_left: [ "ArrowLeft" ],
594
- p2_right: [ "ArrowRight" ],
588
+ p2_right: [ "ArrowRight" ]
595
589
  })
596
590
  ```
597
591
 
598
592
  and then switch groups depending on the mode:
599
593
 
600
594
  ```ts
601
- if ( gameMode === "multiplayer" )
595
+ if (gameMode === "multiplayer")
602
596
  {
603
- player1.jump = device.pressedBind( "p1_jump" )
604
- player1.defend = device.pressedBind( "p1_defend" )
605
- player1.moveX += device.pressedBind( "p1_left" ) ? -1 : 0
606
- player1.moveX += device.pressedBind( "p1_right" ) ? 1 : 0
607
-
608
- player2.jump = device.pressedBind( "p2_jump" )
609
- player2.defend = device.pressedBind( "p2_defend" )
610
- player2.moveX += device.pressedBind( "p2_left" ) ? -1 : 0
611
- player2.moveX += device.pressedBind( "p2_right" ) ? 1 : 0
597
+ player1.jump = device.bindDown("p1_jump")
598
+ player1.defend = device.bindDown("p1_defend")
599
+ player1.moveX += device.bindDown("p1_left") ? -1 : 0
600
+ player1.moveX += device.bindDown("p1_right") ? 1 : 0
601
+
602
+ player2.jump = device.bindDown("p2_jump")
603
+ player2.defend = device.bindDown("p2_defend")
604
+ player2.moveX += device.bindDown("p2_left") ? -1 : 0
605
+ player2.moveX += device.bindDown("p2_right") ? 1 : 0
612
606
  }
613
607
  else
614
608
  {
615
- player1.jump = device.pressedBind( "jump" )
616
- player1.defend = device.pressedBind( "defend" )
617
- player1.moveX += device.pressedBind( "left" ) ? -1 : 0
618
- player1.moveX += device.pressedBind( "right" ) ? 1 : 0
609
+ player1.jump = device.bindDown("jump")
610
+ player1.defend = device.bindDown("defend")
611
+ player1.moveX += device.bindDown("left") ? -1 : 0
612
+ player1.moveX += device.bindDown("right") ? 1 : 0
619
613
 
620
- updateComputerPlayerInput( player2 )
614
+ updateComputerPlayerInput(player2)
621
615
  }
622
616
  ```