The GamepadMapper class provides a comprehensive solution to address the shortcomings of the vanilla Web Gamepad API, including:
// Configurable deadzone (default: 0.1)
const mapper = new GamepadMapper({ deadzone: 0.15 });
// Values below deadzone threshold return 0
// Values above are scaled to maintain full 0-1 range
// Configurable debounce time (default: 50ms)
const mapper = new GamepadMapper({ debounceTime: 30 });
// Prevents multiple rapid button events from hardware bounce
// Listen for button events
mapper.on('buttondown', (data) => {
console.log(`Button ${data.button} pressed on gamepad ${data.gamepadIndex}`);
});
mapper.on('buttonup', (data) => {
console.log(`Button ${data.button} released on gamepad ${data.gamepadIndex}`);
});
// Listen for analog stick/trigger changes
mapper.on('axischange', (data) => {
console.log(`Axis ${data.axis}: ${data.value} (raw: ${data.rawValue})`);
});
| Xbox | PlayStation | Nintendo | Standard Name |
|---|---|---|---|
| A | X (Cross) | B | A |
| B | Circle | A | B |
| X | Square | Y | X |
| Y | Triangle | X | Y |
| LB | L1 | L | LB |
| RB | R1 | R | RB |
| LT | L2 | ZL | LT |
| RT | R2 | ZR | RT |
LEFT_STICK_X / LEFT_STICK_YRIGHT_STICK_X / RIGHT_STICK_YLEFT_TRIGGER / RIGHT_TRIGGER (for analog triggers)import { GamepadMapper } from './gamepad-mapper.js';
const gamepadMapper = new GamepadMapper({
deadzone: 0.15, // 15% deadzone
debounceTime: 30, // 30ms debounce
enableVibration: true // Enable haptic feedback
});
// Handle button presses
gamepadMapper.on('buttondown', (data) => {
if (data.button === 'A') {
// Play note, trigger action, etc.
gamepadMapper.vibrate(data.gamepadIndex, 100, 0.3, 0.1);
}
});
// Handle analog input
gamepadMapper.on('axischange', (data) => {
if (data.axis === 'LEFT_STICK_X') {
// Update frequency, position, etc.
updateFrequency(data.value);
}
});
const options = {
deadzone: 0.1, // Stick deadzone (0-1)
debounceTime: 50, // Button debounce time (ms)
pollRate: 60, // Polling rate (fps)
enableVibration: false // Enable vibration support
};