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:
+14
-13
@@ -4,8 +4,6 @@
|
|||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Use shared TagUtils module
|
|
||||||
const { formatTagHtml, createTagChipHtml } = window.TagUtils || {};
|
|
||||||
|
|
||||||
const container = document.getElementById('showcaseGrid');
|
const container = document.getElementById('showcaseGrid');
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
@@ -59,7 +57,7 @@
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const images = JSON.parse(dataScript.textContent);
|
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) {
|
} catch (e) {
|
||||||
console.error('Failed to parse initial images:', e);
|
console.error('Failed to parse initial images:', e);
|
||||||
}
|
}
|
||||||
@@ -174,20 +172,23 @@
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function distributeImages(images, useLazyLoading = false) {
|
function distributeImages(images, useLazyLoading = false, animate = false) {
|
||||||
images.forEach(img => {
|
images.forEach((img, i) => {
|
||||||
const colIndex = getShortestColumnIndex();
|
const colIndex = getShortestColumnIndex();
|
||||||
const item = createImageElement(img, useLazyLoading);
|
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);
|
columns[colIndex].appendChild(item);
|
||||||
|
|
||||||
// Update height estimate (will be corrected after image loads)
|
|
||||||
columnHeights[colIndex] += 300;
|
columnHeights[colIndex] += 300;
|
||||||
|
|
||||||
// Correct height after image loads
|
|
||||||
const imgEl = item.querySelector('img');
|
const imgEl = item.querySelector('img');
|
||||||
imgEl.onload = () => {
|
imgEl.onload = () => { updateColumnHeights(); };
|
||||||
updateColumnHeights();
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.dispatchEvent(new CustomEvent('showcaseUpdated'));
|
document.dispatchEvent(new CustomEvent('showcaseUpdated'));
|
||||||
@@ -236,7 +237,7 @@
|
|||||||
columns.forEach(col => col.innerHTML = '');
|
columns.forEach(col => col.innerHTML = '');
|
||||||
columnHeights = columnHeights.map(() => 0);
|
columnHeights = columnHeights.map(() => 0);
|
||||||
|
|
||||||
distributeImages(data.images);
|
distributeImages(data.images, false, true); // animate on shuffle
|
||||||
|
|
||||||
// Scroll to top
|
// Scroll to top
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
|||||||
@@ -1394,6 +1394,24 @@ header {
|
|||||||
transition: opacity 0.3s ease;
|
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
|
Forms
|
||||||
------------------------------------------------------------------------------*/
|
------------------------------------------------------------------------------*/
|
||||||
|
|||||||
Reference in New Issue
Block a user