improved image loading animation
All checks were successful
Run Integration Tests / test (push) Successful in 28s
All checks were successful
Run Integration Tests / test (push) Successful in 28s
This commit is contained in:
parent
5fdbe231d1
commit
30528d629b
4 changed files with 111 additions and 21 deletions
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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"></span>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue