input_handler_mouse_handler.js#

CODE
import InputHandler from "./input_handler.js";
import EventHandlerLayer from "../../event/event_handler_layer.js";
import Vec2 from "../../game/vector/vec2.js";
/**
* @module MouseHandler
* @fileoverview Contains MouseHandler class.
*/
/**
* Mouse input handler.
* @class
* @extends InputHandler
*/
class MouseHandler extends InputHandler {
/**
* Create a new mouse input handler.
* @param {EventHandler|EventHandlerLayer} parentHandler Parent event handler or layer
* @param {function} condition Function for checking whether events should run
* @constructor
*/
constructor(parentHandler, condition = () => { return true; }) {
const handler = new EventHandlerLayer(parentHandler, "mouse/");
super(handler, "", condition);
this._other = handler;
this._pos = new Vec2();
this._captured = false;
this._downHandler = this._handleDown.bind(this);
this._upHandler = this._handleUp.bind(this);
this._moveHandler = this._handleMove.bind(this);
this._wheelHandler = this._handleWheel.bind(this);
this._blurHandler = this._handleBlur.bind(this);
this._init();
}
destructor() {
super.destructor();
document.removeEventListener("mousedown", this._downHandler);
document.removeEventListener("mouseup", this._upHandler);
document.removeEventListener("mousemove", this._moveHandler);
document.removeEventListener("wheel", this._wheelHandler);
document.removeEventListener("blur", this._blurHandler);
}
/**
* Set up mouse input listening.
* @private
*/
_init() {
document.addEventListener("mousedown", this._downHandler);
document.addEventListener("mouseup", this._upHandler);
document.addEventListener("mousemove", this._moveHandler);
document.addEventListener("wheel", this._wheelHandler);
window.addEventListener("blur", this._blurHandler);
}
// Getters
/**
* Get the current position of the mouse.
* @returns {Vec2} Current position of mouse.
*/
get pos() {
return this._pos.copy();
}
/**
* Check if the mouse is currently within the canvas.
* @returns {boolean} Whether mouse is within canvas
*/
isInWindow() {
const pos = this.pos;
const c = $$.canvas;
return pos.x >= 0 && pos.x <= c.width && pos.y >= 0 && pos.y <= c.height;
}
// Mouse movement
/**
* Add a function to listen for mouse movement.
* @param {function} func Function to run upon mouse movement
*/
onMove(func = () => {}) {
this._other.on("move", func);
}
/**
* Handle mouse movement.
* @param {number} x Current mouse position along the x-axis
* @param {number} y Current mouse position along the y-axis
* @private
*/
_doMove(x, y) {
if (!this._condition())
return;
const newPos = new Vec2(x, y);
const d = newPos.sub(this._pos);
this._pos = newPos;
this._other.do("move", d);
}
// Mouse scroll wheel
/**
* Add a function to listen for the mouse scroll wheel.
* @param {function} func Function to run upon scrolling
*/
onScroll(func = () => {}) {
this._other.on("scroll", func);
}
/**
* Handle scrolling.
* @param {number} val Scroll value
* @private
*/
_doScroll(val) {
if (!this._condition())
return;
this._other.do("scroll", val);
}
// Cursor
/**
* Set the mouse cursor ("default" by default).
* @param {string} cursor New cursor
*/
setCursor(cursor = "default") {
if (!this._condition())
return;
document.body.style.cursor = cursor;
}
// Handling button presses
/**
* Handle the event of pressing down a button.
* @param {MouseEvent} event Event from document
* @private
*/
_handleDown(event) {
if (!this.gameFocused())
return;
const button = event.button;
if (!this._currentlyDown.has(button))
this._doPress(button);
this._currentlyDown.add(button);
this._doDown(button);
}
/**
* Handle the event of releasing a button.
* @param {MouseEvent} event Event from document
* @private
*/
_handleUp(event) {
const button = event.button;
if (!this.gameFocused()) {
this._currentlyDown.delete(button);
return;
}
this._currentlyDown.delete(button);
this._doRelease(button);
}
/**
* Handle the event of mouse movement.
* @param {MouseEvent} event Event from document
* @private
*/
_handleMove(event) {
this._doMove(event.pageX - $$.app.canvas.offsetLeft, event.pageY - $$.app.canvas.offsetTop);
}
/**
* Handle the event of pressing down a button.
* @param {WheelEvent} event Event from document
* @private
*/
_handleWheel(event) {
this._doScroll(-Math.sign(event.deltaY));
}
/**
* Handle the event of the page losing focus.
* @private
*/
_handleBlur() {
this._currentlyDown.clear();
}
// Capture mouse
/**
* Capture and "claim" the mouse
* @returns {boolean} Whether capture was successful
*/
capture() {
if (this._captured)
return false;
this._captured = true;
return true;
}
/**
* Release the mouse.
*/
release() {
this._captured = false;
}
/**
* Check if the mouse is currently captured.
* @returns {boolean} Whether the mouse is captured
*/
isCaptured() {
return this._captured;
}
}
export default MouseHandler;