controller.js 8.8 KB

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