react-photo-album
Version:
Responsive photo gallery component for React
41 lines (40 loc) • 1.41 kB
JavaScript
import { ratio } from "../utils/index.js";
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)
}))
}))
};
}
export {
computeMasonryLayout as default
};