use-control
Version:
A powerful set of hooks for elegantly handling keyboard, mouse and gamepad input (soon)
68 lines • 3.06 kB
JavaScript
import { useEffect } from 'react';
import { Subject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
var buttonCache = {};
var poll;
export var presses$ = new Subject();
export var held$ = new Subject();
export var releases$ = new Subject();
export var axes$ = new Subject();
presses$.subscribe(console.log);
// TODO(ben): consider using an interval() stream for the tick
export function init(pollIntervalMs) {
if (pollIntervalMs === void 0) { pollIntervalMs = 1000 / 60; }
if (poll)
clearInterval(poll);
poll = setInterval(function () {
var _a;
var gamepads = navigator.getGamepads
? navigator.getGamepads()
: navigator.webkitGetGamepads
? navigator.webkitGetGamepads()
: [];
if (!gamepads)
return;
for (var ctrlIdx = 0; ctrlIdx < gamepads.length; ctrlIdx++) {
if (gamepads[ctrlIdx]) {
for (var btnIdx = 0; btnIdx < gamepads[0].buttons.length; btnIdx++) {
var btn = gamepads[ctrlIdx].buttons[btnIdx];
var cachedBtn = ((_a = buttonCache === null || buttonCache === void 0 ? void 0 : buttonCache[ctrlIdx]) === null || _a === void 0 ? void 0 : _a[btnIdx]) || {};
if (btn.pressed) {
held$.next({ controllerIndex: 0, buttonIndex: btnIdx });
}
if (!btn.pressed && cachedBtn.pressed) {
releases$.next({ controllerIndex: ctrlIdx, buttonIndex: btnIdx });
}
if (btn.pressed && !cachedBtn.pressed) {
presses$.next({ controllerIndex: ctrlIdx, buttonIndex: btnIdx });
}
}
buttonCache[ctrlIdx] = gamepads[ctrlIdx].buttons.slice();
for (var axisIdx = 0; axisIdx < gamepads[ctrlIdx].axes.length; axisIdx++) {
var axis = gamepads[ctrlIdx].axes[axisIdx];
axes$.next({ controllerIndex: ctrlIdx, axisIndex: axisIdx, value: axis });
}
}
}
}, pollIntervalMs);
}
export function teardown() {
clearInterval(poll);
}
export function useGamepadButtonPressed(controllerIndex, buttonIndex, sink) {
useEffect(function () {
var sub = presses$
.pipe(filter(function (p) { return p.buttonIndex === buttonIndex && p.controllerIndex === controllerIndex; }))
.subscribe(sink);
return function () { return sub.unsubscribe(); };
}, [controllerIndex, buttonIndex, sink]);
}
export function useGamepadAxis(controllerIndex, axisIndex, sink) {
useEffect(function () {
var sub = axes$
.pipe(filter(function (p) { return p.axisIndex === axisIndex && p.controllerIndex === controllerIndex; }), map(function (p) { return p.value; }))
.subscribe(sink);
return function () { return sub.unsubscribe(); };
}, [controllerIndex, axisIndex, sink]);
}
//# sourceMappingURL=gamepadStream.js.map