UNPKG

t-fighting-design

Version:

Fighting design can quickly build interactive interfaces in vue3 applications, which looks good.

111 lines (110 loc) 3.93 kB
import { defineComponent as G, ref as m, reactive as N, watch as I, nextTick as P, onMounted as $, onUnmounted as A, openBlock as W, createElementBlock as y, normalizeClass as B, normalizeStyle as E, Fragment as L, renderList as j, unref as q, renderSlot as F, createElementVNode as O } from "vue"; import { Props as R, Emits as U } from "./index4.js"; const V = ["src"], D = G({ name: "Waterfall" }), X = /* @__PURE__ */ G({ ...D, props: R, emits: U, setup(H, { emit: M }) { const i = H; let h = i.cols; const d = m(), u = N([]), _ = m("auto"), S = () => Math.random().toString(16).substring(2), b = m(0), x = m("0px"); I( () => i.list.length, (e) => { e && setTimeout(() => { p(); }, 0); } ); const T = async (e) => Promise.all( e.map((t) => new Promise((n) => { let o = new Image(); o.src = (t == null ? void 0 : t.src) || "", o.onload = () => { n(); }, o.onerror = () => { n(); }; })) ), p = (e = !0) => { let t = d.value.clientWidth; t = t - (Math.floor(t / i.minWidth) - 1) * parseInt(i.colGap), i.minWidth && (h = Math.floor(t / i.minWidth)), h !== Math.floor(d.value.clientWidth / i.minWidth) && (t = d.value.clientWidth - (Number(h) - 1) * parseInt(i.colGap)), b.value = h; const n = t / Number(h) + "px"; x.value = n, t = d.value.clientWidth, u.length = 0, u.push( ...i.list.map((o) => ({ src: o.src, _uuid: S(), _order: 0, _width: n, _minWidth: i.minWidth + "px", ...o })) ), P(async () => { e && await T(u); const o = d.value.querySelectorAll(".f-waterfall-box"); let w = Object.values(o).map((l, r) => ({ height: l.clientHeight, index: r })); const f = Array(h).fill(0).map(() => []); w = w.sort((l, r) => r.height - l.height), w.forEach((l) => { f.reduce((s, a) => s.reduce((v, c) => v + ((c == null ? void 0 : c.height) || 0), 0) < a.reduce((v, c) => v + ((c == null ? void 0 : c.height) || 0), 0) ? s : a, f[0]).push({ ...l }); }); const z = f.reduce((l, r) => l.reduce((s, a) => s + ((a == null ? void 0 : a.height) || 0), 0) > r.reduce((s, a) => s + ((a == null ? void 0 : a.height) || 0), 0) ? l : r, f[0]); _.value = z.reduce((l, r) => l + Number(r.height), 0) + "px", f.flat(1).reverse().forEach((l, r) => { const s = u[(l == null ? void 0 : l.index) || 0]; s._order = r; }); }); }; let g = null; const C = () => { g && clearTimeout(g), g = setTimeout(() => { p(!1); }, 10); }; $(async () => { window.onresize = C, p(); }), A(() => { window.removeEventListener("resize", C); }); const k = (e) => { const t = e.target.clientHeight, n = Math.ceil(e.target.scrollTop), o = e.target.scrollHeight; t + n === o && M("scroll-end"); }; return (e, t) => (W(), y("div", { ref_key: "waterfall", ref: d, class: B(["f-waterfall", [`f-waterfall__${e.type}`]]), style: E({ "--colCount": b.value, "--colWidth": x.value, height: e.type === "flex" ? _.value : "100%", "--rowGap": e.rowGap, "row-gap": e.rowGap, "column-gap": e.colGap }), onScroll: k }, [ (W(!0), y(L, null, j(q(u), (n, o) => (W(), y("div", { key: `waterfall_${o}`, class: "f-waterfall-box", style: E({ order: e.type === "flex" && n._order, minWidth: e.type === "flex" && n._minWidth, width: e.type === "flex" && n._width }) }, [ F(e.$slots, "default", { row: n }, () => [ O("img", { src: n.src }, null, 8, V) ]) ], 4))), 128)) ], 38)); } }); export { X as default };