UNPKG

vuux

Version:

Vue3 Nuxt3 Nuxt4 组件库

104 lines (103 loc) 3.66 kB
import { reactive as P, ref as m, computed as H, watch as R, onMounted as U, onUnmounted as q, nextTick as T } from "vue"; import { Utils as W } from "@vuux/utils"; const O = (h, x) => { const t = P({ //目标元素x x: 0, //目标元素y y: 0, //目标元素宽 w: 0, //目标元素高 h: 0, //高亮圆角 border: 4, //是否显示SVG高亮 isShowSvg: !1, //当前步骤 currentStep: 0, //是否在上方显示 isTop: !1, //是否在下方显示 isBottom: !1 }), p = m({ top: "", left: "" }), s = m(null), g = m(null), S = H(() => h.data.length), f = m([]), V = H(() => { const { x: n, y: o, w: r, h: a, border: e } = t, { width: c, height: l } = W.windowSize(), i = Math.max(r - 2 * e, 0), d = Math.max(a - 2 * e, 0); return ` M${c},0 L0,0 L0,${l} L${c},${l} L${c},0 Z M${n},${o + e} a${e},${e} 0 0 1 ${e},-${e} h${i} a${e},${e} 0 0 1 ${e},${e} v${d} a${e},${e} 0 0 1 -${e},${e} h-${i} a${e},${e} 0 0 1 -${e},-${e} v-${d} z `; }), B = (n) => { const o = n.getBoundingClientRect(); return { w: Math.round(o.width) + 12, h: Math.round(o.height) + 12, x: Math.round(o.left) - 6, y: Math.round(o.top) - 6 }; }, k = (n, o = 30) => { const r = n.getBoundingClientRect(), a = window.innerHeight; return r.top < o ? (window.scrollBy({ top: r.top - o, behavior: "smooth" }), !0) : r.bottom > a - o ? (window.scrollBy({ top: r.bottom - a + o, behavior: "smooth" }), !0) : !1; }, v = async (n) => { const o = f.value[n]; if (!o) return; await T(); const r = B(o); if (t.x = r.x, t.y = r.y, t.w = r.w, t.h = r.h, t.isShowSvg = !0, !s.value) return; const a = s.value; a.style.bottom = "auto", k(o, 30), await T(); const e = window.innerHeight, c = window.innerWidth, l = B(o), i = a.offsetWidth, d = a.offsetHeight; let w = l.y + l.h + 12, b = !1, L = !0; w + d + 30 > e && (w = l.y - d - 12, b = !0, L = !1), w = Math.max(w, 30); let u = l.x + l.w / 2 - i / 2; if (u < 10 && (u = 10), u + i + 10 > c && (u = c - i - 10), a.style.top = `${w}px`, a.style.left = `${u}px`, g.value) { let y = l.x + l.w / 2 - u - 6; y = Math.max(6, Math.min(y, i - 6)), g.value.style.left = `${y}px`; } t.x = l.x, t.y = l.y, t.w = l.w, t.h = l.h, n === 0 && (p.value.top = `${w}px`, p.value.left = `${u}px`), t.isTop = b, t.isBottom = L; }, $ = () => { !h.modelValue || !f.value.length || !s.value || !f.value[t.currentStep] || v(t.currentStep); }, M = () => { f.value = h.data.map((n) => document.querySelector(`.${n.class}`)).filter(Boolean), f.value.length > 0 ? v(0) : t.isShowSvg = !1; }, E = async (n) => { t.currentStep = 0, x("update:modelValue", !1), n === "close" && x("close"), n === "ok" && x("ok"), await W.wait(500), s.value && (s.value.style.top = p.value.top, s.value.style.left = p.value.left); }, z = () => { t.currentStep === S.value - 1 ? E("ok") : (t.currentStep++, v(t.currentStep)); }, C = () => { t.currentStep = Math.max(0, t.currentStep - 1), v(t.currentStep); }; return R( () => h.modelValue, (n) => { n && M(); } ), U(() => { h.modelValue && M(), window.addEventListener("resize", $), window.addEventListener("scroll", $, { passive: !0 }); }), q(() => { window.removeEventListener("resize", $), window.removeEventListener("scroll", $); }), { state: t, stepEl: s, arrowEl: g, stepCount: S, computedPath: V, handleClose: E, handleNext: z, handlePrev: C }; }; export { O as useTour };