feat: add stagger entry animation to showcase on load and shuffle

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-20 08:44:13 -04:00
parent d4258d2ff1
commit 5e675f683f
2 changed files with 32 additions and 13 deletions
+14 -13
View File
@@ -4,8 +4,6 @@
(function() {
'use strict';
// Use shared TagUtils module
const { formatTagHtml, createTagChipHtml } = window.TagUtils || {};
const container = document.getElementById('showcaseGrid');
if (!container) return;
@@ -59,7 +57,7 @@
try {
const images = JSON.parse(dataScript.textContent);
distributeImages(images, true); // Use lazy loading for initial images (some may be below fold)
distributeImages(images, true, true); // animate on initial load
} catch (e) {
console.error('Failed to parse initial images:', e);
}
@@ -174,20 +172,23 @@
return item;
}
function distributeImages(images, useLazyLoading = false) {
images.forEach(img => {
function distributeImages(images, useLazyLoading = false, animate = false) {
images.forEach((img, i) => {
const colIndex = getShortestColumnIndex();
const item = createImageElement(img, useLazyLoading);
if (animate) {
item.style.setProperty('--stagger-index', i);
item.classList.add('animating-in');
// Remove class after animation completes so it doesn't block interactions
const delay = i * 60;
setTimeout(() => item.classList.remove('animating-in'), delay + 300);
}
columns[colIndex].appendChild(item);
// Update height estimate (will be corrected after image loads)
columnHeights[colIndex] += 300;
// Correct height after image loads
const imgEl = item.querySelector('img');
imgEl.onload = () => {
updateColumnHeights();
};
imgEl.onload = () => { updateColumnHeights(); };
});
document.dispatchEvent(new CustomEvent('showcaseUpdated'));
@@ -236,7 +237,7 @@
columns.forEach(col => col.innerHTML = '');
columnHeights = columnHeights.map(() => 0);
distributeImages(data.images);
distributeImages(data.images, false, true); // animate on shuffle
// Scroll to top
window.scrollTo({ top: 0, behavior: 'smooth' });
+18
View File
@@ -1394,6 +1394,24 @@ header {
transition: opacity 0.3s ease;
}
/* Stagger entry animation for showcase items */
@keyframes itemFadeIn {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.masonry-item.animating-in {
animation: itemFadeIn 0.25s ease forwards;
animation-delay: calc(var(--stagger-index, 0) * 60ms);
opacity: 0; /* Start hidden until animation fires */
}
/*------------------------------------------------------------------------------
Forms
------------------------------------------------------------------------------*/