1
0
forked from sent/waves
waves/public/assets/g/burgerandfrights/js/framework/input.class.js
2025-04-09 17:11:14 -05:00

186 lines
5.2 KiB
JavaScript

/**
* @file input.class.js
* @version 1.0.0
*/
export default class Input {
static _init() {
Input._keyDown = new Set();
Input._keyUp = new Set();
Input._key = new Set();
Input._mouseButtonDown = new Set();
Input._mouseButtonUp = new Set();
Input._mouseButton = new Set();
Input._cursorPosition = { x: 0, y: 0 };
Input._enableContextMenu = true;
Input._enableKeyScroll = true;
Input._pointerLockElement = null;
Input._isPointerLocked = false;
Input._scrollKeyCodes = [32, 37, 38, 39, 40];
Input._lastDX = 0;
window.addEventListener('load', Input._handleLoad);
}
static _handleLoad() {
const cursorMove = (x, y) => {
Input._cursorPosition.x = x;
Input._cursorPosition.y = y;
};
document.addEventListener('keydown', e => {
if (!Input._enableKeyScroll &&
Input._scrollKeyCodes.includes(e.keyCode)) {
e.preventDefault();
}
if (e.repeat !== undefined && e.repeat) {
return;
}
Input._keyDown.add(e.keyCode);
Input._key.add(e.keyCode);
}, false);
document.addEventListener('keyup', e => {
if (!Input._enableKeyScroll &&
Input._scrollKeyCodes.includes(e.keyCode)) {
e.preventDefault();
}
if (e.repeat !== undefined && e.repeat) {
return;
}
if (Input._key.has(e.keyCode)) {
Input._keyUp.add(e.keyCode);
Input._key.delete(e.keyCode);
}
}, false);
document.addEventListener('mousedown', e => {
const target = e.target || e.srcElement;
if (e.button === 0 && !Input._isPointerLocked &&
target === Input._pointerLockElement) {
Input._pointerLockElement.requestPointerLock();
}
Input._mouseButtonDown.add(e.button);
Input._mouseButton.add(e.button);
}, false);
document.addEventListener('mouseup', e => {
if (Input._mouseButton.has(e.button)) {
Input._mouseButtonUp.add(e.button);
Input._mouseButton.delete(e.button);
}
}, false);
document.addEventListener('mousemove', e => {
if (Input._isPointerLocked) {
const dx = e.movementX !== undefined ? e.movementX : e.mozMovementX !== undefined ? e.mozMovementX : e.webkitMovementX !== undefined ? e.webkitMovementX : 0;
const dy = e.movementY !== undefined ? e.movementY : e.mozMovementY !== undefined ? e.mozMovementY : e.webkitMovementY !== undefined ? e.webkitMovementY : 0;
// Hack: Fix drifting X bug in Firefox
const ignoreX = Input._lastDX === 1 && dx === 1;
Input._lastDX = dx;
cursorMove(Input._cursorPosition.x + (ignoreX ? 0 : dx), Input._cursorPosition.y + dy);
} else {
cursorMove(e.clientX, e.clientY);
}
}, false);
document.addEventListener('contextmenu', e => {
if (!Input._enableContextMenu) {
e.preventDefault();
}
}, false);
document.addEventListener('pointerlockchange', () => {
Input._isPointerLocked = document.pointerLockElement === Input._pointerLockElement;
}, false);
document.addEventListener('pointerlockerror', () => {
console.error('Unable to use Pointer Lock API');
}, false);
}
static getKeyDown(key) {
return Input._keyDown.has(key);
}
static getKeyUp(key) {
return Input._keyUp.has(key);
}
static getKey(key) {
return Input._key.has(key);
}
static getMouseButtonDown(button = 0) {
return Input._mouseButtonDown.has(button);
}
static getMouseButtonUp(button = 0) {
return Input._mouseButtonUp.has(button);
}
static getMouseButton(button = 0) {
return Input._mouseButton.has(button);
}
static getCursorPosition(target) {
if (target === undefined) {
throw new Error('No target object supplied (target = { x, y })');
}
target.x = Input._cursorPosition.x;
target.y = Input._cursorPosition.y;
return target;
}
static setContextMenuEnabled(enabled) {
Input._enableContextMenu = enabled;
}
static setPointerLockElement(element = null) {
if (element === Input._pointerLockElement) {
return;
}
if (Input._isPointerLocked) {
document.exitPointerLock();
}
Input._pointerLockElement = element;
}
static setKeyScrollEnabled(enabled) {
Input._enableKeyScroll = enabled;
}
static exitPointerLock() {
document.exitPointerLock();
}
static isPointerLocked() {
return Input._isPointerLocked;
}
static resetState() {
Input._mouseButtonDown.clear();
Input._mouseButtonUp.clear();
Input._keyDown.clear();
Input._keyUp.clear();
}
}
Input._init();