improved image loading animation
All checks were successful
Run Integration Tests / test (push) Successful in 28s

This commit is contained in:
partisan 2025-04-23 12:26:05 +02:00
parent 5fdbe231d1
commit 30528d629b
4 changed files with 111 additions and 21 deletions

View file

@ -1,5 +1,40 @@
// dynamicscrollingimages.js
(function() {
// Configuration
// Add loading effects to image and title
function addLoadingEffects(imgElement) {
const title = imgElement.closest('.image').querySelector('.img_title');
imgElement.classList.add('loading-image');
title.classList.add('title-loading');
}
function removeLoadingEffects(imgElement) {
const title = imgElement.closest('.image').querySelector('.img_title');
imgElement.classList.remove('loading-image');
title.classList.remove('title-loading');
if (imgElement.src.endsWith('/images/missing.svg')) {
imgElement.closest('.image').remove();
}
}
// Modified handleImageError with theme-consistent error handling
function handleImageError(imgElement, retryCount = 3, retryDelay = 1000) {
const container = imgElement.closest('.image');
const title = container.querySelector('.img_title');
if (retryCount > 0) {
setTimeout(() => {
imgElement.src = imgElement.getAttribute('data-full');
imgElement.onerror = () => handleImageError(imgElement, retryCount - 1, retryDelay);
}, retryDelay);
} else {
imgElement.classList.remove('loading-image');
title.classList.remove('title-loading');
container.style.display = 'none';
}
}
// Rest of your existing code with minor additions
const imageStatusInterval = 500;
const scrollThreshold = 500;
const loadingIndicator = document.getElementById('message-bottom-left');
@ -14,18 +49,6 @@
let imageIds = [];
let imageStatusTimer;
function handleImageError(imgElement, retryCount = 3, retryDelay = 1000) {
if (retryCount > 0) {
setTimeout(() => {
imgElement.src = imgElement.getAttribute('data-full');
imgElement.onerror = () => handleImageError(imgElement, retryCount - 1, retryDelay);
}, retryDelay);
} else {
console.warn('Image failed to load:', imgElement.getAttribute('data-full'));
imgElement.parentElement.style.display = 'none';
}
}
function ensureScrollable() {
if (noMoreImages) return;
if (document.body.scrollHeight <= window.innerHeight) {
@ -59,21 +82,21 @@
let img = clonedImageDiv.querySelector('img');
if (img && img.getAttribute('data-id')) {
addLoadingEffects(img);
if (hardCacheEnabled) {
img.src = '/static/images/placeholder.svg';
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
img.onerror = () => handleImageError(img);
imageElements.push(img);
imageIds.push(img.getAttribute('data-id'));
} else {
img.src = img.getAttribute('data-full');
img.onload = () => removeLoadingEffects(img);
img.onerror = () => handleImageError(img);
}
}
});
if (hardCacheEnabled) {
checkImageStatus(); // Immediately check status for new images
}
if (hardCacheEnabled) checkImageStatus();
ensureScrollable();
} else {
noMoreImages = true;
@ -101,6 +124,7 @@
const id = img.getAttribute('data-id');
if (statusMap[id]) {
img.src = statusMap[id];
img.onload = () => removeLoadingEffects(img);
img.onerror = () => handleImageError(img);
} else {
pendingImages.push(img);
@ -117,21 +141,24 @@
});
}
// Initialize
// Initialize with loading effects
document.querySelectorAll('img[data-id]').forEach(img => {
const id = img.getAttribute('data-id');
if (id) {
addLoadingEffects(img);
imageElements.push(img);
imageIds.push(id);
if (hardCacheEnabled) {
img.src = '/static/images/placeholder.svg';
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
} else {
img.src = img.getAttribute('data-full');
img.onload = () => removeLoadingEffects(img);
}
img.onerror = () => handleImageError(img);
}
});
// Rest of your existing code remains unchanged
if (hardCacheEnabled) {
imageStatusTimer = setInterval(checkImageStatus, imageStatusInterval);
checkImageStatus();
@ -145,7 +172,6 @@
}
});
// Cleanup
window.addEventListener('beforeunload', () => {
if (imageStatusTimer) clearInterval(imageStatusTimer);
});

View file

@ -29,7 +29,7 @@ document.addEventListener('DOMContentLoaded', function() {
</div>
<p class="image-alt" id="viewer-title"></p>
<br>
<div class="search-type-icons" style="display:flex; justify-content:center; gap:15px; flex-wrap: wrap;">
<div class="search-type-icons" style="display:flex; justify-content:center; flex-wrap: wrap;">
<div class="icon-button">
<button class="material-icons-round clickable btn-nostyle" id="viewer-copy-link">
<span class="material-icons-round">&#xe37c;</span>