ITR-Website/src/components/Waterfall.js
2023-09-26 19:25:53 -05:00

93 lines
2.5 KiB
JavaScript

import { useSize } from "ahooks";
import React, { useRef, useEffect, useState } from "react";
import "../assets/stylesheets/waterfall.scss";
import { Image } from "antd";
const WaterfallItem = ({ data, onLoad }) => {
const ref = useRef();
const size = useSize(ref);
const sizeRef = useRef({});
useEffect(() => {
sizeRef.current.size = size;
}, [size]);
return (
<div className="waterfallItem" ref={ref}>
<div className="project__content__main__container">
<h3 style={{ color: "#fff", marginBottom: 12 }}>{data.title}</h3>
<div className="project_item_content">
<Image
onLoad={() => {
setTimeout(() => {
onLoad(sizeRef.current.size);
}, 500);
}}
alt="asd"
onError={setTimeout(() => {
onLoad(sizeRef.current.size);
}, 500)}
width={"100%"}
src={data.img}
/>
<span>{data.content}</span>
</div>
</div>
</div>
);
};
const WaterfallPosition = ({ columnNumber, list }) => {
const stateRef = useRef({
heights: [],
loadNum: 0,
});
const onload = (index, height) => {
stateRef.current.heights[index] = height;
stateRef.current.loadNum++;
if (stateRef.current.loadNum === list.length) {
onSize();
}
};
const [columns, setColumns] = useState([[], [], [], []]);
const onSize = () => {
let res = [[], [], [], []];
let columnHeights = [0, 0, 0, 0];
rendered.map((renderItem, index) => {
let minHeight = Infinity;
let minHeightIndex = 0;
for (let i = 0; i < columnNumber; ++i) {
if (minHeight > columnHeights[i]) {
minHeight = columnHeights[i];
minHeightIndex = i;
}
}
res[minHeightIndex].push(renderItem);
columnHeights[minHeightIndex] += stateRef.current.heights[minHeightIndex];
});
setColumns(res);
};
const waterfallDOM = useRef();
const size = useSize(waterfallDOM);
useEffect(() => {
onSize();
}, [size, columnNumber]);
const rendered = list.map((item, index) => (
<WaterfallItem onLoad={(size) => onload(index, size.height)} data={item} />
));
return (
<div ref={waterfallDOM} className="waterfallContainer">
{columns.map((column) => {
return (
<div
style={{
width: `calc(${100 / columnNumber}% - 16px)`,
}}
>
{column}
</div>
);
})}
</div>
);
};
export default WaterfallPosition;