UNPKG

3.15 kBJavaScriptView Raw
1import { supportsPassiveEventListener } from '@material/mwc-base/utils.js';
2function toPointer(ev) {
3 const { clientX, clientY, pageX, pageY } = ev;
4 const x = Math.max(pageX, clientX);
5 const y = Math.max(pageY, clientY);
6 const id = ev.identifier || ev.pointerId;
7 return { x, y, id: id == null ? 0 : id };
8}
9function getFirstTouch(startPointer, ev) {
10 const changedTouches = ev.changedTouches;
11 if (changedTouches == null)
12 return { newPointer: toPointer(ev), oldPointer: startPointer };
13 const touches = Array.from(changedTouches, n => toPointer(n));
14 const newPointer = startPointer == null
15 ? touches[0]
16 : touches.find(n => n.id === startPointer.id);
17 return { newPointer, oldPointer: startPointer };
18}
19function addPassiveEventListener(node, event, callback) {
20 node.addEventListener(event, callback, supportsPassiveEventListener ? { passive: true } : false);
21}
22export class Tracker {
23 constructor(_element, handlers) {
24 this._element = _element;
25 this._startPointer = null;
26 const { down, move, up } = handlers;
27 this._down = this._onDown(down);
28 this._move = this._onMove(move);
29 this._up = this._onUp(up);
30 if (_element && _element.addEventListener) {
31 _element.addEventListener('mousedown', this._down);
32 addPassiveEventListener(_element, 'touchstart', this._down);
33 addPassiveEventListener(_element, 'touchmove', this._move);
34 addPassiveEventListener(_element, 'touchend', this._up);
35 }
36 }
37 disconnect() {
38 const rootEl = this._element;
39 if (rootEl && rootEl.removeEventListener) {
40 rootEl.removeEventListener('mousedown', this._down);
41 rootEl.removeEventListener('touchstart', this._down);
42 rootEl.removeEventListener('touchmove', this._move);
43 rootEl.removeEventListener('touchend', this._up);
44 }
45 }
46 _onDown(down) {
47 return (ev) => {
48 if (ev instanceof MouseEvent) {
49 this._element.addEventListener('mousemove', this._move);
50 this._element.addEventListener('mouseup', this._up);
51 this._element.addEventListener('mouseleave', this._up);
52 }
53 const { newPointer } = getFirstTouch(this._startPointer, ev);
54 down(newPointer, ev);
55 this._startPointer = newPointer;
56 };
57 }
58 _onMove(move) {
59 return (ev) => {
60 this._updatePointers(move, ev);
61 };
62 }
63 _onUp(up) {
64 return (ev) => {
65 this._updatePointers(up, ev, true);
66 };
67 }
68 _updatePointers(cb, ev, shouldReset) {
69 if (shouldReset && ev instanceof MouseEvent) {
70 this._element.removeEventListener('mousemove', this._move);
71 this._element.removeEventListener('mouseup', this._up);
72 this._element.removeEventListener('mouseleave', this._up);
73 }
74 const { newPointer, oldPointer } = getFirstTouch(this._startPointer, ev);
75 cb(newPointer, oldPointer, ev);
76 this._startPointer = shouldReset ? null : newPointer;
77 }
78}