import { Vector, ZoomableDoodler } from "@bearmetal/doodler"; import { getContextItem } from "./context.ts"; function mouseButtonToString(button: number) { switch (button) { case 0: return "left"; case 1: return "middle"; case 2: return "right"; } } function mouseButtonToNumber(button: string) { switch (button) { case "left": return 0; case "middle": return 1; case "right": return 2; } } export class InputManager { private keyStates: Map = new Map(); private mouseStates: Map = new Map(); private mouseLocation: { x: number; y: number } = { x: 0, y: 0 }; private mouseDelta: { x: number; y: number } = { x: 0, y: 0 }; private keyEvents: Map void> = new Map(); private mouseEvents: Map void> = new Map(); constructor() { document.addEventListener("keydown", (e) => { this.keyStates.set(e.key, true); this.keyEvents.get(e.key)?.call(e); }); document.addEventListener("keyup", (e) => { this.keyStates.set(e.key, false); }); document.addEventListener("mousedown", (e) => { const button = mouseButtonToString(e.button); if (!button) throw "Mouse button not found: " + e.button; this.mouseStates.set(button, true); this.mouseEvents.get(button)?.call(e); }); document.addEventListener("mouseup", (e) => { const button = mouseButtonToString(e.button); if (!button) throw "Mouse button not found: " + e.button; this.mouseStates.set(button, false); }); self.addEventListener("mousemove", (e) => { this.mouseLocation = { x: e.clientX, y: e.clientY }; this.mouseDelta = { x: e.movementX, y: e.movementY, }; }); } getKeyState(key: string) { return this.keyStates.get(key); } getMouseState(key: string) { return this.mouseStates.get(key); } getMouseLocation() { if (getContextItem("doodler") instanceof ZoomableDoodler) { return getContextItem("doodler").screenToWorld( this.mouseLocation.x, this.mouseLocation.y, ); } return this.mouseLocation; } getMouseLocationV() { if (getContextItem("doodler") instanceof ZoomableDoodler) { return new Vector( getContextItem("doodler").screenToWorld( this.mouseLocation.x, this.mouseLocation.y, ), ); } return new Vector(this.mouseLocation); } getMouseDelta() { return this.mouseDelta; } onKey(key: string, cb: () => void) { this.keyEvents.set(key, cb); } onMouse(key: string, cb: () => void) { this.mouseEvents.set(key, cb); } offKey(key: string) { const events = this.keyEvents.get(key); this.keyEvents.delete(key); return events; } offMouse(key: string) { this.mouseEvents.delete(key); } onNumberKey(arg0: (arg: number) => void) { for (let i = 0; i < 10; i++) { this.onKey(i.toString(), () => arg0(i)); } } }