magnifuer
Version:
Feature-rich Vue component and tooling for creating customizable magnifying-glass-style interfaces with ease.
324 lines (323 loc) • 9.54 kB
JavaScript
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
};