UNPKG

comic-plus

Version:

<p align="center"> <img width="200px" src="./logo.png"/> </p>

88 lines (87 loc) 3.11 kB
import { defineComponent, ref, provide, onMounted, onUpdated, h } from "vue"; import "../style/waterfall.css"; import "../../../utils/config.mjs"; import { debounce } from "../../../utils/tools.mjs"; import { addClass, removeClass } from "../../../utils/dom.mjs"; import "@vueuse/core"; import { waterfallProps, waterfallEmits } from "./main.props.mjs"; import { WATERFALL_PROVIDE } from "./type.mjs"; import { useResize } from "../../../hooks/resize.mjs"; const findIndexOfMinOrMax = (arr, flag) => { if (arr.length === 0) { return -1; } let flagValue; { flagValue = Math.min(...arr); } const index = arr.indexOf(flagValue); return index; }; const Waterfall = defineComponent({ name: "CuWaterfall", props: waterfallProps, emits: waterfallEmits, setup(props, { slots, emit }) { const waterfallRef = ref(null); const containerWidth = ref(0); const dFc = debounce(setWaterfallStyle, 300); function setWaterfallStyle() { if (!waterfallRef.value || !containerWidth.value) return; let colNum; if (props.colWidth) { colNum = Math.floor((containerWidth.value + props.gutter) / (props.colWidth + props.gutter)); colNum = Math.min(colNum, waterfallRef.value.children.length); } else { colNum = props.col; } let childrenList = new Array(colNum).fill(0); let list = Array.from(waterfallRef.value.children).filter( //防犊子 防止某些傻逼不使用item组件 (el) => el.classList.value.indexOf("cu-waterfall-item") >= 0 ); list.forEach((item) => { let itemRect = item.getBoundingClientRect(); let maxIdx = findIndexOfMinOrMax(childrenList); let w = (containerWidth.value - props.gutter * (colNum - 1)) / colNum; let x = maxIdx * w + maxIdx * props.gutter; let y = childrenList[maxIdx]; item.style.setProperty("width", w + "px"); item.style.setProperty("transform", `translate3d(${x}px,${y}px,0px)`); item.style.setProperty("visibility", "visible"); item.setAttribute("data-show", "show"); addAnimation(item); childrenList[maxIdx] += itemRect.height + props.gutter; }); waterfallRef.value.style.setProperty("height", Math.max(...childrenList) - props.gutter + "px"); emit("update"); } function addAnimation(el) { if (el.classList.value.indexOf("loaded") >= 0) return; addClass(el, "loaded"); if (props.fadeIn) addClass(el, "fadeIn"); setTimeout(() => { removeClass(el, "fadeIn"); el.style.setProperty("transition", "transform 300ms"); }, 500); } useResize(waterfallRef, (rect) => { containerWidth.value = rect.width; dFc(); }); provide(WATERFALL_PROVIDE, { updateStyle: dFc }); onMounted(() => { containerWidth.value = waterfallRef.value.getBoundingClientRect().width; setWaterfallStyle(); }); onUpdated(dFc); return () => { return h("div", { class: "cu-waterfall", ref: waterfallRef }, slots); }; } }); export { Waterfall as default };