UNPKG

magnifuer

Version:

Feature-rich Vue component and tooling for creating customizable magnifying-glass-style interfaces with ease.

324 lines (323 loc) 9.54 kB
import { toRef as R, reactive as m, computed as n, toValue as X, watch as L, defineComponent as G, mergeModels as J, useModel as K, ref as V, createElementBlock as $, openBlock as b, mergeProps as k, unref as p, renderSlot as B, createCommentVNode as Y, createBlock as Q, normalizeStyle as O, createElementVNode as N, normalizeClass as E, Teleport as U, createVNode as Z, Transition as _, withCtx as ee } from "vue"; import { useFloating as te } from "@floating-ui/vue"; import { useMouseInElement as I, useElementHover as ne } from "@vueuse/core"; function ae(a, u, e, l = {}) { const r = R(u), f = m({ width: R(e.width), height: R(e.height) }), c = R((l == null ? void 0 : l.allowOverflow) ?? !1), { elementX: v, elementY: i, x: z, y, elementWidth: M, elementHeight: S } = I(a), h = m({ x: v, y: i, absolute: { x: z, y }, isInside: ne(a) }), g = m({ width: M, height: S }), d = m({ width: n(() => f.width / r.value), height: n(() => f.height / r.value) }), w = m({ x: n( () => c.value ? h.x : Math.max( d.width / 2, Math.min( g.width - d.width / 2, h.x ) ) ), y: n( () => c.value ? h.y : Math.max( d.height / 2, Math.min( g.height - d.height / 2, h.y ) ) ) }); return m({ scale: r, x: n(() => w.x / g.width), y: n(() => w.y / g.height), absolute: w, pointer: h, size: f, containerSize: g, areaSize: d }); } function s(a) { return typeof a == "number" ? `${a}px` : a; } function oe(a, u = {}) { const e = n(() => X(u.min) ?? 1), l = n(() => X(u.max) ?? 10), r = (i) => Math.max( 1, e.value, Math.min( l.value, i ) ), f = n({ get: () => r(a.value), set: (i) => { a.value = r(i); } }); L([e, l], () => { a.value = f.value; }); function c(i) { const z = X(u.speed) ?? 1.3, y = u.step ?? ((M, S) => M * Math.pow(z, S)); f.value = y(f.value, i); } function v(i) { c(i.deltaY > 0 ? -1 : 1), i.preventDefault(), i.stopPropagation(); } return { scale: f, alter: c, onWheel: v }; } const re = ["src"], ie = ["src"], le = /* @__PURE__ */ G({ __name: "Magnifuer", props: /* @__PURE__ */ J({ controllable: { type: Boolean, default: !1 }, img: {}, anchor: { default: "self" }, position: { default: "anchor" }, transform: { type: Boolean, default: !0 }, offset: {}, floating: {}, size: { default: "anchor" }, teleport: { type: [String, Boolean], default: "body" }, transition: {}, zIndex: { default: 1e3 }, disabled: { type: Boolean, default: !1 }, allowOverflow: { type: Boolean, default: !1 }, area: { type: Boolean, default: !0 }, cursor: {}, borderRadius: {}, areaClass: {}, magnifierClass: {}, contentClass: {} }, { scale: { required: !0 }, scaleModifiers: {} }), emits: ["update:scale"], setup(a, { expose: u }) { var T; const e = a, l = K(a, "scale"), r = n(() => typeof e.controllable == "object" ? e.controllable : {}), { onWheel: f } = oe(l, { min: () => r.value.min, max: () => r.value.max, speed: () => r.value.speed, step: r.value.step }), c = V(), v = V(), { elementPositionX: i, elementPositionY: z } = I(c), y = n(() => typeof window < "u" && e.anchor instanceof HTMLElement ? e.anchor : c.value), { x: M, y: S, elementPositionX: h, elementPositionY: g, elementWidth: d, elementHeight: w } = I(y), P = m({ x: n(() => e.anchor === "pointer" ? M.value : h.value), y: n(() => e.anchor === "pointer" ? S.value : g.value), width: n(() => e.anchor === "pointer" ? 0 : d.value), height: n(() => e.anchor === "pointer" ? 0 : w.value) }); function W(t = !1) { if (e.img) return typeof e.img.src == "string" ? e.img.src : t ? e.img.src.magnifier : e.img.src.default; } const j = m({ default: n(() => W()), magnifier: n(() => W(!0)) }), H = n(() => e.position === "anchor" ? { x: P.x - (e.teleport === !1 ? i.value : 0), y: P.y - (e.teleport === !1 ? z.value : 0) } : e.position), C = n(() => { if (e.offset) return typeof e.offset == "object" ? { x: s(e.offset.x), y: s(e.offset.y) } : { x: s(e.offset), y: s(e.offset) }; }), { floatingStyles: q } = te( y, v, { open: () => { var t; return (t = e.floating) == null ? void 0 : t.open; }, placement: () => { var t; return (t = e.floating) == null ? void 0 : t.placement; }, strategy: () => { var t; return (t = e.floating) == null ? void 0 : t.strategy; }, middleware: () => { var t; return (t = e.floating) == null ? void 0 : t.middleware; }, transform: () => { var t; return (t = e.floating) == null ? void 0 : t.transform; }, whileElementsMounted: (T = e.floating) == null ? void 0 : T.whileElementsMounted } ), D = n(() => { if (e.floating) return q.value; const t = { x: s(H.value.x), y: s(H.value.y) }, x = C.value ? `translate(${C.value.x}, ${C.value.y})` : ""; return e.transform ? { position: "absolute", top: "0", left: "0", transform: [ x, `translate(${t.x}, ${t.y})` ].filter(Boolean).join(" ") } : { position: "absolute", top: t.y, left: t.x, transform: x }; }), A = ae( c, l, { width: n(() => e.size === "anchor" ? d.value : typeof e.size == "number" ? e.size : e.size.width), height: n(() => e.size === "anchor" ? w.value : typeof e.size == "number" ? e.size : e.size.height) }, { allowOverflow: () => e.allowOverflow } ), o = n(() => ({ active: !e.disabled && A.pointer.isInside, ...A, anchor: P, offset: C.value })); return u({ state: o }), (t, x) => (b(), $("div", k({ ref_key: "containerRef", ref: c, class: "magnifuer", style: { cursor: t.cursor } }, t.$attrs, { onWheel: x[0] || (x[0] = (F) => t.controllable && !t.disabled && p(f)(F)) }), [ B(t.$slots, "default", { state: o.value, isMagnifier: !1 }, () => [ t.img ? (b(), $("img", k({ key: 0 }, t.img, { src: j.default }), null, 16, re)) : Y("", !0) ], !0), t.area && o.value.active ? (b(), $("div", { key: 0, class: "magnifuer__area-container", style: O({ width: p(s)(o.value.areaSize.width), height: p(s)(o.value.areaSize.height), transform: [ "translate(-50%, -50%)", `translate(${o.value.absolute.x}px, ${o.value.absolute.y}px)` ].join(" ") }) }, [ B(t.$slots, "area", { state: o.value }, () => [ N("div", { class: E(["magnifuer__area", t.areaClass]), style: O({ borderRadius: t.borderRadius }) }, null, 6) ], !0) ], 4)) : Y("", !0), (b(), Q(U, { to: t.teleport === !1 ? void 0 : t.teleport, disabled: t.teleport === !1 }, [ Z(_, k({ name: typeof t.transition == "string" ? t.transition : void 0 }, typeof t.transition == "object" ? t.transition : {}), { default: ee(() => [ o.value.active ? (b(), $("div", { key: 0, ref_key: "magnifierRef", ref: v, class: E(["magnifuer__magnifier", t.magnifierClass]), style: O({ ...D.value, width: p(s)(o.value.size.width), height: p(s)(o.value.size.height), zIndex: t.zIndex, borderRadius: t.borderRadius }) }, [ N("div", { ref: "contentRef", class: E(["magnifuer__content", t.contentClass]), style: O({ width: p(s)(o.value.containerSize.width), height: p(s)(o.value.containerSize.height), transform: [ `scale(${l.value})`, `translate(${-o.value.x * 100}%, ${-o.value.y * 100}%)` ].join(" ") }) }, [ B(t.$slots, "magnifier", { state: o.value }, () => [ B(t.$slots, "default", { state: o.value, isMagnifier: !0 }, () => [ t.img ? (b(), $("img", k({ key: 0 }, t.img, { src: j.magnifier }), null, 16, ie)) : Y("", !0) ], !0) ], !0) ], 6) ], 6)) : Y("", !0) ]), _: 3 }, 16, ["name"]) ], 8, ["to", "disabled"])) ], 16)); } }), se = (a, u) => { const e = a.__vccOpts || a; for (const [l, r] of u) e[l] = r; return e; }, ue = /* @__PURE__ */ se(le, [["__scopeId", "data-v-fc5624b6"]]), me = { install: (a) => { a.component("Magnifuer", ue); } }; export { ue as Magnifuer, me as default, ae as useMagnifuer, oe as useMagnifuerScale };