vue-previewable-image
Version:
A previewable image Vue component based on viewerjs.
316 lines (315 loc) • 8.14 kB
JavaScript
import { ref as p, onMounted as $, onUnmounted as E, defineComponent as T, toRefs as N, computed as v, watch as b, openBlock as g, createElementBlock as z, resolveComponent as x, normalizeStyle as B, renderSlot as L, createTextVNode as P, normalizeClass as _, createBlock as C, createCommentVNode as F } from "vue";
import k from "viewerjs";
import { default as re } from "viewerjs";
const U = (e, r = !0, a, n) => {
const l = p(), u = p(""), o = p(!1), i = p(!1), w = p(!1), s = p(!1), d = p(), h = () => {
d.value = new IntersectionObserver(
(f) => {
f.forEach((y) => {
const { intersectionRatio: I, target: m } = y;
if (I > 0 && !m.classList.contains("lazy-loaded")) {
const t = new Image();
s.value = !0, t.addEventListener("load", (c) => {
m.classList.add("lazy-loaded"), u.value = e, w.value = !0, o.value = !0, i.value = !1, s.value = !1, n && n(c);
}), t.addEventListener("error", (c) => {
m.classList.add("lazy-loaded"), w.value = !0, i.value = !0, o.value = !1, s.value = !1, a && a(c);
}), t.src = e;
}
});
},
{
threshold: [1]
}
), l.value && d.value.observe(l.value);
};
return $(() => {
r ? h() : u.value = e;
}), E(() => {
var f;
l.value && ((f = d.value) == null || f.unobserve(l.value));
}), {
lazySrc: u,
lazyloadSuccess: o,
lazyloadError: i,
lazyloaded: w,
lazyloading: s,
lazyloadTrigger: l
};
};
function A(e) {
return typeof e[0] == "string";
}
const R = T({
props: {
modelValue: {
type: Boolean,
default: !1
},
currentPreviewIndex: {
type: Number,
default: 0
},
previewSrcList: {
type: Array,
default: () => []
},
viewerOptions: {
type: Object,
default: () => ({})
},
viewerTitle: {
type: Function,
default: void 0
},
zIndex: {
type: [Number, String],
default: 2015
}
},
emits: ["update:modelValue", "update:currentPreviewIndex", "switch"],
setup(e, { emit: r }) {
const { modelValue: a, previewSrcList: n, currentPreviewIndex: l } = N(e), u = v(
() => n.value && n.value.length > 0
), o = p(), i = () => {
var t;
(t = o.value) == null || t.view(s.value);
};
b(a, (t) => {
t && i();
});
const w = v(() => u.value ? A(n.value) ? n.value.map((t) => ({
src: t,
alt: t
})) : n.value : []), s = v({
get() {
return l.value;
},
set(t) {
r("update:currentPreviewIndex", t);
}
}), d = v(() => n.value.length || 0), h = () => {
const t = document.createElement("div");
return w.value.forEach((c) => {
const V = new Image();
Object.keys(c).forEach((S) => {
V[S] = c[S];
}), t.appendChild(V);
}), t.addEventListener("view", (c) => {
const V = c;
s.value = V.detail.index, r("switch", s.value, o.value);
}), t.addEventListener("hidden", () => {
r("update:modelValue", !1);
}), t;
}, f = v(() => e.viewerTitle ? (t) => e.viewerTitle(t, {
index: s.value,
total: d.value
}) : (t) => `${t.alt} (${s.value + 1}/${d.value})`), y = v(() => Object.assign(
{
title: f.value,
zIndex: e.zIndex
},
e.viewerOptions
)), I = () => {
u.value && (o.value = new k(
h(),
y.value
), a.value && i());
}, m = () => {
I();
};
return b(
[w, y],
() => {
m();
},
{ deep: !0 }
), $(() => {
m();
}), E(() => {
var t;
(t = o.value) == null || t.destroy();
}), {
hasPreviewList: u,
PreviewListLength: d,
finalPreviewSrcList: w,
viewer: o,
handleImgView: i
};
}
}), j = (e, r) => {
const a = e.__vccOpts || e;
for (const [n, l] of r)
a[n] = l;
return a;
}, M = { class: "image-viewer" };
function q(e, r, a, n, l, u) {
return g(), z("div", M);
}
const D = /* @__PURE__ */ j(R, [["render", q], ["__scopeId", "data-v-0c5bf984"]]), G = T({
name: "PreviewableImage",
components: {
ImageViewer: D
},
props: {
width: {
type: String,
default: void 0
},
height: {
type: String,
default: void 0
},
src: {
type: String,
default: ""
},
alt: {
type: String,
default: ""
},
referrerPolicy: {
type: String,
default: void 0
},
fit: {
type: String,
default: "fill"
},
zIndex: {
type: [Number, String],
default: 2015
},
previewSrcList: {
type: Array,
default: () => []
},
currentPreviewIndex: {
type: Number,
default: 0
},
viewerOptions: {
type: Object,
default: () => ({})
},
viewerTitle: {
type: Function,
default: void 0
},
lazy: {
type: Boolean,
default: !0
}
},
emits: ["switch", "update:currentPreviewIndex", "load", "error"],
setup(e, { emit: r }) {
const { previewSrcList: a, currentPreviewIndex: n } = N(e), l = v(() => ({
"--img-object-fit": e.fit
})), {
lazySrc: u,
lazyloadTrigger: o,
lazyloading: i,
lazyloadError: w,
lazyloadSuccess: s
} = U(
e.src,
e.lazy,
(t) => {
r("load", t);
},
(t) => {
r("error", t);
}
), d = v(
() => a.value && a.value.length > 0
), h = v(() => !(!d.value || e.lazy && !s.value)), f = p(!1), y = () => {
d.value && (f.value = !0);
}, I = v({
get() {
return n.value;
},
set(t) {
r("update:currentPreviewIndex", t);
}
});
return {
lazyloadTrigger: o,
imgStyleVars: l,
hasPreviewList: d,
lazySrc: u,
lazyloading: i,
lazyloadError: w,
lazyloadSuccess: s,
showImageViewer: f,
handleImgView: y,
currentViewerIndex: I,
handleSwitch: (t, c) => {
r("switch", t, c);
},
initViewer: h
};
}
}), H = {
key: 0,
class: "previewable-image__placeholder"
}, J = {
key: 1,
class: "previewable-image__error"
}, K = ["src", "alt", "referrerpolicy"];
function Q(e, r, a, n, l, u) {
const o = x("ImageViewer");
return g(), z("div", {
ref: "lazyloadTrigger",
class: "previewable-image",
style: B([{ width: e.width, height: e.height }, e.imgStyleVars])
}, [
e.lazy && e.lazyloading ? (g(), z("div", H, [
L(e.$slots, "placeholder", {}, () => [
P("Loading...")
])
])) : e.lazy && e.lazyloadError ? (g(), z("div", J, [
L(e.$slots, "error", {}, () => [
P("Load Error")
])
])) : (g(), z("img", {
key: 2,
src: e.lazySrc,
alt: e.alt,
referrerpolicy: e.referrerPolicy,
class: _([
"previewable-image__inner",
{ "previewable-image__preview": e.hasPreviewList }
]),
onClick: r[0] || (r[0] = (...i) => e.handleImgView && e.handleImgView(...i))
}, null, 10, K)),
e.initViewer ? (g(), C(o, {
key: 3,
modelValue: e.showImageViewer,
"onUpdate:modelValue": r[1] || (r[1] = (i) => e.showImageViewer = i),
"current-preview-index": e.currentViewerIndex,
"onUpdate:currentPreviewIndex": r[2] || (r[2] = (i) => e.currentViewerIndex = i),
"preview-src-list": e.previewSrcList,
"viewer-options": e.viewerOptions,
"viewer-title": e.viewerTitle,
"z-index": e.zIndex,
onSwitch: e.handleSwitch
}, null, 8, ["modelValue", "current-preview-index", "preview-src-list", "viewer-options", "viewer-title", "z-index", "onSwitch"])) : F("", !0)
], 4);
}
const O = /* @__PURE__ */ j(G, [["render", Q]]), W = (e, r) => {
const a = Object.assign(
{
componentName: O.name,
defaultViewerOptions: {}
},
r
);
e.component(a.componentName, O), k.setDefaults(a.defaultViewerOptions);
}, Z = {
install: W
};
export {
D as ImageViewer,
O as PreviewableImage,
re as Viewer,
Z as default
};