UNPKG

vue-amazing-ui

Version:

An Amazing Vue3 UI Components Library, Using TypeScript.

150 lines (149 loc) 4.72 kB
import { defineComponent as x, ref as r, computed as g, watch as G, onMounted as B, createElementBlock as $, openBlock as k, normalizeStyle as E, Fragment as H, renderList as M, createBlock as A, unref as N, mergeProps as O, withCtx as V, createElementVNode as b, normalizeClass as j } from "vue"; import q from "../spin/index.js"; import { useResizeObserver as D } from "../utils/index.js"; const J = ["href", "target"], K = ["src", "alt", "onLoad"], X = /* @__PURE__ */ x({ __name: "Waterfall", props: { images: { default: () => [] }, columnCount: { default: 3 }, columnGap: { default: 20 }, width: { default: "100%" }, borderRadius: { default: 8 }, backgroundColor: { default: "#F2F4F8" }, spinProps: { default: () => ({}) } }, setup(o) { const t = o, s = r(), h = r(0), C = r([]), c = r([]), v = r([]), i = r([]), p = r(0), W = g(() => typeof t.width == "number" ? `${t.width}px` : t.width), z = g(() => Math.max(...i.value) + t.columnGap), f = g(() => (h.value - (t.columnCount + 1) * t.columnGap) / t.columnCount), y = g(() => t.images.length); G( () => t.images, (e, a) => { (e.length !== e.length || e.some((n, l) => n.src !== a[l]?.src)) && (c.value = [], d()); }, { deep: !0, flush: "post" } ), G( () => [t.columnCount, t.columnGap, t.width], () => { d(); }, { deep: !0, flush: "post" } ), B(() => { d(); }), D(s, () => { const e = s.value.offsetWidth; t.images.length && e !== h.value && d(); }); function d() { s.value && (h.value = s.value.offsetWidth, i.value = Array(t.columnCount).fill(0), v.value.splice(0), p.value++, I(p.value)); } async function I(e) { for (let a = 0; a < y.value; a++) if (e === p.value) c.value[a] ? w(a) : await P(t.images[a].src, a); else return !1; } function P(e, a) { if (c.value[a]) w(a); else return new Promise((l, u) => { const m = new Image(); m.src = e, m.onload = function() { c.value[a] = { // 保存已加载图片的尺寸信息 width: m.naturalWidth, height: m.naturalHeight }, w(a), l("loaded"); }, m.onerror = function(R) { u(new Error(`Failed to load image at ${e}, err: ${R}`)); }; }); } function w(e) { const a = c.value[e], n = a.height / (a.width / f.value); v.value[e] = { width: f.value, height: n, ...S(e, n) }; } function S(e, a) { if (e < t.columnCount) return i.value[e] = t.columnGap + a, { top: t.columnGap, left: (f.value + t.columnGap) * e + t.columnGap }; { const n = Math.min(...i.value); let l = 0; for (let u = 0; u < t.columnCount; u++) if (i.value[u] === n) { l = u; break; } return i.value[l] = n + t.columnGap + a, { top: n + t.columnGap, left: (f.value + t.columnGap) * l + t.columnGap }; } } function F(e) { C.value[e] = !0; } function L(e) { if (e) { if (e.name) return e.name; { const a = e.src.split("?")[0].split("/"); return a[a.length - 1]; } } return ""; } return (e, a) => (k(), $("div", { ref_key: "waterfallRef", ref: s, class: "waterfall-wrap", style: E(` --waterfall-border-radius: ${o.borderRadius}px; --waterfall-bg-color: ${o.backgroundColor}; --waterfall-width: ${W.value}; --waterfall-height: ${z.value}px; `) }, [ (k(!0), $(H, null, M(v.value, (n, l) => (k(), A(N(q), O({ class: "waterfall-image", style: `width: ${n.width}px; height: ${n.height}px; top: ${n && n.top}px; left: ${n && n.left}px;`, spinning: !C.value[l], size: "small", indicator: "dynamic-circle" }, { ref_for: !0 }, o.spinProps, { key: l }), { default: V(() => [ b("a", { class: j(["image-link", { "link-cursor": o.images[l].link }]), href: o.images[l].link, target: o.images[l].target ? o.images[l].target : "_blank" }, [ b("img", { class: "image-item", src: o.images[l].src, alt: L(o.images[l]), onLoad: (u) => F(l) }, null, 40, K) ], 10, J) ]), _: 2 }, 1040, ["style", "spinning"]))), 128)) ], 4)); } }); export { X as default };