UNPKG

vue-amazing-ui

Version:

An Amazing Vue3 UI Components Library, Using TypeScript.

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