UNPKG

evidently-input

Version:

TypeScript powered for easily handling input in your games.

166 lines 7.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var MouseButtons; (function (MouseButtons) { MouseButtons[MouseButtons["Left"] = 0] = "Left"; MouseButtons[MouseButtons["Middle"] = 1] = "Middle"; MouseButtons[MouseButtons["Right"] = 2] = "Right"; })(MouseButtons = exports.MouseButtons || (exports.MouseButtons = {})); /** * Handles the mouse events and provdes an API for interacting with it easily. The simplest way to use it is: * * 1. Create a new instance of `MouseInput`. * 2. Call `registerListeners()` passing the `document`. * 3. Set `inputContainer` to the canvas element created by PIXI. * 4. Call `update` **at the end** of every update frame of your game. * 5. Use the functions of this library in your code. * * ### Different mouse positions * * * `screen` is the position of the mouse in the whole screen. * * `page` is the position of the mouse inside the loaded webpage. * * `local` is the position of the mouse relative to the `inputContainer` if defined, or to the element passed to `registerListeners`. * * `scaled` is the position of the mouse inside the game, which is `local` modified by `scaleProperties`. It is mostly useful in games * that scale up when their workspace is enlarged, as opposed to games that just reorganize their content and allow seeing more * space inside. * * In order to get the proper values for `local` it is recommended to set `inputContainer` to the canvas element used to render the game. * * ### Scaled mouse position * * In order to get the proper values for `scaled` you need to keep the `scaleProperties` in sync with the modifications you do to the rendering of the game. * For example, a typical game imitating 8-bit aesthetics would likely have its own internal resolution and then would scale that up, maybe pixel-perfect * or maybe not. For example: a game in resolution `320x240` scaled up proportionally to resolution `1920x1080`: * * * It would scale `4.5` times, to `1440x1080.` * * It would be horizontally centered, so offset in `X` by `240px` ( `(1920 - 1440) / 2` ) * * So the `scaleProperties` would be `{scaleX: 4.5, scaleY: 4.5, offsetX: 240, offsetY: 0} * * With these values scaledX/Y will return the proper position of the mouse in the stage. * * ### How does it work: * * See [[KeyboardInput]] for details. * * ### Understanding mouse button states * * Down, pressed and released for the mouse buttons work exactly the same as the keys in [[KeyboardInput]], please refer to its documentation. */ class MouseInput { constructor() { this.isMouseDown = (button) => this._mouseButtonsDown.indexOf(button) !== -1 || this.isMousePressed(button); this.isMousePressed = (button) => this._mouseButtonsPressed.indexOf(button) !== -1; this.isMouseReleased = (button) => this._mouseButtonsReleased.indexOf(button) !== -1; /** * Updates the internal state, should be called at the end of each frame. */ this.update = () => { this._mouseButtonsReleased.length = 0; this._mouseButtonsPressed.length = 0; }; /** * Resets the internal state of this class to what it is during creation - nothing pressed, released or held down, positions reset. * This won't affect `scaleProperties` and `inputContainer`. */ this.flush = () => { this._mouseButtonsDown.length = 0; this._mouseButtonsPressed.length = 0; this._mouseButtonsReleased.length = 0; this._pageX = 0; this._pageY = 0; this._localX = 0; this._localY = 0; this._screenX = 0; this._screenY = 0; }; /** * Handles a mouse event updating the internal status. This will be called automatically if you register the listeners * via `registerListeners`. If you have listeners being registered somewhere else entirely and would like to keep it * that way, you can manually call this method passing the MouseEvent/PointerEvent. * * @param {MouseEvent | PointerEvent} event */ this.handleEvent = (event) => { var _a, _b; this._pageX = (_a = event.pageX, (_a !== null && _a !== void 0 ? _a : event.clientX)); this._pageY = (_b = event.pageY, (_b !== null && _b !== void 0 ? _b : event.clientY)); this._screenX = event.screenX; this._screenY = event.screenY; this._localX = this.inputContainer ? event.pageX - this.inputContainer.offsetLeft : event.clientX; this._localY = this.inputContainer ? event.pageY - this.inputContainer.offsetTop : event.clientY; if (event.type === 'mouseup' || event.type === 'pointerup') { this._mouseButtonsDown = this._mouseButtonsDown.filter(button => button !== event.button); this._mouseButtonsReleased.push(event.button); } else if (event.type === 'mousedown' || event.type === 'pointerup') { this._mouseButtonsDown.push(event.button); this._mouseButtonsPressed.push(event.button); } }; this.handleContextMenuEvent = (event) => { event.preventDefault(); return false; }; this._pageX = 0; this._pageY = 0; this._localX = 0; this._localY = 0; this._mouseButtonsDown = []; this._mouseButtonsReleased = []; this._mouseButtonsPressed = []; this.scaleProperties = { scaleX: 1, scaleY: 1, offsetX: 0, offsetY: 0, }; } get pageX() { return this._pageX; } get pageY() { return this._pageY; } get localX() { return this._localX; } get localY() { return this._localY; } get screenX() { return this._screenX; } get screenY() { return this._screenY; } get scaledX() { return this.localX / this.scaleProperties.scaleX - this.scaleProperties.offsetX; } get scaledY() { return this.localY / this.scaleProperties.scaleY - this.scaleProperties.offsetY; } get isAnyMouseDown() { return this.isAnyMousePressed || this._mouseButtonsDown.length > 0; } get isAnyMousePressed() { return this._mouseButtonsPressed.length > 0; } get isAnyMouseReleased() { return this._mouseButtonsReleased.length > 0; } /** * Registers the `mousemove`, `mosedown` and `mouseup` listeners on the passed element so that the class * can handle the input. * This also registers an event that blocks right mouse button context menu from appearing. * * @param {GlobalEventHandlers} element To avoid issues with focus it's best to pass `document` here */ registerListeners(element) { element.addEventListener("mousedown", this.handleEvent); element.addEventListener("mouseup", this.handleEvent); element.addEventListener("mousemove", this.handleEvent); element.addEventListener('contextmenu', this.handleContextMenuEvent); } } exports.MouseInput = MouseInput; //# sourceMappingURL=MouseInput.js.map