import { Vector } from '../math/vector'; import type { PointerEvent } from './pointer-event'; import type { EventKey, Handler, Subscription } from '../event-emitter'; import { EventEmitter } from '../event-emitter'; import type { PointerEvents } from './pointer-event-receiver'; import { GlobalCoordinates } from '../math/global-coordinates'; import type { Engine } from '../engine'; export class PointerAbstraction { public events = new EventEmitter(); /** * The last position on the document this pointer was at. Can be `null` if pointer was never active. */ public lastPagePos: Vector = Vector.Zero; /** * The last position on the screen this pointer was at. Can be `null` if pointer was never active. */ public lastScreenPos: Vector = Vector.Zero; /** * The last position in the game world coordinates this pointer was at. Can be `null` if pointer was never active. */ public lastWorldPos: Vector = Vector.Zero; constructor() { this.on('move', this._onPointerMove); this.on('down', this._onPointerDown); } public emit>(eventName: TEventName, event: PointerEvents[TEventName]): void; public emit(eventName: string, event?: any): void; public emit | string>(eventName: TEventName, event?: any): void { this.events.emit(eventName, event); } public on>(eventName: TEventName, handler: Handler): Subscription; public on(eventName: string, handler: Handler): Subscription; public on | string>(eventName: TEventName, handler: Handler): Subscription { return this.events.on(eventName, handler); } public once>(eventName: TEventName, handler: Handler): Subscription; public once(eventName: string, handler: Handler): Subscription; public once | string>(eventName: TEventName, handler: Handler): Subscription { return this.events.once(eventName, handler); } public off>(eventName: TEventName, handler: Handler): void; public off(eventName: string, handler: Handler): void; public off(eventName: string): void; public off | string>(eventName: TEventName, handler?: Handler): void { this.events.off(eventName, handler as any); } /** * Called internally by excalibur to keep pointers up to date * @internal * @param engine */ public _updateWorldPosition(engine: Engine) { const coord = GlobalCoordinates.fromPagePosition(this.lastPagePos, engine); this.lastScreenPos = coord.screenPos; this.lastWorldPos = coord.worldPos; } private _onPointerMove = (ev: PointerEvent): void => { this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y); this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y); this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y); }; private _onPointerDown = (ev: PointerEvent): void => { this.lastPagePos = new Vector(ev.pagePos.x, ev.pagePos.y); this.lastScreenPos = new Vector(ev.screenPos.x, ev.screenPos.y); this.lastWorldPos = new Vector(ev.worldPos.x, ev.worldPos.y); }; }