116 lines
3.0 KiB
TypeScript
116 lines
3.0 KiB
TypeScript
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<string, boolean> = new Map();
|
|
private mouseStates: Map<string, boolean> = 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<string, () => void> = new Map();
|
|
private mouseEvents: Map<string, () => 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<ZoomableDoodler>("doodler").screenToWorld(
|
|
this.mouseLocation.x,
|
|
this.mouseLocation.y,
|
|
);
|
|
}
|
|
return this.mouseLocation;
|
|
}
|
|
getMouseLocationV() {
|
|
if (getContextItem("doodler") instanceof ZoomableDoodler) {
|
|
return new Vector(
|
|
getContextItem<ZoomableDoodler>("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));
|
|
}
|
|
}
|
|
}
|