WIP KeyControl event source
This commit is contained in:
parent
b05cdab771
commit
b04ba4e622
1 changed files with 67 additions and 0 deletions
67
lib/keys.ts
Normal file
67
lib/keys.ts
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import { Source } from "./source";
|
||||||
|
|
||||||
|
export type KeyName = "up" | "down" | "left" | "right" | "a" | "b" | "menu";
|
||||||
|
|
||||||
|
const KEY_NAMES: Record<string, KeyName> = {
|
||||||
|
// compact keys (WASD+ZXC)
|
||||||
|
KeyZ: "a",
|
||||||
|
KeyX: "b",
|
||||||
|
KeyC: "menu",
|
||||||
|
KeyW: "up",
|
||||||
|
KeyS: "down",
|
||||||
|
KeyA: "left",
|
||||||
|
KeyD: "right",
|
||||||
|
// full-board keys (arrows+space/shift/enter)
|
||||||
|
Space: "a",
|
||||||
|
ShiftLeft: "b",
|
||||||
|
ShiftRight: "b",
|
||||||
|
Enter: "menu",
|
||||||
|
ArrowUp: "up",
|
||||||
|
ArrowDown: "down",
|
||||||
|
ArrowLeft: "left",
|
||||||
|
ArrowRight: "right",
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A keypress/release event for an abstract button, or else ["focus", "release"] if for some reason future release events might not be registered. */
|
||||||
|
export type KeyEvent = [KeyName | "focus", "press" | "release"];
|
||||||
|
|
||||||
|
export function keyControl(source: HTMLElement): Source<KeyEvent> {
|
||||||
|
const tabIndex = source.getAttribute("tabIndex");
|
||||||
|
source.setAttribute(
|
||||||
|
"tabindex",
|
||||||
|
tabIndex == "" || tabIndex == null ? "-1" : tabIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
return ((callback?: (keyEvent: KeyEvent) => void) => {
|
||||||
|
if (callback) {
|
||||||
|
const handle = (evt: KeyboardEvent, action: "press" | "release") => {
|
||||||
|
const keyName = KEY_NAMES[evt.code];
|
||||||
|
if (keyName != undefined) {
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
|
||||||
|
callback([keyName, action]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const keyUp = (evt: KeyboardEvent) => handle(evt, "release");
|
||||||
|
const keyDown = (evt: KeyboardEvent) => handle(evt, "press");
|
||||||
|
const focus = () => callback(["focus", "press"]);
|
||||||
|
const blur = () => callback(["focus", "release"]);
|
||||||
|
|
||||||
|
source.addEventListener("keyup", keyUp, false);
|
||||||
|
source.addEventListener("keydown", keyDown, false);
|
||||||
|
source.addEventListener("focus", focus, false);
|
||||||
|
source.addEventListener("blur", blur, false);
|
||||||
|
source.focus({ focusVisible: true } as FocusOptions);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
source.removeEventListener("keyup", keyUp, false);
|
||||||
|
source.removeEventListener("keydown", keyDown, false);
|
||||||
|
source.removeEventListener("focus", focus, false);
|
||||||
|
source.removeEventListener("blur", blur, false);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return ["blur", "release"];
|
||||||
|
}
|
||||||
|
}) as Source<KeyEvent>;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue