inputs/mouse.js

import { DOMEventHandler } from "../events/index.js"
/**
 * This handles all inputs from mouse and touchpad on laptops
 */

export class Mouse {
  /**
   * Number of times the mouse has been clicked.
   * 
   * @type number
   */
  clickCount = 0
  /**
   * If the mouse is being dragged or not.
   * 
   * @type boolean
   */
  dragging = false
  /**
   * The position from which the mouse is being dragged.
   * 
   * @type Vector_like
   */
  dragLastPosition = { x: 0, y: 0 }
  /**
   * Distance vector between the last frame's position and current position.
   * 
   * @type Vector_like
   */
  delta = { x: 0, y: 0 }
  /**
   * Position of the mouse in current frame.
   * 
   * @type Vector_like
   */
  position = { x: 0, y: 0 }
  /**

   * Position of the mouse in last frame.

   * 
   * @type Vector_like
   */
  lastPosition = { x: 0, y: 0 }
  /**
   * If the left mouse button is pressed or not.
   * 
   * @type boolean
   */
  leftbutton = false
  /**
   * If the right mouse button is pressed or not.
   * 
   * @type boolean
   */
  rightbutton = false
  /**
   * @param {DOMEventHandler} eh
   */
  constructor(eh) {
    this.init(eh)
  }
  /**
   * Checks to see if the vector provided is
   * within a dragbox if mouse is being dragged with a right or left button down
   * 
   * @param {Vector_like} pos an object containing x and y coordinates to be checked
   * @returns {Boolean}
   * 
   */
  inDragBox(pos) {
    if (!this.dragging) return false
    if (pos.x > this.dragLastPosition.x && pos.x < this.position.x &&
      pos.y > this.dragLastPosition.y &&
      pos.y < this.position.y) {
      return false
    }
    return true
  }
  /**
   * Initializes the mouse by appending to the DOM
   *
   * @param {DOMEventHandler} eh
   */
  init(eh) {
    eh.add('click', this._onClick)
    eh.add('mousedown', this._onDown)
    eh.add('mouseup', this._onUp)
    eh.add('wheel', this._onWheel)
    eh.add('mousemove', this._onMove)
    eh.add("contextmenu", this._onContextMenu)
  }
  /**
   * @private
   */
  // @ts-ignore
  // @ts-ignore
  _onClick = (e) => {
    ++this.clickCount
  }
  /**
   * @private
   */
  // @ts-ignore
  _onMove = (e) => {
    this.position.x = e.clientX;

    this.position.y = e.clientY

    if (this.lastPosition.x === undefined) {
      this.lastPosition = { ...this.position }
    }
    this.delta.x = this.position.x - this.lastPosition.x
    this.delta.y = this.position.y - this.lastPosition.y
    this.dragging = this.leftbutton || this.rightbutton ? true : false
    if (!this.dragging) {
      this.dragLastPosition.x = e.clientX;
      this.dragLastPosition.y = e.clientY
    }
  }
  /**
   * @private
   */
  // @ts-ignore
  _onDown = (e) => {
    switch (e.button) {

      case 0:

        this.leftbutton = true
        break;
      case 2:
        this.rightbutton = true
        break;
    }
  }
  /**
   * @private
   */
  // @ts-ignore
  _onUp = (e) => {
    switch (e.button) {
      case 0:
        this.leftbutton = false
        break;
      case 2:
        this.rightbutton = false
        break;
    }
  }
  /**
   * @private
   */
  // @ts-ignore
  _onWheel = (e) => {
  }
  /**
   * @private
   */
  // @ts-ignore
  _onContextMenu = (e) => {
    e.preventDefault()
  }
  /**
   * Updates the mouse internals.
   */
  update() {
    this.lastPosition = { ...this.position }
  }
}