import { ICanvas , IDocument } from '../apis' ; import { Control , TriggerControl } from '../core/control' ; import store from '../store' ; import { Vector2 } from '../utils/math' ; const mouseButtons = [ 'left' , 'middle' , 'right' ] ; export class Mouse { private canvas : ICanvas ; private document : IDocument ; private pointerMovement : Vector2 = new Vector2 ( ) ; private pressedButtons : Set < number > = new Set ( ) ; private queuedButtons : Set < number > = new Set ( ) ; private scrollDistance = 0 ; constructor ( { canvas , doc } ) { this . canvas = canvas ; this . document = doc ?? document ; const on = this . canvas . addEventListener . bind ( this . canvas ) ; on ( 'mousedown' , ( event ) => { store . preferGamepad = false ; this . pressedButtons . add ( event . button ) ; this . queuedButtons . add ( event . button ) ; } ) ; on ( 'mouseup' , ( event ) => { store . preferGamepad = false ; this . pressedButtons . delete ( event . button ) ; this . queuedButtons . delete ( event . button ) ; } ) ; on ( 'mousemove' , ( event ) => { store . preferGamepad = false ; this . pointerMovement . x += event . movementX ; this . pointerMovement . y += event . movementY ; } ) ; on ( 'wheel' , ( event ) => { store . preferGamepad = false ; const distance = event . deltaY ; this . scrollDistance += distance ; } ) ; } public parseButton ( button ) { if ( typeof button === 'string' ) { if ( mouseButtons . includes ( button ) ) { return mouseButtons . indexOf ( button ) ; } else { throw new Error ( `There is no mouse button called "${ button }"!` ) ; } } else { if ( button < mouseButtons . length ) { return button ; } else { throw new Error ( `There is no mouse button with the index ${ button }!` ) ; } } } public button ( button ) { const buttonNumber = this . parseButton ( button ) ; const label = [ 'Left' , 'Middle' , 'Right' ] [ buttonNumber ] + ' Mouse Button' ; return { label , query : ( ) => this . pressedButtons . has ( buttonNumber ) , trigger : { label , query : ( ) => { if ( this . queuedButtons . has ( buttonNumber ) ) { this . queuedButtons . delete ( buttonNumber ) ; return true ; } return false ; } , } , } ; } public pointer ( ) { return { label : 'Cursor' , query : ( ) => { const movement = this . pointerMovement ; this . pointerMovement = new Vector2 ( 0 , 0 ) ; return movement ; } , } ; } public wheel ( ) { return { label : 'Mouse wheel' , query : ( ) => { const distance = this . scrollDistance ; this . scrollDistance = 0 ; return distance ; } , } ; } public lockPointer ( ) { this . canvas . requestPointerLock ( ) ; } public unlockPointer ( ) { this . document . exitPointerLock ( ) ; } public isPointerLocked ( ) { return this . document . pointerLockElement === this . canvas ; } }