UNPKG

onsight

Version:

Interactive, easy to use JavaScript game framework.

186 lines (159 loc) 6.14 kB
import { MOUSE_DOUBLE_TIME, } from '../../constants.js'; import { Key } from './Key.js'; import { Vector2 } from '../../math/Vector2.js'; class Pointer { // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button static LEFT = 0; static MIDDLE = 1; static RIGHT = 2; static BACK = 3; static FORWARD = 4; #locked = false; // 0 #lockID = 1; constructor(element, disableContextMenu = true) { if (!element || !element.dom) { console.error(`Pointer: No element was provided`); return; } const self = this; // Raw data this._keys = new Array(5); this._location = new Vector2(0, 0); this._locationUpdated = false; this._delta = new Vector2(0, 0); this._wheel = 0; this._wheelUpdated = false; this._doubleClicked = new Array(5); this._clickTime = new Array(5); this.keys = new Array(5); // pointer buttons states this.position = new Vector2(0, 0); // position inside of the window (coordinates in world space) this.location = new Vector2(0, 0); // location inside of the window (coordinates in window space) this.delta = new Vector2(0, 0); // movement since the last update (coordinates in window space) this.wheel = 0; // scroll wheel movement since the last update this.doubleClicked = new Array(5); // indicates a button of the pointer was double clicked this.downAt = new Vector2(0, 0); // stores pointer down location this.pointerInside = false; // indicated if pointer is inside DOM element this.dragging = false; // indicates if pointer is dragging an object // Initialize key instances for (let i = 0; i < 5; i++) { this._doubleClicked[i] = false; this.doubleClicked[i] = false; this._keys[i] = new Key(); this.keys[i] = new Key(); } // Updates function updateLocation(x, y) { if (element && element.dom) { const rect = element.dom.getBoundingClientRect(); x -= rect.left; y -= rect.top; } const xDiff = x - self._location.x; const yDiff = y - self._location.y; self._delta.x += xDiff; self._delta.y += yDiff; self._location.set(x, y); self._locationUpdated = true; self.position.set(x, -y); } function updateKey(button, action) { if (button >= 0) self._keys[button].update(action); } // Disable Context Menu if (disableContextMenu) { element.on('contextmenu', (event) => { event.preventDefault(); event.stopPropagation(); }); } // Pointer element.on('pointermove', (event) => { updateLocation(event.clientX, event.clientY); }); element.on('pointerdown', (event) => { element.dom.setPointerCapture(event.pointerId); updateKey(event.button, Key.DOWN); self._clickTime[event.button] = performance.now(); }); element.on('pointerup', (event) => { element.dom.releasePointerCapture(event.pointerId); updateKey(event.button, Key.UP); }); element.on('pointerenter', () => { self.pointerInside = true; }); element.on('pointerleave', () => { self.pointerInside = false; }); // Wheel element.on('wheel', (event) => { self._wheel = event.deltaY; self._wheelUpdated = true; }); // Drag element.on('dragstart', (event) => { updateKey(event.button, Key.UP); }); // Double Click element.on('dblclick', (event) => { self._doubleClicked[event.button] = (performance.now() - self._clickTime[event.button]) < MOUSE_DOUBLE_TIME; }); } buttonPressed(button, id = -1) { if (this.#locked && this.#locked !== id) return false; return this.keys[button].pressed; } buttonDoubleClicked(button, id = -1) { if (this.#locked && this.#locked !== id) return false; return this.doubleClicked[button]; } buttonJustPressed(button, id = -1) { if (this.#locked && this.#locked !== id) return false; return this.keys[button].justPressed; } buttonJustReleased(button, id = -1) { if (this.#locked && this.#locked !== id) return false; return this.keys[button].justReleased; } insideDom() { return this.pointerInside; } lock() { this.#locked = this.#lockID; this.#lockID++; return this.#locked; } unlock() { this.#locked = false; } update() { // Key States for (let i = 0; i < 5; i++) { // Pressed if (this._keys[i].justPressed && this.keys[i].justPressed) this._keys[i].justPressed = false; if (this._keys[i].justReleased && this.keys[i].justReleased) this._keys[i].justReleased = false; this.keys[i].set(this._keys[i].justPressed, this._keys[i].pressed, this._keys[i].justReleased); // Double Click if (this._doubleClicked[i] === true) { this.doubleClicked[i] = true; this._doubleClicked[i] = false; } else { this.doubleClicked[i] = false; } } // Wheel if (this._wheelUpdated) { this.wheel = this._wheel; this._wheelUpdated = false; } else { this.wheel = 0; } // Pointer Location if (this._locationUpdated) { this.delta.copy(this._delta); this.location.copy(this._location); this._delta.set(0, 0); this._locationUpdated = false; } else { this.delta.x = 0; this.delta.y = 0; } } } export { Pointer };