react-use-gamepad
Version:
Event driven functionality for the GamepadAPI
102 lines • 4.56 kB
JavaScript
import { __spreadArray } from "tslib";
import { useEffect, useRef, useState } from 'react';
export var useGamepad = function (_a) {
var onButtonDown = _a.onButtonDown, onButtonUp = _a.onButtonUp, onJoystickMove = _a.onJoystickMove, dependencies = _a.dependencies;
var _b = useState([]), gamepadAxes = _b[0], setGamepadAxes = _b[1];
var isInitialized = useRef(false);
var deps = dependencies ? dependencies : [];
useEffect(function () {
if (!isInitialized.current) {
!!onButtonDown &&
window.addEventListener('gamepadbuttondown', function (_a) {
var buttonNumber = _a.detail.buttonNumber;
onButtonDown(buttonNumber);
});
!!onButtonUp &&
window.addEventListener('gamepadbuttonup', function (_a) {
var buttonNumber = _a.detail.buttonNumber;
onButtonUp(buttonNumber);
});
!!onJoystickMove &&
window.addEventListener('joystickmove', function (_a) {
var _b = _a.detail, index = _b.index, value = _b.value;
onJoystickMove(index, value);
});
isInitialized.current = true;
}
return function () {
!!onButtonDown &&
window.removeEventListener('gamepadbuttondown', function (_a) {
var buttonNumber = _a.detail.buttonNumber;
onButtonDown(buttonNumber);
});
!!onButtonUp &&
window.removeEventListener('gamepadbuttonup', function (_a) {
var buttonNumber = _a.detail.buttonNumber;
onButtonUp(buttonNumber);
});
!!onJoystickMove &&
window.removeEventListener('joystickmove', function (_a) {
var _b = _a.detail, index = _b.index, value = _b.value;
onJoystickMove(index, value);
});
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, __spreadArray([onButtonDown, onButtonUp, onJoystickMove], deps, true));
var gameLoopRef = useRef(null);
var gamepadConnectedRef = useRef(false);
var gamepadRef = useRef(null);
var sendButtonEvent = function (buttonNum, lastVal, curVal) {
var eventName = !lastVal && curVal ? 'gamepadbuttondown' : 'gamepadbuttonup';
var event = new CustomEvent(eventName, {
detail: { buttonNumber: buttonNum },
});
window.dispatchEvent(event);
};
var gameLoop = function (index) {
var gamepads = navigator.getGamepads();
var gp = gamepads === null || gamepads === void 0 ? void 0 : gamepads[index];
if (!gp)
return;
if (gamepadRef.current) {
gamepadRef.current.buttons.forEach(function (button, i) {
var lastVal = button.pressed;
var curVal = gp.buttons[i].pressed;
if (lastVal !== curVal)
sendButtonEvent(i, lastVal, curVal);
});
var axes = gamepadRef.current.axes;
setGamepadAxes(axes);
}
gamepadRef.current = gp;
gameLoopRef.current = requestAnimationFrame(function () { return gameLoop(index); });
};
useEffect(function () {
var handleGamepadConnected = function (_a) {
var index = _a.gamepad.index;
gamepadRef.current = navigator.getGamepads()[index];
if (gamepadRef.current)
gameLoop(index);
};
var handleGamepadDisconnected = function () {
gamepadRef.current = null;
gamepadConnectedRef.current = false;
if (gameLoopRef.current !== null) {
cancelAnimationFrame(gameLoopRef.current);
gameLoopRef.current = null;
}
};
window.addEventListener('gamepadconnected', handleGamepadConnected);
window.addEventListener('gamepaddisconnected', handleGamepadDisconnected);
return function () {
window.removeEventListener('gamepadconnected', handleGamepadConnected);
window.removeEventListener('gamepaddisconnected', handleGamepadDisconnected);
if (gamepadConnectedRef.current) {
handleGamepadDisconnected();
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return gamepadAxes;
};
//# sourceMappingURL=useGamepad.js.map