UNPKG

vue-amazing-ui

Version:

An Amazing Vue3 UI Components Library, Using TypeScript.

153 lines (152 loc) 4.83 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) => { console.log("images changed", e), (e.length !== e.length || e.some((n, l) => { var o; return n.src !== ((o = a[l]) == null ? void 0 : o.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: "m-waterfall", 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 };