UNPKG

cross-gesture

Version:
371 lines 15.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrossGesture = void 0; var utils_1 = require("./utils"); var MOVE_OUT_DISTANCE = 10; var CrossGesture = /** @class */ (function () { function CrossGesture(el) { var _this = this; // 配置 this.options = { singleTapTimeout: 250, longTapTimeout: 750, }; // 事件监听回调函数 this.listenersMap = new Map(); // 之前滑动触点 this.touchPrePoints = {}; // 触摸点的滑动轨迹 this.touchPointsPath = new Map(); this.isMouseDown = false; this.onWheel = function (evt) { _this.dispatch('wheel', evt); }; this.onPointerDown = function (evt) { _this.dispatch('pointerdown', evt); }; this.onPointerUp = function (evt) { _this.dispatch('pointerup', evt); }; this.onPointerMove = function (evt) { _this.dispatch('pointermove', evt); }; this.onMouseDown = function (evt) { _this.isMouseDown = true; // dispatch mousedown _this.dispatch('mousedown', evt); // dispatch press move _this.dispatchPressMove(evt); }; this.onMouseMove = function (evt) { // dispatch mousemove _this.dispatch('mousemove', evt); if (!_this.isMouseDown) { return; } // dispatch press move _this.dispatchPressMove(evt); }; this.onMouseUp = function (evt) { _this.isMouseDown = false; // dispatch mouseup _this.dispatch('mouseup', evt); }; this.onTouchStart = function (evt) { // dispatch touchstart _this.dispatch('touchstart', evt); // dispatch press move _this.dispatchPressMove(evt); // update touch path _this.updatePathOfPoint(evt.touches); // 清除上一个 single tap if (_this.singleTapTimer) { clearTimeout(_this.singleTapTimer); _this.singleTapTimer = undefined; } if (!_this.longTapTimer) { _this.longTapPoint = evt.touches[0]; _this.longTapTimer = setTimeout(function () { // dispatch longTap _this.dispatch('longTap', evt); }, _this.options.longTapTimeout); } }; this.onTouchMove = function (evt) { var touches = evt.touches; if (touches.length > 1) { evt.preventDefault(); } // dispatch touchmove _this.dispatch('touchmove', evt); // dispatch press move _this.dispatchPressMove(evt); // pinch var touchPrePoints = _this.touchPrePoints.points || []; if (touches.length > 1 && touchPrePoints && touchPrePoints.length > 1) { var pre1 = touchPrePoints[0]; var pre2 = touchPrePoints[1]; var cur1 = touches[0]; var cur2 = touches[1]; var rect = _this.element.getBoundingClientRect(); var fromPoints = [ { x: pre1.clientX - rect.x, y: pre1.clientY - rect.y, }, { x: pre2.clientX - rect.x, y: pre2.clientY - rect.y, }, ]; var toPoints = [ { x: cur1.clientX - rect.x, y: cur1.clientY - rect.y, }, { x: cur2.clientX - rect.x, y: cur2.clientY - rect.y, }, ]; var rotateDeg = utils_1.getRotateDeg(fromPoints, toPoints); var zoomCenter = { x: (toPoints[0].x + toPoints[1].x) / 2, y: (toPoints[0].y + toPoints[1].y) / 2, }; var zoom = utils_1.pinchTimes(fromPoints, toPoints); _this.dispatch('pinch', evt, { fromPoints: fromPoints, toPoints: toPoints, zoomCenter: zoomCenter, zoom: zoom, }); _this.dispatch('rotate', evt, { fromPoints: fromPoints, toPoints: toPoints, rotateCenter: zoomCenter, rotateDeg: rotateDeg, }); _this.dispatch('pinchAndRotate', evt, { fromPoints: fromPoints, toPoints: toPoints, rotateCenter: zoomCenter, rotateDeg: rotateDeg, zoomCenter: zoomCenter, zoom: zoom, }); } // swipe if (touchPrePoints.length > 0 && _this.touchPrePoints.time) { var preTouch = touchPrePoints[0]; var touch = touches[0]; var fromPoint = { x: preTouch.clientX, y: preTouch.clientY, }; var toPoint = { x: touch.clientX, y: touch.clientY, }; _this.dispatch('swipe', evt, utils_1.getDirectionAndSpeed(fromPoint, toPoint, Date.now() - _this.touchPrePoints.time)); } // update touch path _this.updatePathOfPoint(evt.touches); for (var i = 0; i < evt.touches.length; i++) { var touch = evt.touches[i]; // cancel longTap if move out of distance if (_this.longTapTimer && _this.longTapPoint && _this.longTapPoint.identifier === touch.identifier && _this.moveOutDistance(touch.identifier)) { clearTimeout(_this.longTapTimer); _this.longTapTimer = undefined; _this.longTapPoint = undefined; } } }; this.onTouchEnd = function (evt) { // dispatch touchend _this.dispatch('touchend', evt); // evt.changedTouches 为结束触摸的点 if (!evt.changedTouches || !evt.changedTouches.length) { return; } for (var i = 0; i < evt.changedTouches.length; i++) { var touchEnd = evt.changedTouches[i]; // 清除 long tap if (_this.longTapPoint && _this.longTapPoint.identifier === touchEnd.identifier) { _this.longTapTimer && clearTimeout(_this.longTapTimer); _this.longTapTimer = undefined; _this.longTapPoint = undefined; } // double tap // singleTap event if (evt.changedTouches.length === 1 && evt.touches.length === 0 && !_this.moveOutDistance(touchEnd.identifier)) { _this.singleTapTimer = setTimeout(function () { _this.singleTapTimer = undefined; _this.dispatch('singleTap', evt); }, _this.options.singleTapTimeout); } var now = Date.now(); // 滑动轨迹 var path = _this.touchPointsPath.get(touchEnd.identifier); // tap event // 没有超过长安时间 // 滑动没超过 10 if (path && path[0] && now - path[0].time < _this.options.longTapTimeout && !_this.moveOutDistance(touchEnd.identifier)) { // dispatch tap event _this.dispatch('tap', evt); // double tap event if (_this.lastTapTime && now - _this.lastTapTime < _this.options.singleTapTimeout) { _this.singleTapTimer && clearTimeout(_this.singleTapTimer); _this.singleTapTimer = undefined; _this.lastTapTime = undefined; _this.dispatch('doubleTap', evt); } else { _this.lastTapTime = now; } } // 清除滑动轨迹 _this.touchPointsPath.delete(touchEnd.identifier); } // clear touch points _this.clearPrePoints(evt.changedTouches); }; this.onTouchCancel = function (evt) { var _a; // dispatch touchcancel _this.dispatch('touchcancel', evt); // cancel longTap for (var i = 0; i < evt.touches.length; i++) { var touch = evt.touches[i]; if (((_a = _this.longTapPoint) === null || _a === void 0 ? void 0 : _a.identifier) === touch.identifier) { _this.longTapTimer && clearTimeout(_this.longTapTimer); _this.longTapTimer = undefined; _this.longTapPoint = undefined; _this.touchPointsPath.delete(touch.identifier); } } // clear touch points _this.clearPrePoints(evt.changedTouches); }; var element = typeof el === 'string' ? document.querySelector(el) : el; if (!element) { throw new Error("CrossGesture: Element " + el + " does not exists on the document!"); } this.element = element; this.element.addEventListener('touchstart', this.onTouchStart); this.element.addEventListener('touchmove', this.onTouchMove, { passive: false }); this.element.addEventListener('touchend', this.onTouchEnd); this.element.addEventListener('touchcancel', this.onTouchCancel); this.element.addEventListener('touchstart', this.onTouchStart); this.element.addEventListener('mousedown', this.onMouseDown); this.element.addEventListener('mousemove', this.onMouseMove); this.element.addEventListener('mouseup', this.onMouseUp); this.element.addEventListener('pointerdown', this.onPointerDown); this.element.addEventListener('pointerup', this.onPointerUp); this.element.addEventListener('pointermove', this.onPointerMove); this.element.addEventListener('wheel', this.onWheel); } CrossGesture.prototype.updatePathOfPoint = function (touches) { this.touchPrePoints = { points: Array.from(touches), time: Date.now(), }; for (var i = 0; i < touches.length; i++) { var touch = touches[i]; var path = this.touchPointsPath.get(touch.identifier); if (!path) { path = []; this.touchPointsPath.set(touch.identifier, path); } path.push({ time: Date.now(), pageX: touch.pageX, pageY: touch.pageY, }); } }; CrossGesture.prototype.dispatch = function (eventType, evt, detail) { var listeners = this.listenersMap.get(eventType); if (!listeners) { return; } listeners.forEach(function (l) { l(evt, detail); }); }; CrossGesture.prototype.moveOutDistance = function (key, distance) { if (distance === void 0) { distance = MOVE_OUT_DISTANCE; } var path = this.touchPointsPath.get(key); if (!path) { return false; } var firstPoint = path[0]; for (var i = 1; i < path.length; i++) { var point = path[i]; if (point.pageX - firstPoint.pageX > distance || point.pageY - firstPoint.pageY > distance) { return true; } } return false; }; CrossGesture.prototype.clearPrePoints = function (touches) { if (!this.touchPrePoints.points || !this.touchPrePoints.points.length) { return; } var touchesMap = new Map(); for (var i = 0; i < touches.length; i++) { var touch = touches[i]; touchesMap.set(touch.identifier, touch); } this.touchPrePoints.points = this.touchPrePoints.points.filter(function (p) { return !touchesMap.has(p.identifier); }); }; CrossGesture.prototype.dispatchPressMove = function (evt) { var touch = evt; var rect = this.element.getBoundingClientRect(); if (touch.touches) { if (touch.touches.length !== 1) { return; } return this.dispatch('pressMove', touch, { point: { x: touch.touches[0].clientX - rect.x, y: touch.touches[0].clientY - rect.y, }, }); } var mouse = evt; return this.dispatch('pressMove', touch, { point: { x: mouse.clientX - rect.x, y: mouse.clientY - rect.y, }, }); }; CrossGesture.prototype.addListener = function (eventType, listener) { var listeners = this.listenersMap.get(eventType); if (!listeners) { listeners = []; this.listenersMap.set(eventType, listeners); } listeners.push(listener); }; CrossGesture.prototype.removeListener = function (eventType, listener) { var listeners = this.listenersMap.get(eventType); if (!listeners) { return; } // clear event timeout if (eventType === 'singleTap') { this.singleTapTimer && clearTimeout(this.singleTapTimer); this.singleTapTimer = undefined; } else if (eventType === 'longTap') { this.longTapTimer && clearTimeout(this.longTapTimer); this.longTapTimer = undefined; this.longTapPoint = undefined; } // clear listener this.listenersMap.set(eventType, listeners.filter(function (cb) { return cb !== listener; })); }; CrossGesture.prototype.destroy = function () { this.singleTapTimer && clearTimeout(this.singleTapTimer); this.longTapTimer && clearTimeout(this.longTapTimer); this.singleTapTimer = undefined; this.longTapTimer = undefined; this.longTapPoint = undefined; this.lastTapTime = undefined; this.touchPrePoints.points = undefined; this.touchPrePoints.time = undefined; this.touchPointsPath.clear(); this.listenersMap.clear(); }; return CrossGesture; }()); exports.CrossGesture = CrossGesture; //# sourceMappingURL=index.js.map