49 lines
1.3 KiB
JavaScript
49 lines
1.3 KiB
JavaScript
// Handle lame OS key input event behavior. See: https://mzl.la/2Ob0WQE
|
|
// Also "up" all keys on blur.
|
|
export default function addKeyListener(target, listener) {
|
|
let keysDown = {};
|
|
let keyUpDelays = {};
|
|
function setAllKeysUp() {
|
|
for (const i in keyUpDelays) {
|
|
clearTimeout(keyUpDelays[i]);
|
|
}
|
|
keyUpDelays = {};
|
|
for (const key in keysDown) {
|
|
listener({type: 'keyUp', payload: key});
|
|
}
|
|
keysDown = {};
|
|
}
|
|
function onBlur() {
|
|
setAllKeysUp();
|
|
}
|
|
function onKeyDown(event) {
|
|
const {key} = event;
|
|
if (keysDown[key]) {
|
|
if (keyUpDelays[key]) {
|
|
clearTimeout(keyUpDelays[key]);
|
|
delete keyUpDelays[key];
|
|
}
|
|
return;
|
|
}
|
|
keysDown[key] = true;
|
|
listener({type: 'keyDown', payload: key});
|
|
}
|
|
function onKeyUp(event) {
|
|
const {key} = event;
|
|
keyUpDelays[key] = setTimeout(() => {
|
|
delete keyUpDelays[key];
|
|
delete keysDown[key];
|
|
listener({type: 'keyUp', payload: key});
|
|
}, 20);
|
|
}
|
|
window.addEventListener('blur', onBlur);
|
|
window.addEventListener('keyup', onKeyUp);
|
|
target.addEventListener('keydown', onKeyDown);
|
|
return () => {
|
|
setAllKeysUp();
|
|
target.removeEventListener('keydown', onKeyDown);
|
|
window.removeEventListener('keyup', onKeyUp);
|
|
window.removeEventListener('blur', onBlur);
|
|
};
|
|
}
|