// Justified photo grid layout (Google Photos style) // Inspired by https://github.com/flickr/justified-layout (function () { const SPACING = 3; const PADDING = 3; function applyLayout() { const container = document.getElementById('lightgallery'); if (!container) return; const items = [...container.querySelectorAll('.photo-item')]; if (!items.length) return; const containerWidth = container.offsetWidth - PADDING * 2; const TARGET_HEIGHT = Math.min(220, Math.floor(containerWidth * 0.4)); const ratios = items.map(a => { const w = parseInt(a.dataset.width) || 1; const h = parseInt(a.dataset.height) || 1; return w / h; }); // Group items into rows const rows = []; let rowStart = 0; while (rowStart < ratios.length) { let sum = 0; let end = rowStart; while (end < ratios.length) { sum += ratios[end]; const rowWidth = sum * TARGET_HEIGHT + SPACING * (end - rowStart); end++; if (rowWidth >= containerWidth) break; } rows.push({ start: rowStart, end }); rowStart = end; } // Position each item let top = PADDING; rows.forEach(({ start, end }, rowIndex) => { const isLastRow = rowIndex === rows.length - 1; const count = end - start; const sumRatios = ratios.slice(start, end).reduce((a, b) => a + b, 0); const totalSpacing = SPACING * (count - 1); // Don't stretch the last row if it's not full const rowHeight = isLastRow && count < 3 ? TARGET_HEIGHT : (containerWidth - totalSpacing) / sumRatios; let left = PADDING; for (let i = start; i < end; i++) { const width = Math.round(ratios[i] * rowHeight); const height = Math.round(rowHeight); const item = items[i]; item.style.top = top + 'px'; item.style.left = left + 'px'; item.style.width = width + 'px'; item.style.height = height + 'px'; left += width + SPACING; } top += Math.round(rowHeight) + SPACING; }); container.style.height = (top - SPACING + PADDING) + 'px'; items.forEach(item => { item.style.visibility = 'visible'; const img = item.querySelector('img[data-lazy]'); if (img) img.src = img.dataset.lazy; }); } document.addEventListener('DOMContentLoaded', applyLayout); window.addEventListener('resize', applyLayout); })();