UNPKG

10.4 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var base_1 = require("./base");
5var PRESS_DELAY = 250;
6// 计算滑动的方向
7var calcDirection = function (start, end) {
8 var xDistance = end.x - start.x;
9 var yDistance = end.y - start.y;
10 // x 的距离大于y 说明是横向,否则就是纵向
11 if (Math.abs(xDistance) > Math.abs(yDistance)) {
12 return xDistance > 0 ? 'right' : 'left';
13 }
14 return yDistance > 0 ? 'down' : 'up';
15};
16// 计算2点之间的距离
17var calcDistance = function (point1, point2) {
18 var xDistance = Math.abs(point2.x - point1.x);
19 var yDistance = Math.abs(point2.y - point1.y);
20 return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
21};
22var getCenter = function (point1, point2) {
23 var x = (point1.x + point2.x) / 2;
24 var y = (point1.y + point2.y) / 2;
25 return { x: x, y: y };
26};
27var convertPoints = function (touches, canvas) {
28 if (!touches) {
29 return;
30 }
31 var points = [];
32 var len = touches.length;
33 for (var i = 0; i < len; i++) {
34 var touch = touches[i];
35 // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
36 var clientX = touch.clientX, clientY = touch.clientY;
37 var point = canvas.getPointByClient(clientX, clientY);
38 points.push(point);
39 }
40 return points;
41};
42var GestureController = /** @class */ (function (_super) {
43 tslib_1.__extends(GestureController, _super);
44 function GestureController(view) {
45 var _this = _super.call(this, view) || this;
46 _this.processEvent = {};
47 _this.touchStart = function (ev) {
48 var points = convertPoints(ev.originalEvent.touches, _this.canvas);
49 if (!points) {
50 return;
51 }
52 ev.points = points;
53 // 防止上次的内容没有清理掉,重新reset下
54 _this.reset();
55 // 记录touch start 的时间
56 _this.startTime = Date.now();
57 // 记录touch start 的点
58 _this.startPoints = points;
59 if (points.length > 1) {
60 _this.startDistance = calcDistance(points[0], points[1]);
61 _this.center = getCenter(points[0], points[1]);
62 }
63 else {
64 // 如果touchstart后停顿250ms, 则也触发press事件
65 _this.pressTimeout = setTimeout(function () {
66 // 这里固定触发press事件
67 var eventType = 'press';
68 ev.direction = 'none';
69 _this.emitStart(eventType, ev);
70 _this.emitEvent(eventType, ev);
71 _this.eventType = eventType;
72 }, PRESS_DELAY);
73 }
74 };
75 _this.touchMove = function (ev) {
76 var points = convertPoints(ev.originalEvent.touches, _this.canvas);
77 if (!points) {
78 return;
79 }
80 _this.clearPressTimeout();
81 ev.points = points;
82 var startPoints = _this.startPoints;
83 if (!startPoints) {
84 return;
85 }
86 // 多指触控
87 if (points.length > 1) {
88 // touchstart的距离
89 var startDistance = _this.startDistance;
90 var currentDistance = calcDistance(points[0], points[1]);
91 ev.zoom = currentDistance / startDistance;
92 ev.center = _this.center;
93 // 触发缩放事件
94 _this.emitStart('pinch', ev);
95 _this.emitEvent('pinch', ev);
96 }
97 else {
98 var deltaX = points[0].x - startPoints[0].x;
99 var deltaY = points[0].y - startPoints[0].y;
100 var direction = _this.direction || calcDirection(startPoints[0], points[0]);
101 _this.direction = direction;
102 // 获取press或者pan的事件类型
103 // press 按住滑动, pan表示平移
104 // 如果start后立刻move,则触发pan, 如果有停顿,则触发press
105 var eventType = _this.getEventType(points);
106 ev.direction = direction;
107 ev.deltaX = deltaX;
108 ev.deltaY = deltaY;
109 _this.emitStart(eventType, ev);
110 _this.emitEvent(eventType, ev);
111 // 记录最后2次move的时间和坐标,为了给swipe事件用
112 var prevMoveTime = _this.lastMoveTime;
113 var now = Date.now();
114 // 最后2次的时间间隔一定要大于0,否则swipe没发计算
115 if (now - prevMoveTime > 0) {
116 _this.prevMoveTime = prevMoveTime;
117 _this.prevMovePoints = _this.lastMovePoints;
118 _this.lastMoveTime = now;
119 _this.lastMovePoints = points;
120 }
121 }
122 };
123 _this.touchEnd = function (ev) {
124 _this.emitEnd(ev);
125 // swipe事件处理, 在touchend之后触发
126 var lastMoveTime = _this.lastMoveTime;
127 var now = Date.now();
128 // 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程
129 // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
130 if (now - lastMoveTime < 100) {
131 var prevMoveTime = _this.prevMoveTime || _this.startTime;
132 var intervalTime = lastMoveTime - prevMoveTime;
133 // 时间间隔一定要大于0, 否则计算没意义
134 if (intervalTime > 0) {
135 var prevMovePoints = _this.prevMovePoints || _this.startPoints;
136 var lastMovePoints = _this.lastMovePoints;
137 // move速率
138 var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime;
139 // 0.3 是参考hammerjs的设置
140 if (velocity > 0.3) {
141 ev.velocity = velocity;
142 ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]);
143 _this.emitEvent('swipe', ev);
144 }
145 }
146 }
147 _this.reset();
148 var touches = ev.touches;
149 // 当多指只释放了1指时也会触发end, 这时重新触发一次start
150 if (touches && touches.length > 0) {
151 _this.touchStart(ev);
152 }
153 };
154 _this.canvas = view.getCanvas();
155 _this.delegateEvent();
156 // 用来记录当前触发的事件
157 _this.processEvent = {};
158 return _this;
159 }
160 Object.defineProperty(GestureController.prototype, "name", {
161 get: function () {
162 return 'gesture';
163 },
164 enumerable: false,
165 configurable: true
166 });
167 GestureController.prototype.init = function () { };
168 GestureController.prototype.render = function () { };
169 GestureController.prototype.layout = function () { };
170 GestureController.prototype.update = function () { };
171 GestureController.prototype.destroy = function () {
172 this.reset();
173 this.offEvent();
174 this.processEvent = null;
175 };
176 GestureController.prototype.delegateEvent = function () {
177 // 代理这几个事件
178 this.canvas.on('touchstart', this.touchStart);
179 this.canvas.on('touchmove', this.touchMove);
180 this.canvas.on('touchend', this.touchEnd);
181 };
182 GestureController.prototype.offEvent = function () {
183 this.canvas.off('touchstart', this.touchStart);
184 this.canvas.off('touchmove', this.touchMove);
185 this.canvas.off('touchend', this.touchEnd);
186 };
187 GestureController.prototype.emitEvent = function (type, ev) {
188 var view = this.view;
189 view.emit(type, ev);
190 };
191 // 触发start事件
192 GestureController.prototype.emitStart = function (type, ev) {
193 if (this.isProcess(type)) {
194 return;
195 }
196 this.enable(type);
197 this.emitEvent("".concat(type, "start"), ev);
198 };
199 // 触发end事件
200 GestureController.prototype.emitEnd = function (ev) {
201 var _this = this;
202 var processEvent = this.processEvent;
203 Object.keys(processEvent).forEach(function (type) {
204 _this.emitEvent("".concat(type, "end"), ev);
205 delete processEvent[type];
206 });
207 };
208 GestureController.prototype.enable = function (eventType) {
209 this.processEvent[eventType] = true;
210 };
211 // 是否进行中的事件
212 GestureController.prototype.isProcess = function (eventType) {
213 return this.processEvent[eventType];
214 };
215 GestureController.prototype.reset = function () {
216 this.clearPressTimeout();
217 this.startTime = 0;
218 this.startPoints = null;
219 this.startDistance = 0;
220 this.direction = null;
221 this.eventType = null;
222 this.prevMoveTime = 0;
223 this.prevMovePoints = null;
224 this.lastMoveTime = 0;
225 this.lastMovePoints = null;
226 };
227 GestureController.prototype.clearPressTimeout = function () {
228 if (this.pressTimeout) {
229 clearTimeout(this.pressTimeout);
230 this.pressTimeout = 0;
231 }
232 };
233 GestureController.prototype.getEventType = function (points) {
234 var _a = this, eventType = _a.eventType, view = _a.view, startTime = _a.startTime, startPoints = _a.startPoints;
235 if (eventType) {
236 return eventType;
237 }
238 var type;
239 var panEventListeners = view.getEvents().pan;
240 // 如果 view 上没有 pan 事件的监听,默认都是 press
241 if (!panEventListeners || !panEventListeners.length) {
242 type = 'press';
243 }
244 else {
245 // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
246 var now = Date.now();
247 if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) {
248 type = 'press';
249 }
250 else {
251 type = 'pan';
252 }
253 }
254 this.eventType = type;
255 return type;
256 };
257 return GestureController;
258}(base_1.Controller));
259exports.default = GestureController;
260//# sourceMappingURL=gesture.js.map
\No newline at end of file