UNPKG

vue-app-touch

Version:

124 lines (110 loc) 4.2 kB
interface Pos { x: number; y: number; } export default class MTouch { private tracking = false; private lastTapTime = 0; private spos: Pos; private epos: Pos; private maxDistance: number; private tapInterval: number; private openPress: boolean; private pressTime: number; private pressTimeId: number; public constructor(target: HTMLElement, option?: { maxDistance?: number, tapInterval?: number, openPress?: boolean, pressTime?: number }) { target.addEventListener('touchstart', this, false); target.addEventListener('touchmove', this, false); target.addEventListener('touchend', this, false); target.addEventListener('touchcancel', this, false); this.maxDistance = option && option.maxDistance || 5; this.tapInterval = option && option.tapInterval || 800; this.openPress = option && option.openPress || false; this.pressTime = option && option.pressTime || 650; } public handleEvent(e: TouchEvent) { const type = e.type; const touche = e.touches[0]; const target = e.target as HTMLElement; switch (type) { case 'touchstart': if (e.targetTouches.length > 1) { this.tracking = false; this.openPress && this.clearPress(); return true; } this.tracking = true; this.spos = { x: touche.pageX, y: touche.pageY } this.epos = { x: touche.pageX, y: touche.pageY } this.openPress && this.press(target); break; case 'touchmove': { this.epos = { x: touche.pageX, y: touche.pageY }; const distance = this.getDistance(this.spos, this.epos); this.openPress && distance > this.maxDistance && this.clearPress(); break; } case 'touchend': { this.openPress && this.clearPress(); if (!this.tracking) { return true; } const fingers = this.getFingers(e); const distance = this.getDistance(this.spos, this.epos); if (fingers === 0 && distance <= this.maxDistance && e.timeStamp - this.lastTapTime > this.tapInterval) { e.stopPropagation(); this.lastTapTime = e.timeStamp; this.sendTap(target); } break; } case 'touchcancel': this.openPress && this.clearPress(); break; } } private getDistance(p1: Pos, p2: Pos) { const x = p2.x - p1.x; const y = p2.y - p1.y; return Math.sqrt((x * x) + (y * y)); } private getFingers(evt: TouchEvent) { return evt.touches && evt.touches.length || 0; } private press(target: HTMLElement) { this.pressTimeId = setTimeout(() => { this.tracking = false; this.sendPress(target); }, this.pressTime); } private clearPress() { if (this.pressTimeId) { clearTimeout(this.pressTimeId); this.pressTimeId = 0; } } private sendTap(target: HTMLElement) { const targetElement = target.nodeType === Node.TEXT_NODE ? target.parentNode : target; const evt = document.createEvent('HTMLEvents'); evt.initEvent('tap', true, true); targetElement.dispatchEvent(evt); } private sendPress(target: HTMLElement) { const targetElement = target.nodeType === Node.TEXT_NODE ? target.parentNode : target; const evt = document.createEvent('HTMLEvents'); evt.initEvent('press', true, true); targetElement.dispatchEvent(evt); } } new MTouch(document.body, { openPress: true });