UNPKG

react-wb-imageviewer

Version:

Images viewer is a react component use in mobile website App, that function same as Weibo native viewer.

197 lines 6.98 kB
export class TouchGesture { el; eventPool = { 'tap': [], 'doubleTap': [], 'longTap': [], 'pressMove': [], 'pinch': [], 'tapDown': [], 'tapMove': [], 'tapUp': [] }; touchLength = 0; startPoint = { x: 0, y: 0 }; startPoint2 = { x: 0, y: 0 }; startMiddlePoint = { x: 0, y: 0 }; lastMovePoint = { x: 0, y: 0 }; lastTapEndPoint = { x: 0, y: 0 }; startSpace = { x: 0, y: 0, d: 0 }; startAngle = 0; lastDoubleTime = 0; longTimer = 0; moveFlag = false; constructor(el) { this.el = el; this.el.style.touchAction = 'none'; this._initEve(); } _initEve() { this.el.addEventListener('touchstart', this._touchstart); this.el.addEventListener('touchmove', this._tapMove); this.el.addEventListener('touchend', this._tapUp); document.addEventListener('touchmove', this._touchmove); document.addEventListener('touchend', this._touchend); } _touchstart = (e) => { if (e.targetTouches.length === 1) { // 按下且只有一根手指 this.touchLength = 1; this.startPoint = { x: e.targetTouches[0].clientX, y: e.targetTouches[0].clientY }; this.lastMovePoint = this.startPoint; this.longTimer = window.setTimeout(() => { this._longTap(e); }, 1000); } else if (e.targetTouches.length === 2) { // 按下且只有两根手指 this.startPoint2 = { x: e.targetTouches[1].clientX, y: e.targetTouches[1].clientY }; this.startSpace = this.getMove(this.startPoint, this.startPoint2); this.startAngle = this.getAngle(this.startSpace); this.startMiddlePoint = this.getMiddlePoint(this.startPoint, this.startPoint2); this.touchLength = this.startSpace.d < 5 ? 0 : 2; } e.startMiddlePoint = this.startMiddlePoint; e.touchLength = this.touchLength; this._tapDown(e); }; _touchmove = (e) => { clearTimeout(this.longTimer); const nowPoint = { x: e.touches[0].clientX, y: e.touches[0].clientY }; if (this.touchLength === 1) { // 按下且只有一根手指 const moveDistance = this.getMove(nowPoint, this.lastMovePoint); const startDistance = this.getMove(nowPoint, this.startPoint); e.moveDistance = moveDistance; e.startDistance = startDistance; this._pressMove(e); this.lastMovePoint = nowPoint; this.moveFlag = true; } else if (this.touchLength === 2) { // 按下且只有两根手指 const twoPoint = { x: e.touches[1].clientX, y: e.touches[1].clientY }; const pointSpace = this.getMove(nowPoint, twoPoint); const pointAngle = this.getAngle(pointSpace); const scale = pointSpace.d / this.startSpace.d; e.startMiddlePoint = this.startMiddlePoint; e.pointAngle = pointAngle; e.startAngle = this.startAngle; e.pointSpace = pointSpace; e.startSpace = this.startSpace; e.scale = scale; e.rotate = this.radian2angle(pointAngle - this.startAngle); this._pinch(e); } }; _touchend = (e) => { clearTimeout(this.longTimer); const tapEndPoint = { x: e.changedTouches[0].clientX, y: e.changedTouches[0].clientY }; if (this.touchLength === 1) { // 按下且只有一根手指 if (!this.moveFlag) { this._tap(e); } const lastTapEndPoint = this.lastTapEndPoint; this.interval(this.lastDoubleTime).then(() => { if (this.getMove(tapEndPoint, lastTapEndPoint).d < 30) { this._doubleTap(e); } this.lastDoubleTime = 0; this.lastTapEndPoint = { x: 0, y: 0 }; }).catch((nowTime) => { this.lastDoubleTime = nowTime; }); this.lastTapEndPoint = tapEndPoint; } else if (this.touchLength === 2) { // 按下且只有两根手指 } this.touchLength = 0; this.moveFlag = false; }; _tapDown = (e) => { this.eventPool['tapDown'].forEach((callback) => { callback(e); }); }; _tapMove = (e) => { this.eventPool['tapMove'].forEach((callback) => { callback(e); }); }; _tapUp = (e) => { this.eventPool['tapUp'].forEach((callback) => { callback(e); }); }; _tap(e) { this.eventPool['tap'].forEach((callback) => { callback(e); }); } _doubleTap(e) { this.eventPool['doubleTap'].forEach((callback) => { callback(e); }); } _longTap(e) { this.eventPool['longTap'].forEach((callback) => { callback(e); }); } _pressMove(e) { this.eventPool['pressMove'].forEach((callback) => { callback(e); }); } _pinch(e) { this.eventPool['pinch'].forEach((callback) => { callback(e); }); } on(eve, eveCallback) { this.eventPool[eve].push(eveCallback); } off(eve, eveCallback) { this.eventPool[eve] = this.eventPool[eve].filter(function (v) { return v != eveCallback; }); } destroy() { this.el.removeEventListener('touchstart', this._touchstart); this.el.removeEventListener('touchmove', this._tapMove); this.el.removeEventListener('touchend', this._tapUp); document.removeEventListener('touchmove', this._touchmove); document.removeEventListener('touchend', this._touchend); } interval(lastTime, duration = 500) { // 判定当前时间是否和给定的时间间隔符合期望值 return new Promise((resolve, reject) => { const nowTime = new Date().getTime(); if (nowTime - lastTime < duration) { resolve(nowTime); } else { reject(nowTime); } }); } getMove(p1, p2) { return { x: p1.x - p2.x, y: p1.y - p2.y, d: Math.hypot(p1.x - p2.x, p1.y - p2.y) }; } getAngle(move) { const { x, y } = move; return Math.atan2(y, x); } getMiddlePoint(p1, p2) { return { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 }; } radian2angle(radian) { return radian * 180 / Math.PI; } angle2radian(angle) { return angle * Math.PI / 180; } } //# sourceMappingURL=touch.js.map