vue-data-ui
Version:
A user-empowering data visualization Vue 3 components library for eloquent data storytelling
123 lines (122 loc) • 5 kB
JavaScript
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
};