UNPKG

@s2ui/justified-gallery

Version:
69 lines (59 loc) 2.04 kB
import { JustifiedGalleryOptions, JustifiedImageBox, Photo } from "./types"; import { calculateLastRowOffset, loadImageAspectRatio, splitIntoRows } from "./utils/helpers"; async function computeLayout( options: JustifiedGalleryOptions ): Promise<JustifiedImageBox[]> { const { container, rowHeight: targetRowHeight, gap, lastRow = "left", } = options; const images = Array.from( container.querySelectorAll("img") ) as HTMLImageElement[]; if (!images.length) return []; // Load images with aspect ratios const photos: Photo[] = await Promise.all(images.map(loadImageAspectRatio)); const containerWidth = container.clientWidth; const rows = splitIntoRows(photos, containerWidth, targetRowHeight, gap); const layout: JustifiedImageBox[] = []; let currentTop = 0; rows.forEach(([start, end, rowWidth], rowIndex) => { const row = photos.slice(start, end + 1); const isLastRow = rowIndex === rows.length - 1; const canJustify = !(isLastRow && lastRow !== "justify"); // Calculate row height const adjustedRowHeight = canJustify ? ((containerWidth - (row.length - 1) * gap) / rowWidth) * targetRowHeight : Math.min( targetRowHeight, ((containerWidth - (row.length - 1) * gap) / rowWidth) * targetRowHeight ); let leftOffset = isLastRow && lastRow !== "justify" ? calculateLastRowOffset( lastRow, containerWidth, row, adjustedRowHeight, gap ) : 0; row.forEach((photo) => { const width = Math.round(adjustedRowHeight * photo.ratio); layout.push({ left: leftOffset, top: currentTop, width, height: Math.round(adjustedRowHeight), img: photo.img, }); leftOffset += width + gap; }); currentTop += Math.round(adjustedRowHeight) + gap; }); return layout; } export { computeLayout };