258 lines
10 KiB
Java
258 lines
10 KiB
Java
![]() |
import { __extends } from "tslib";
|
|||
|
import { Controller } from './base';
|
|||
|
var PRESS_DELAY = 250;
|
|||
|
// 计算滑动的方向
|
|||
|
var calcDirection = function (start, end) {
|
|||
|
var xDistance = end.x - start.x;
|
|||
|
var yDistance = end.y - start.y;
|
|||
|
// x 的距离大于y 说明是横向,否则就是纵向
|
|||
|
if (Math.abs(xDistance) > Math.abs(yDistance)) {
|
|||
|
return xDistance > 0 ? 'right' : 'left';
|
|||
|
}
|
|||
|
return yDistance > 0 ? 'down' : 'up';
|
|||
|
};
|
|||
|
// 计算2点之间的距离
|
|||
|
var calcDistance = function (point1, point2) {
|
|||
|
var xDistance = Math.abs(point2.x - point1.x);
|
|||
|
var yDistance = Math.abs(point2.y - point1.y);
|
|||
|
return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
|
|||
|
};
|
|||
|
var getCenter = function (point1, point2) {
|
|||
|
var x = (point1.x + point2.x) / 2;
|
|||
|
var y = (point1.y + point2.y) / 2;
|
|||
|
return { x: x, y: y };
|
|||
|
};
|
|||
|
var convertPoints = function (touches, canvas) {
|
|||
|
if (!touches) {
|
|||
|
return;
|
|||
|
}
|
|||
|
var points = [];
|
|||
|
var len = touches.length;
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
var touch = touches[i];
|
|||
|
// x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
|
|||
|
var clientX = touch.clientX, clientY = touch.clientY;
|
|||
|
var point = canvas.getPointByClient(clientX, clientY);
|
|||
|
points.push(point);
|
|||
|
}
|
|||
|
return points;
|
|||
|
};
|
|||
|
var GestureController = /** @class */ (function (_super) {
|
|||
|
__extends(GestureController, _super);
|
|||
|
function GestureController(view) {
|
|||
|
var _this = _super.call(this, view) || this;
|
|||
|
_this.processEvent = {};
|
|||
|
_this.touchStart = function (ev) {
|
|||
|
var points = convertPoints(ev.originalEvent.touches, _this.canvas);
|
|||
|
if (!points) {
|
|||
|
return;
|
|||
|
}
|
|||
|
ev.points = points;
|
|||
|
// 防止上次的内容没有清理掉,重新reset下
|
|||
|
_this.reset();
|
|||
|
// 记录touch start 的时间
|
|||
|
_this.startTime = Date.now();
|
|||
|
// 记录touch start 的点
|
|||
|
_this.startPoints = points;
|
|||
|
if (points.length > 1) {
|
|||
|
_this.startDistance = calcDistance(points[0], points[1]);
|
|||
|
_this.center = getCenter(points[0], points[1]);
|
|||
|
}
|
|||
|
else {
|
|||
|
// 如果touchstart后停顿250ms, 则也触发press事件
|
|||
|
_this.pressTimeout = setTimeout(function () {
|
|||
|
// 这里固定触发press事件
|
|||
|
var eventType = 'press';
|
|||
|
ev.direction = 'none';
|
|||
|
_this.emitStart(eventType, ev);
|
|||
|
_this.emitEvent(eventType, ev);
|
|||
|
_this.eventType = eventType;
|
|||
|
}, PRESS_DELAY);
|
|||
|
}
|
|||
|
};
|
|||
|
_this.touchMove = function (ev) {
|
|||
|
var points = convertPoints(ev.originalEvent.touches, _this.canvas);
|
|||
|
if (!points) {
|
|||
|
return;
|
|||
|
}
|
|||
|
_this.clearPressTimeout();
|
|||
|
ev.points = points;
|
|||
|
var startPoints = _this.startPoints;
|
|||
|
if (!startPoints) {
|
|||
|
return;
|
|||
|
}
|
|||
|
// 多指触控
|
|||
|
if (points.length > 1) {
|
|||
|
// touchstart的距离
|
|||
|
var startDistance = _this.startDistance;
|
|||
|
var currentDistance = calcDistance(points[0], points[1]);
|
|||
|
ev.zoom = currentDistance / startDistance;
|
|||
|
ev.center = _this.center;
|
|||
|
// 触发缩放事件
|
|||
|
_this.emitStart('pinch', ev);
|
|||
|
_this.emitEvent('pinch', ev);
|
|||
|
}
|
|||
|
else {
|
|||
|
var deltaX = points[0].x - startPoints[0].x;
|
|||
|
var deltaY = points[0].y - startPoints[0].y;
|
|||
|
var direction = _this.direction || calcDirection(startPoints[0], points[0]);
|
|||
|
_this.direction = direction;
|
|||
|
// 获取press或者pan的事件类型
|
|||
|
// press 按住滑动, pan表示平移
|
|||
|
// 如果start后立刻move,则触发pan, 如果有停顿,则触发press
|
|||
|
var eventType = _this.getEventType(points);
|
|||
|
ev.direction = direction;
|
|||
|
ev.deltaX = deltaX;
|
|||
|
ev.deltaY = deltaY;
|
|||
|
_this.emitStart(eventType, ev);
|
|||
|
_this.emitEvent(eventType, ev);
|
|||
|
// 记录最后2次move的时间和坐标,为了给swipe事件用
|
|||
|
var prevMoveTime = _this.lastMoveTime;
|
|||
|
var now = Date.now();
|
|||
|
// 最后2次的时间间隔一定要大于0,否则swipe没发计算
|
|||
|
if (now - prevMoveTime > 0) {
|
|||
|
_this.prevMoveTime = prevMoveTime;
|
|||
|
_this.prevMovePoints = _this.lastMovePoints;
|
|||
|
_this.lastMoveTime = now;
|
|||
|
_this.lastMovePoints = points;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
_this.touchEnd = function (ev) {
|
|||
|
_this.emitEnd(ev);
|
|||
|
// swipe事件处理, 在touchend之后触发
|
|||
|
var lastMoveTime = _this.lastMoveTime;
|
|||
|
var now = Date.now();
|
|||
|
// 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程
|
|||
|
// 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
|
|||
|
if (now - lastMoveTime < 100) {
|
|||
|
var prevMoveTime = _this.prevMoveTime || _this.startTime;
|
|||
|
var intervalTime = lastMoveTime - prevMoveTime;
|
|||
|
// 时间间隔一定要大于0, 否则计算没意义
|
|||
|
if (intervalTime > 0) {
|
|||
|
var prevMovePoints = _this.prevMovePoints || _this.startPoints;
|
|||
|
var lastMovePoints = _this.lastMovePoints;
|
|||
|
// move速率
|
|||
|
var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime;
|
|||
|
// 0.3 是参考hammerjs的设置
|
|||
|
if (velocity > 0.3) {
|
|||
|
ev.velocity = velocity;
|
|||
|
ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]);
|
|||
|
_this.emitEvent('swipe', ev);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
_this.reset();
|
|||
|
var touches = ev.touches;
|
|||
|
// 当多指只释放了1指时也会触发end, 这时重新触发一次start
|
|||
|
if (touches && touches.length > 0) {
|
|||
|
_this.touchStart(ev);
|
|||
|
}
|
|||
|
};
|
|||
|
_this.canvas = view.getCanvas();
|
|||
|
_this.delegateEvent();
|
|||
|
// 用来记录当前触发的事件
|
|||
|
_this.processEvent = {};
|
|||
|
return _this;
|
|||
|
}
|
|||
|
Object.defineProperty(GestureController.prototype, "name", {
|
|||
|
get: function () {
|
|||
|
return 'gesture';
|
|||
|
},
|
|||
|
enumerable: false,
|
|||
|
configurable: true
|
|||
|
});
|
|||
|
GestureController.prototype.init = function () { };
|
|||
|
GestureController.prototype.render = function () { };
|
|||
|
GestureController.prototype.layout = function () { };
|
|||
|
GestureController.prototype.update = function () { };
|
|||
|
GestureController.prototype.destroy = function () {
|
|||
|
this.reset();
|
|||
|
this.offEvent();
|
|||
|
this.processEvent = null;
|
|||
|
};
|
|||
|
GestureController.prototype.delegateEvent = function () {
|
|||
|
// 代理这几个事件
|
|||
|
this.canvas.on('touchstart', this.touchStart);
|
|||
|
this.canvas.on('touchmove', this.touchMove);
|
|||
|
this.canvas.on('touchend', this.touchEnd);
|
|||
|
};
|
|||
|
GestureController.prototype.offEvent = function () {
|
|||
|
this.canvas.off('touchstart', this.touchStart);
|
|||
|
this.canvas.off('touchmove', this.touchMove);
|
|||
|
this.canvas.off('touchend', this.touchEnd);
|
|||
|
};
|
|||
|
GestureController.prototype.emitEvent = function (type, ev) {
|
|||
|
var view = this.view;
|
|||
|
view.emit(type, ev);
|
|||
|
};
|
|||
|
// 触发start事件
|
|||
|
GestureController.prototype.emitStart = function (type, ev) {
|
|||
|
if (this.isProcess(type)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
this.enable(type);
|
|||
|
this.emitEvent(type + "start", ev);
|
|||
|
};
|
|||
|
// 触发end事件
|
|||
|
GestureController.prototype.emitEnd = function (ev) {
|
|||
|
var _this = this;
|
|||
|
var processEvent = this.processEvent;
|
|||
|
Object.keys(processEvent).forEach(function (type) {
|
|||
|
_this.emitEvent(type + "end", ev);
|
|||
|
delete processEvent[type];
|
|||
|
});
|
|||
|
};
|
|||
|
GestureController.prototype.enable = function (eventType) {
|
|||
|
this.processEvent[eventType] = true;
|
|||
|
};
|
|||
|
// 是否进行中的事件
|
|||
|
GestureController.prototype.isProcess = function (eventType) {
|
|||
|
return this.processEvent[eventType];
|
|||
|
};
|
|||
|
GestureController.prototype.reset = function () {
|
|||
|
this.clearPressTimeout();
|
|||
|
this.startTime = 0;
|
|||
|
this.startPoints = null;
|
|||
|
this.startDistance = 0;
|
|||
|
this.direction = null;
|
|||
|
this.eventType = null;
|
|||
|
this.prevMoveTime = 0;
|
|||
|
this.prevMovePoints = null;
|
|||
|
this.lastMoveTime = 0;
|
|||
|
this.lastMovePoints = null;
|
|||
|
};
|
|||
|
GestureController.prototype.clearPressTimeout = function () {
|
|||
|
if (this.pressTimeout) {
|
|||
|
clearTimeout(this.pressTimeout);
|
|||
|
this.pressTimeout = 0;
|
|||
|
}
|
|||
|
};
|
|||
|
GestureController.prototype.getEventType = function (points) {
|
|||
|
var _a = this, eventType = _a.eventType, view = _a.view, startTime = _a.startTime, startPoints = _a.startPoints;
|
|||
|
if (eventType) {
|
|||
|
return eventType;
|
|||
|
}
|
|||
|
var type;
|
|||
|
var panEventListeners = view.getEvents().pan;
|
|||
|
// 如果 view 上没有 pan 事件的监听,默认都是 press
|
|||
|
if (!panEventListeners || !panEventListeners.length) {
|
|||
|
type = 'press';
|
|||
|
}
|
|||
|
else {
|
|||
|
// 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
|
|||
|
var now = Date.now();
|
|||
|
if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) {
|
|||
|
type = 'press';
|
|||
|
}
|
|||
|
else {
|
|||
|
type = 'pan';
|
|||
|
}
|
|||
|
}
|
|||
|
this.eventType = type;
|
|||
|
return type;
|
|||
|
};
|
|||
|
return GestureController;
|
|||
|
}(Controller));
|
|||
|
export default GestureController;
|
|||
|
//# sourceMappingURL=gesture.js.map
|