UNPKG

the-finger

Version:

JavaScript library to detect touch gestures: tap, double tap, press, long press, drag, flick, rotate, pinch, spread, pan, two-finger.

456 lines (455 loc) 17.5 kB
var gt = Object.defineProperty; var et = (g) => { throw TypeError(g); }; var pt = (g, s, i) => s in g ? gt(g, s, { enumerable: !0, configurable: !0, writable: !0, value: i }) : g[s] = i; var nt = (g, s, i) => pt(g, typeof s != "symbol" ? s + "" : s, i), $ = (g, s, i) => s.has(g) || et("Cannot " + i); var t = (g, s, i) => ($(g, s, "read from private field"), i ? i.call(g) : s.get(g)), f = (g, s, i) => s.has(g) ? et("Cannot add the same private member more than once") : s instanceof WeakSet ? s.add(g) : s.set(g, i), l = (g, s, i, e) => ($(g, s, "write to private field"), e ? e.call(g, i) : s.set(g, i), i), c = (g, s, i) => ($(g, s, "access private method"), i); var tt = (g, s, i, e) => ({ set _(n) { l(g, s, n, i); }, get _() { return t(g, s, e); } }); const D = { PRESS_TIME: 350, // ms DOUBLE_TAP_INTERVAL: 250, // ms FLICK_THRESHOLD: 0.75, // drag speed DOUBLE_TAP_DRAG_THRESHOLD: 5 // px }, ht = /* @__PURE__ */ new WeakMap(); var N, V, v, X, L, b, u, F, H, x, T, K, q, w, W, P, B, Y, A, J, k, M, p, R, S, C, I, O, a, rt, lt, at, ot, ct, ut, Q, U, Z, st, ft, z, j, dt, it, G; class vt { constructor(s, i = {}) { f(this, a); f(this, N); f(this, V); f(this, v); f(this, X, null); f(this, L, !1); f(this, b); f(this, u, {}); f(this, F); f(this, H); f(this, x); f(this, T); f(this, K); f(this, q); f(this, w); f(this, W); f(this, P, null); f(this, B, null); f(this, Y, 0); f(this, A, !1); f(this, J); f(this, k, {}); f(this, M, {}); f(this, p, /* @__PURE__ */ new Map()); f(this, R, []); f(this, S); f(this, C, !1); f(this, I, null); nt(this, "gestures", { press: { start: () => (l(this, X, "press"), { type: "press", data: { x: t(this, x), y: t(this, T) } }), move: () => { }, end: () => { } }, tap: { start: () => { }, move: () => { clearTimeout(t(this, b)); }, end: (s, i) => !t(this, L) && i - t(this, F) < D.PRESS_TIME ? (clearTimeout(t(this, b)), i < t(this, H) + D.DOUBLE_TAP_INTERVAL + D.PRESS_TIME ? (l(this, H, null), { type: "double-tap", data: { x: t(this, x), y: t(this, T) } }) : (l(this, H, i), { type: "tap", data: { x: t(this, x), y: t(this, T) } })) : null }, "two-finger-tap": { start: () => { }, move: () => { }, end: (s, i) => { if (t(this, R).length === 2 && !t(this, L) && i - t(this, F) < D.PRESS_TIME) { const e = [...t(this, p).values()].map((n) => ({ x: n.x[0], y: n.y[0] })); if (e.length === 2) { const n = (e[0].x + e[1].x) / 2, h = (e[0].y + e[1].y) / 2; return { type: "two-finger-tap", data: { x: n, y: h, touches: e } }; } } return null; } }, "long-press": { start: (s, i) => { s.length === 1 && l(this, b, setTimeout(() => { l(this, X, "long-press"), l(this, u, { x: t(this, x), y: t(this, T) }), c(this, a, G).call(this, "long-press", [t(this, u)]); }, D.PRESS_TIME)); }, move: () => { clearTimeout(t(this, b)); }, end: () => { clearTimeout(t(this, b)); } }, drag: { start: () => { }, move: (s) => { if (s.length !== 1) return null; const i = s[0], e = i.clientX - t(this, v).left, n = i.clientY - t(this, v).top, { prevX: h, prevY: r } = c(this, a, it).call(this, s, t(this, x), t(this, T)); return l(this, u, { x: e, y: n, startX: t(this, x), startY: t(this, T), step: c(this, a, Q).call(this), speed: c(this, a, U).call(this), angle: c(this, a, z).call(this, h, r, e, n) }), t(this, S) || (l(this, S, c(this, a, j).call(this, t(this, x), t(this, T), e, n)), t(this, u).initial_direction = t(this, S)), { type: "drag", data: t(this, u) }; }, end: () => { var n, h; if (!t(this, L) || t(this, p).size === 0 || t(this, X) !== "drag") return null; const s = t(this, p).values().next().value; if (!((n = s == null ? void 0 : s.x) != null && n.length) || !((h = s == null ? void 0 : s.y) != null && h.length)) return null; const i = s.x, e = s.y; return l(this, K, i[i.length - 1]), l(this, q, e[e.length - 1]), t(this, u).endX = t(this, K), t(this, u).endY = t(this, q), t(this, u).speed = c(this, a, U).call(this), t(this, u).initial_direction = t(this, S), i.length > 1 && e.length > 1 && (t(this, u).final_direction = c(this, a, j).call(this, i[i.length - 2], e[e.length - 2], t(this, u).endX, t(this, u).endY)), t(this, u).flick = t(this, u).speed >= D.FLICK_THRESHOLD, { type: "drag", data: t(this, u) }; } }, pan: { start: (s) => { if (s.length < 2) return null; const { x: i, y: e } = c(this, a, st).call(this, s); l(this, x, i), l(this, T, e); }, move: (s) => { if (s.length < 2) return null; const { x: i, y: e, touchesArr: n } = c(this, a, st).call(this, s), { prevX: h, prevY: r } = c(this, a, it).call(this, s, t(this, x), t(this, T)); return l(this, u, { touches: n, x: i, y: e, startX: t(this, x), startY: t(this, T), step: c(this, a, Q).call(this), speed: c(this, a, U).call(this), angle: c(this, a, z).call(this, h, r, i, e) }), t(this, S) || (l(this, S, c(this, a, j).call(this, t(this, x), t(this, T), i, e)), t(this, u).initial_direction = t(this, S)), { type: "pan", data: t(this, u) }; }, end: () => { if (t(this, R).length < 2 || !t(this, L) || t(this, p).size === 0) return null; const s = [...t(this, p).values()].map((_) => ({ x: _.x[_.x.length - 1], y: _.y[_.y.length - 1] })), i = s.length, e = s.reduce((_, m) => _ + m.x, 0) / i, n = s.reduce((_, m) => _ + m.y, 0) / i; let h = t(this, u).x || t(this, x), r = t(this, u).y || t(this, T), o = 0, d = 0, E = 0; for (const [_, m] of t(this, p).entries()) m.x.length >= 5 && m.y.length >= 5 && (o += m.x[m.x.length - 5], d += m.y[m.y.length - 5], E++); E > 0 && (h = o / E, r = d / E); const y = c(this, a, U).call(this); return l(this, u, { touches: s, x: e, y: n, startX: t(this, x), startY: t(this, T), step: c(this, a, Q).call(this), speed: y, angle: c(this, a, z).call(this, h, r, e, n), endX: e, endY: n, initial_direction: t(this, S), final_direction: c(this, a, j).call(this, t(this, x), t(this, T), e, n), flick: y >= D.FLICK_THRESHOLD }), { type: "pan", data: t(this, u) }; } }, rotate: { start: (s) => { if (s.length !== 2) return; const [i, e] = s, n = i.clientX, h = i.clientY, r = e.clientX, o = e.clientY; l(this, w, c(this, a, z).call(this, n, h, r, o)), l(this, W, t(this, w) > 180 ? 360 * t(this, Y) + t(this, w) - 360 : 360 * t(this, Y) + t(this, w)); }, move: (s) => { if (s.length !== 2) return null; const [i, e] = s, n = i.clientX, h = i.clientY, r = e.clientX, o = e.clientY, d = c(this, a, z).call(this, n, h, r, o); c(this, a, dt).call(this, d); const E = { touches: [ { x: n, y: h }, { x: r, y: o } ], rotation: t(this, B) - t(this, W), angleAbsolute: d, angleRelative: t(this, B) }; return l(this, u, E), { type: "rotate", data: E }; }, end: () => { } }, "pinch-spread": { start: (s) => { if (s.length !== 2) return; const [i, e] = s, n = i.clientX, h = i.clientY, r = e.clientX, o = e.clientY; l(this, J, c(this, a, Z).call(this, n, h, r, o)); }, move: (s) => { if (s.length !== 2 || !t(this, k)["pinch-spread"]) return null; const [i, e] = s, n = i.clientX, h = i.clientY, r = e.clientX, o = e.clientY, d = c(this, a, Z).call(this, n, h, r, o), E = c(this, a, ft).call(this, t(this, J), d), y = { touches: [ { x: n, y: h }, { x: r, y: o } ], distance: d, scale: E }; return l(this, u, y), { type: "pinch-spread", data: y }; }, end: () => t(this, X) !== "pinch-spread" || !t(this, L) || t(this, p).size === 0 ? null : (t(this, u).end = !0, { type: "pinch-spread", data: t(this, u) }) }, "double-tap-and-drag": { start: (s, i) => { if (s.length === 1) if (t(this, H) && i < t(this, H) + D.DOUBLE_TAP_INTERVAL + D.PRESS_TIME) { l(this, C, !0); const e = s[0]; l(this, I, { x: e.clientX - t(this, v).left, y: e.clientY - t(this, v).top }); } else l(this, C, !1); }, move: (s, i) => { if (!t(this, C) || s.length !== 1) return null; const e = s[0], n = e.clientX - t(this, v).left, h = e.clientY - t(this, v).top, r = n - t(this, I).x, o = h - t(this, I).y, d = Math.sqrt(r * r + o * o); return d > D.DOUBLE_TAP_DRAG_THRESHOLD ? (l(this, X, "double-tap-and-drag"), l(this, u, { x: n, y: h, startX: t(this, I).x, startY: t(this, I).y, dx: r, dy: o, dist: d }), { type: "double-tap-and-drag", data: t(this, u) }) : null; }, end: () => { l(this, C, !1), l(this, I, null); } } }); // Private methods f(this, O, (s) => { var h, r; (h = t(this, V)) != null && h.preventDefault && s.preventDefault(); const { touches: i, type: e, timeStamp: n } = s; switch (e) { case "touchstart": c(this, a, rt).call(this, i, n); break; case "touchmove": c(this, a, lt).call(this, i, n); break; case "touchend": c(this, a, at).call(this, i, n); break; } c(this, a, ot).call(this, s), (r = t(this, V)) != null && r.visualize && visualize(i); }); l(this, N, s), l(this, V, i), s && this.on(s); } // Public API methods on(s) { l(this, N, s), s.addEventListener("touchstart", t(this, O)), s.addEventListener("touchmove", t(this, O)), s.addEventListener("touchend", t(this, O)), ht.set(s, {}); } off(s) { s = s || t(this, N), s.removeEventListener("touchstart", t(this, O)), s.removeEventListener("touchmove", t(this, O)), s.removeEventListener("touchend", t(this, O)), ht.delete(s); } track(s, i, e) { t(this, k)[s] = i, e && (e.preventDefault === !0 && (t(this, M)[s] = !0), e.preventDefault === "horizontal" && (t(this, M)[s] = "horizontal"), e.preventDefault === "vertical" && (t(this, M)[s] = "vertical")); } untrack(s) { delete t(this, k)[s]; } } N = new WeakMap(), V = new WeakMap(), v = new WeakMap(), X = new WeakMap(), L = new WeakMap(), b = new WeakMap(), u = new WeakMap(), F = new WeakMap(), H = new WeakMap(), x = new WeakMap(), T = new WeakMap(), K = new WeakMap(), q = new WeakMap(), w = new WeakMap(), W = new WeakMap(), P = new WeakMap(), B = new WeakMap(), Y = new WeakMap(), A = new WeakMap(), J = new WeakMap(), k = new WeakMap(), M = new WeakMap(), p = new WeakMap(), R = new WeakMap(), S = new WeakMap(), C = new WeakMap(), I = new WeakMap(), O = new WeakMap(), a = new WeakSet(), rt = function(s, i) { l(this, F, i), l(this, P, null), l(this, B, null), l(this, Y, 0), l(this, A, !1), l(this, X, null), c(this, a, ct).call(this, s, i); const e = Object.values(this.gestures); for (let n = 0; n < e.length; n++) { const h = e[n]; if (h.start) { const r = h.start(s, i); r && (l(this, X, r.type), c(this, a, G).call(this, r.type, [r.data, t(this, p)])); } } }, lt = function(s, i) { l(this, L, !0), c(this, a, ut).call(this, s, i); const e = Object.values(this.gestures); for (let n = 0; n < e.length; n++) { const h = e[n]; if (h.move) { const r = h.move(s, i); r && (l(this, X, r.type), c(this, a, G).call(this, r.type, [r.data, t(this, p)])); } } }, at = function(s, i) { const e = Object.values(this.gestures); for (let n = 0; n < e.length; n++) { const h = e[n]; if (h.end) { const r = h.end(s, i); r && (l(this, X, r.type), c(this, a, G).call(this, r.type, [r.data, t(this, p)])); } } s.length === 0 && (l(this, p, /* @__PURE__ */ new Map()), l(this, R, [])), l(this, L, !1), l(this, S, null); }, ot = function(s) { if (t(this, M)[t(this, X)] === !0) { s.preventDefault(); return; } const i = t(this, u).angle; i == null || Number.isNaN(i) || (t(this, M)[t(this, X)] === "horizontal" ? (i > 45 && i < 135 || i > 225 && i < 315) && s.preventDefault() : t(this, M)[t(this, X)] === "vertical" && (i > 315 || i < 45 || i > 135 && i < 225) && s.preventDefault()); }, ct = function(s, i) { l(this, v, t(this, N).getBoundingClientRect()); for (const e of s) { const n = e.identifier; if (!t(this, p).has(n)) { const h = e.clientX - t(this, v).left, r = e.clientY - t(this, v).top; l(this, x, h), l(this, T, r), t(this, p).set(n, { x: [h], y: [r], t: [i] }), t(this, R).push(n); } } }, ut = function(s, i) { if (t(this, p).size !== 0) for (const e of s) { const n = t(this, p).get(e.identifier); n && (n.x.push(e.clientX - t(this, v).left), n.y.push(e.clientY - t(this, v).top), n.t.push(i)); } }, Q = function() { let s = 0; const i = t(this, R).length; for (let e = 0; e < i; e++) { const n = t(this, R)[e], h = t(this, p).get(n); if (h && h.x.length > 1) { const r = h.x; s = Math.abs(r[r.length - 1] - r[r.length - 2]); break; } } return s; }, U = function() { var E, y, _; const s = t(this, R)[0], i = t(this, p).get(s); if (!((E = i == null ? void 0 : i.x) != null && E.length) || !((y = i == null ? void 0 : i.y) != null && y.length) || !((_ = i == null ? void 0 : i.t) != null && _.length)) return 0; const e = Math.min(5, i.x.length), n = i.x.slice(-e), h = i.y.slice(-e), r = i.t.slice(-e), o = r[r.length - 1] - r[0]; return o === 0 ? 0 : c(this, a, Z).call(this, n[0], h[0], n[n.length - 1], h[h.length - 1]) / o; }, Z = function(s, i, e, n) { return Math.hypot(e - s, n - i); }, st = function(s) { const i = s.length; let e = 0, n = 0; for (let o = 0; o < i; o++) e += s[o].clientX - t(this, v).left, n += s[o].clientY - t(this, v).top; const h = e / i, r = n / i; return { x: h, y: r, touchesArr: Array.from(s).map((o) => ({ x: o.clientX - t(this, v).left, y: o.clientY - t(this, v).top })) }; }, ft = function(s, i) { return i / s; }, z = function(s, i, e, n) { const h = e - s, r = n - i; let d = Math.atan2(r, h) * 180 / Math.PI + 90; return d < 0 && (d += 360), d > 360 && (d -= 360), d; }, j = function(s, i, e, n) { const h = c(this, a, z).call(this, s, i, e, n); if (h >= 315 || h < 45) return "top"; if (h >= 45 && h < 135) return "right"; if (h >= 135 && h < 225) return "bottom"; if (h >= 225 && h < 315) return "left"; }, dt = function(s) { if (t(this, P) === null) { l(this, P, s); return; } s - t(this, P) <= -180 ? t(this, A) ? (l(this, Y, 0), l(this, A, !1)) : tt(this, Y)._++ : s - t(this, P) >= 180 && (t(this, Y) === 0 && !t(this, A) ? l(this, A, !0) : tt(this, Y)._--), l(this, B, t(this, A) || t(this, Y) < 0 ? 360 * t(this, Y) + s - 360 : 360 * t(this, Y) + s), l(this, P, s); }, it = function(s, i, e) { let n = i, h = e; if (s.length > 1) { let r = 0, o = 0, d = 0; for (const E of s) { const y = t(this, p).get(E.identifier); y && y.x.length >= 5 && y.y.length >= 5 && (r += y.x[y.x.length - 5], o += y.y[y.y.length - 5], d++); } if (d > 0) return n = r / d, h = o / d, { prevX: n, prevY: h }; r = 0, o = 0, d = 0; for (const E of s) { const y = t(this, p).get(E.identifier); y && y.x.length > 0 && y.y.length > 0 && (r += y.x[0], o += y.y[0], d++); } d > 0 && (n = r / d, h = o / d); } else if (s.length === 1) { const r = s[0].identifier, o = t(this, p).get(r); o && o.x.length > 1 && o.y.length > 1 && (o.x.length >= 5 ? (n = o.x[o.x.length - 5], h = o.y[o.y.length - 5]) : (n = o.x[0], h = o.y[0])); } return { prevX: n, prevY: h }; }, G = function(s, i) { t(this, p).size > 0 && t(this, k)[s] && t(this, k)[s].apply(this, i); }; export { vt as default };