comic-plus
Version:
<p align="center"> <img width="200px" src="./logo.png"/> </p>
88 lines (87 loc) • 3.11 kB
JavaScript
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
};