UNPKG

vue-data-ui

Version:

A user-empowering data visualization Vue 3 components library for eloquent data storytelling

123 lines (122 loc) • 5 kB
import { ref as h, computed as H, onMounted as I, onUnmounted as W, watchEffect as _, watch as G } from "vue"; function U(r, A = { x: 0, y: 0, width: 100, height: 100 }, C = 1, k) { const l = h({ ...A }), o = h({ ...l.value }), v = h(1), E = h(!1), p = h(!1), w = h(0), X = h(null), m = h({ x: 0, y: 0 }), D = H( () => o.value.x !== l.value.x || o.value.y !== l.value.y || o.value.width !== l.value.width || o.value.height !== l.value.height ); let f = null; function M(e) { if (e.length < 2) return 0; const t = e[0].clientX - e[1].clientX, n = e[0].clientY - e[1].clientY; return Math.hypot(t, n); } function g(e) { const t = r.value; if (!t) return { x: 0, y: 0 }; const n = t.createSVGPoint(); n.x = e.clientX, n.y = e.clientY; const a = t.getScreenCTM()?.inverse(); return a ? n.matrixTransform(a) : { x: 0, y: 0 }; } function B(e, t) { const n = r.value; if (!n) return { dx: 0, dy: 0 }; const a = Math.max(1, n.clientWidth), i = Math.max(1, n.clientHeight), c = o.value.width / a, s = o.value.height / i; return { dx: e * c, dy: t * s }; } function L(e) { E.value = !0; const t = e.touches?.[0] || e; m.value = { x: t.clientX, y: t.clientY }, r.value && (r.value.style.cursor = "grabbing"); } function P(e) { if (!E.value) return; const t = e.touches?.[0] || e, n = t.clientX - m.value.x, a = t.clientY - m.value.y; if (n === 0 && a === 0) return; const { dx: i, dy: c } = B(n, a); o.value.x -= i, o.value.y -= c, m.value = { x: t.clientX, y: t.clientY }; } function d() { E.value = !1, r.value && (r.value.style.cursor = ""); } function T(e) { e.preventDefault(); const t = e.deltaY > 0 ? 0.9 : 1.1; S(t, g(e)); } function Z(e) { e.preventDefault(); const t = g(e), n = 1.02 * (1 + C / 100); V(n, t); } function V(e, t) { f && cancelAnimationFrame(f); const n = v.value, a = n * e; let i = 0; const c = (u) => u < 0.5 ? 2 * u * u : -1 + (4 - 2 * u) * u, s = () => { i += 0.02; const u = n + (a - n) * c(i); S(u / n, t), i < 1 ? f = requestAnimationFrame(s) : f = null; }; s(); } function S(e, t) { const n = v.value * e, a = n / v.value, i = o.value.width / a, c = o.value.height / a, s = (t.x - o.value.x) * (1 - 1 / a), u = (t.y - o.value.y) * (1 - 1 / a); o.value.x += s, o.value.y += u, o.value.width = i, o.value.height = c, v.value = n; } function b(e) { e.touches.length === 2 ? (p.value = !0, w.value = M(e.touches), X.value = { ...o.value }) : (e.preventDefault(), L(e)); } function F(e) { if (p.value && e.touches.length === 2) { e.preventDefault(); const t = M(e.touches); if (w.value) { const n = t / w.value; r.value.getBoundingClientRect(); const i = (e.touches[0].clientX + e.touches[1].clientX) / 2, c = (e.touches[0].clientY + e.touches[1].clientY) / 2, s = g({ clientX: i, clientY: c }); o.value = { ...X.value }, S(n, s); } } else e.preventDefault(), P(e); } function x(e) { e.touches.length < 2 && (p.value = !1), d(); } function q(e = !1) { if (!e) { o.value = { ...l.value }, v.value = 1; return; } const t = { ...o.value }, n = v.value, a = 300; let i = null; const c = (s) => { i == null && (i = s); const u = Math.min((s - i) / a, 1); o.value = { x: t.x + (l.value.x - t.x) * u, y: t.y + (l.value.y - t.y) * u, width: t.width + (l.value.width - t.width) * u, height: t.height + (l.value.height - t.height) * u }, v.value = n + (1 - n) * u, u < 1 && requestAnimationFrame(c); }; requestAnimationFrame(c); } function z(e, t = {}) { const { overwriteCurrentIfNotZoomed: n = !0 } = t; l.value = { ...e }, !D.value && n && (o.value = { ...l.value }, v.value = 1); } function Y() { const e = r.value; e && (e.addEventListener("mousedown", L), e.addEventListener("mousemove", P), e.addEventListener("mouseup", d), e.addEventListener("mouseleave", d), e.addEventListener("wheel", T, { passive: !1 }), e.addEventListener("dblclick", Z), e.addEventListener("touchstart", b, { passive: !1 }), e.addEventListener("touchmove", F, { passive: !1 }), e.addEventListener("touchend", x), e.addEventListener("touchcancel", x)); } function y() { const e = r.value; e && (e.removeEventListener("mousedown", L), e.removeEventListener("mousemove", P), e.removeEventListener("mouseup", d), e.removeEventListener("mouseleave", d), e.removeEventListener("wheel", T), e.removeEventListener("dblclick", Z), e.removeEventListener("touchstart", b), e.removeEventListener("touchmove", F), e.removeEventListener("touchend", x), e.removeEventListener("touchcancel", x)); } return I(Y), W(y), _(() => (k?.value ? Y() : y(), () => y())), G(r, (e, t) => { y(), Y(); }), { viewBox: o, resetZoom: q, isZoom: D, setInitialViewBox: z }; } export { U as u };