react-photo-album
Version:
Responsive photo gallery component for React
32 lines (31 loc) • 1.37 kB
JavaScript
import { ratio$1 as ratio } from "../utils/index.js";
//#region src/layouts/masonry/masonry.ts
function computeMasonryLayout(photos, spacing, padding, containerWidth, columns) {
const columnWidth = (containerWidth - spacing * (columns - 1) - 2 * padding * columns) / columns;
if (columnWidth <= 0) return columns > 1 ? computeMasonryLayout(photos, spacing, padding, containerWidth, columns - 1) : void 0;
const columnsCurrentTopPositions = [];
for (let i = 0; i < columns; i += 1) columnsCurrentTopPositions[i] = 0;
const columnsModel = photos.reduce((model, photo, index) => {
const shortestColumn = columnsCurrentTopPositions.reduce((currentShortestColumn, item, i) => item < columnsCurrentTopPositions[currentShortestColumn] - 1 ? i : currentShortestColumn, 0);
columnsCurrentTopPositions[shortestColumn] = columnsCurrentTopPositions[shortestColumn] + columnWidth / ratio(photo) + spacing + 2 * padding;
model[shortestColumn].push({
photo,
index
});
return model;
}, Array.from({ length: columns }, () => []));
return {
spacing,
padding,
containerWidth,
variables: { columns },
tracks: columnsModel.map((column) => ({ photos: column.map(({ photo, index }) => ({
photo,
index,
width: columnWidth,
height: columnWidth / ratio(photo)
})) }))
};
}
//#endregion
export { computeMasonryLayout, computeMasonryLayout as default };