import {EventService} from "../eventService"; import {IEventEmitter} from "../interfaces/iEventEmitter"; import {Utils as _} from "../utils"; import {AgEvent} from "../events"; export interface TapEvent extends AgEvent { touchStart: Touch; } export interface LongTapEvent extends AgEvent { touchStart: Touch; } export class TouchListener implements IEventEmitter { private eElement: HTMLElement; private destroyFuncs: Function[] = []; private moved: boolean; private touching = false; private touchStart: Touch; private eventService: EventService = new EventService(); // private mostRecentTouch: Touch; public static EVENT_TAP = 'tap'; public static EVENT_LONG_TAP = 'longTap'; constructor(eElement: HTMLElement) { this.eElement = eElement; let startListener = this.onTouchStart.bind(this); let moveListener = this.onTouchMove.bind(this); let endListener = this.onTouchEnd.bind(this); this.eElement.addEventListener('touchstart', startListener, {passive:true}); this.eElement.addEventListener('touchmove', moveListener, {passive:true}); this.eElement.addEventListener('touchend', endListener, {passive:true}); this.destroyFuncs.push( ()=> { this.eElement.addEventListener('touchstart', startListener, {passive:true}); this.eElement.addEventListener('touchmove', moveListener, {passive:true}); this.eElement.addEventListener('touchend', endListener, {passive:true}); }); } private getActiveTouch(touchList: TouchList): Touch { for (let i = 0; i { let touchesMatch = this.touchStart === touchStartCopy; if (this.touching && touchesMatch && !this.moved) { this.moved = true; let event: LongTapEvent = { type: TouchListener.EVENT_LONG_TAP, touchStart: this.touchStart }; this.eventService.dispatchEvent(event); } }, 500); } private onTouchMove(touchEvent: TouchEvent): void { if (!this.touching) { return; } let touch = this.getActiveTouch(touchEvent.touches); if (!touch) { return; } let eventIsFarAway = !_.areEventsNear(touch, this.touchStart, 4); if (eventIsFarAway) { this.moved = true; } } private onTouchEnd(touchEvent: TouchEvent): void { if (!this.touching) { return; } if (!this.moved) { let event: TapEvent = { type: TouchListener.EVENT_TAP, touchStart: this.touchStart }; this.eventService.dispatchEvent(event); } this.touching = false; } public destroy(): void { this.destroyFuncs.forEach( func => func() ); } }