/ src / input / Mouse.ts
Mouse.ts
  1  import { Point } from '../Point'
  2  
  3  import { Pointer } from './Pointer'
  4  import { WheelDirection } from './WheelDirection'
  5  
  6  export class Mouse extends Pointer {
  7    private readonly element: HTMLElement
  8    private click: number | null
  9    private mtime: number
 10    private loose: number | null
 11    private wheelValue: number
 12    private lastEvent: Event | null
 13  
 14    public constructor(element: HTMLElement | null = null) {
 15      super()
 16  
 17      this.click = null
 18      this.mtime = 0
 19      this.loose = null
 20      this.wheelValue = 0
 21      this.element = element instanceof HTMLElement ? element : document.body
 22  
 23      this.lastEvent = null
 24  
 25      this.listen()
 26    }
 27  
 28    public listen(): void {
 29      this.element.addEventListener('mousedown', this)
 30      this.element.addEventListener('mousemove', this)
 31      this.element.addEventListener('mouseup', this)
 32      this.element.addEventListener('wheel', this)
 33    }
 34  
 35    public unlisten(): void {
 36      this.element.removeEventListener('mousedown', this)
 37      this.element.removeEventListener('mousemove', this)
 38      this.element.removeEventListener('mouseup', this)
 39      this.element.removeEventListener('wheel', this)
 40    }
 41  
 42    public handleEvent(e: MouseEvent | WheelEvent): void {
 43      this.lastEvent = e
 44  
 45      switch (e.type) {
 46        case 'mousedown':
 47          this.onMouseDown(e as MouseEvent)
 48          break
 49  
 50        case 'mousemove':
 51          this.onMouseMove(e as MouseEvent)
 52          break
 53  
 54        case 'mouseup':
 55          this.onMouseUp(e as MouseEvent)
 56          break
 57  
 58        case 'wheel':
 59          this.onWheel(e as WheelEvent)
 60          break
 61      }
 62    }
 63  
 64    // à faire : trouver une méthode pour éviter un appel à une méthode, comme
 65    // dans la classe Keyboard
 66    public update(): void {
 67      this.mtime += 1
 68  
 69      this.wheelValue = 0
 70    }
 71  
 72    // Tant que le bouton est levé
 73    public up(): boolean {
 74      return this.click === null
 75    }
 76  
 77    // Tant que le bouton est baissé
 78    public down(): boolean {
 79      return this.click !== null
 80    }
 81  
 82    // Au moment où le bouton est enfoncé
 83    public press(): boolean {
 84      return this.click === this.mtime
 85    }
 86  
 87    // Au moment où le bouton est levé
 88    public release(): boolean {
 89      return this.loose === this.mtime
 90    }
 91  
 92    // Roulette
 93    public wheel(): WheelDirection {
 94      if (this.wheelValue < 0) {
 95        return WheelDirection.Top
 96      }
 97  
 98      if (this.wheelValue > 0) {
 99        return WheelDirection.Bottom
100      }
101  
102      return WheelDirection.None
103    }
104  
105    public getLastEvent(): Event | null {
106      return this.lastEvent
107    }
108  
109    private onMouseDown(e: MouseEvent): void {
110      this.onMouseMove(e)
111      this.click = this.mtime
112    }
113  
114    private onMouseMove(e: MouseEvent): void {
115      const position = new Point(
116        e.pageX - this.element.offsetLeft,
117        e.pageY - this.element.offsetTop,
118      )
119  
120      this.setPosition(position)
121    }
122  
123    private onMouseUp(_e: MouseEvent): void {
124      this.loose = this.mtime
125      this.click = null
126    }
127  
128    private onWheel(e: WheelEvent): void {
129      this.wheelValue = e.deltaY
130    }
131  }