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
63
static/css/style-imageloading.css
Normal file
63
static/css/style-imageloading.css
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/* Image Loading Effect */
|
||||||
|
.loading-image {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: var(--snip-background);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(255, 255, 255, 0) 25%,
|
||||||
|
rgba(255, 255, 255, 0.15) 50%,
|
||||||
|
rgba(255, 255, 255, 0) 75%
|
||||||
|
);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: image-wave 2s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Title Loading Effect */
|
||||||
|
.title-loading {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
color: transparent !important;
|
||||||
|
background-color: var(--snip-background);
|
||||||
|
min-height: 1.2em;
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto;
|
||||||
|
top: 2px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-loading::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
transparent 25%,
|
||||||
|
rgba(255, 255, 255, 0.25) 50%,
|
||||||
|
transparent 75%
|
||||||
|
);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: title-wave 2.5s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animations */
|
||||||
|
@keyframes image-wave {
|
||||||
|
0% {
|
||||||
|
background-position: -100% 0; /* Start off-screen left */
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 100% 0; /* End off-screen right */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes title-wave {
|
||||||
|
0% {
|
||||||
|
background-position: -100% 0; /* Start off-screen left */
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 100% 0; /* End off-screen right */
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,40 @@
|
||||||
|
// dynamicscrollingimages.js
|
||||||
(function() {
|
(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 imageStatusInterval = 500;
|
||||||
const scrollThreshold = 500;
|
const scrollThreshold = 500;
|
||||||
const loadingIndicator = document.getElementById('message-bottom-left');
|
const loadingIndicator = document.getElementById('message-bottom-left');
|
||||||
|
@ -14,18 +49,6 @@
|
||||||
let imageIds = [];
|
let imageIds = [];
|
||||||
let imageStatusTimer;
|
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() {
|
function ensureScrollable() {
|
||||||
if (noMoreImages) return;
|
if (noMoreImages) return;
|
||||||
if (document.body.scrollHeight <= window.innerHeight) {
|
if (document.body.scrollHeight <= window.innerHeight) {
|
||||||
|
@ -59,21 +82,21 @@
|
||||||
|
|
||||||
let img = clonedImageDiv.querySelector('img');
|
let img = clonedImageDiv.querySelector('img');
|
||||||
if (img && img.getAttribute('data-id')) {
|
if (img && img.getAttribute('data-id')) {
|
||||||
|
addLoadingEffects(img);
|
||||||
if (hardCacheEnabled) {
|
if (hardCacheEnabled) {
|
||||||
img.src = '/static/images/placeholder.svg';
|
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
|
||||||
img.onerror = () => handleImageError(img);
|
img.onerror = () => handleImageError(img);
|
||||||
imageElements.push(img);
|
imageElements.push(img);
|
||||||
imageIds.push(img.getAttribute('data-id'));
|
imageIds.push(img.getAttribute('data-id'));
|
||||||
} else {
|
} else {
|
||||||
img.src = img.getAttribute('data-full');
|
img.src = img.getAttribute('data-full');
|
||||||
|
img.onload = () => removeLoadingEffects(img);
|
||||||
img.onerror = () => handleImageError(img);
|
img.onerror = () => handleImageError(img);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hardCacheEnabled) {
|
if (hardCacheEnabled) checkImageStatus();
|
||||||
checkImageStatus(); // Immediately check status for new images
|
|
||||||
}
|
|
||||||
ensureScrollable();
|
ensureScrollable();
|
||||||
} else {
|
} else {
|
||||||
noMoreImages = true;
|
noMoreImages = true;
|
||||||
|
@ -101,6 +124,7 @@
|
||||||
const id = img.getAttribute('data-id');
|
const id = img.getAttribute('data-id');
|
||||||
if (statusMap[id]) {
|
if (statusMap[id]) {
|
||||||
img.src = statusMap[id];
|
img.src = statusMap[id];
|
||||||
|
img.onload = () => removeLoadingEffects(img);
|
||||||
img.onerror = () => handleImageError(img);
|
img.onerror = () => handleImageError(img);
|
||||||
} else {
|
} else {
|
||||||
pendingImages.push(img);
|
pendingImages.push(img);
|
||||||
|
@ -117,21 +141,24 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize
|
// Initialize with loading effects
|
||||||
document.querySelectorAll('img[data-id]').forEach(img => {
|
document.querySelectorAll('img[data-id]').forEach(img => {
|
||||||
const id = img.getAttribute('data-id');
|
const id = img.getAttribute('data-id');
|
||||||
if (id) {
|
if (id) {
|
||||||
|
addLoadingEffects(img);
|
||||||
imageElements.push(img);
|
imageElements.push(img);
|
||||||
imageIds.push(id);
|
imageIds.push(id);
|
||||||
if (hardCacheEnabled) {
|
if (hardCacheEnabled) {
|
||||||
img.src = '/static/images/placeholder.svg';
|
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';
|
||||||
} else {
|
} else {
|
||||||
img.src = img.getAttribute('data-full');
|
img.src = img.getAttribute('data-full');
|
||||||
|
img.onload = () => removeLoadingEffects(img);
|
||||||
}
|
}
|
||||||
img.onerror = () => handleImageError(img);
|
img.onerror = () => handleImageError(img);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Rest of your existing code remains unchanged
|
||||||
if (hardCacheEnabled) {
|
if (hardCacheEnabled) {
|
||||||
imageStatusTimer = setInterval(checkImageStatus, imageStatusInterval);
|
imageStatusTimer = setInterval(checkImageStatus, imageStatusInterval);
|
||||||
checkImageStatus();
|
checkImageStatus();
|
||||||
|
@ -145,7 +172,6 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
window.addEventListener('beforeunload', () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
if (imageStatusTimer) clearInterval(imageStatusTimer);
|
if (imageStatusTimer) clearInterval(imageStatusTimer);
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,7 +29,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
</div>
|
</div>
|
||||||
<p class="image-alt" id="viewer-title"></p>
|
<p class="image-alt" id="viewer-title"></p>
|
||||||
<br>
|
<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">
|
<div class="icon-button">
|
||||||
<button class="material-icons-round clickable btn-nostyle" id="viewer-copy-link">
|
<button class="material-icons-round clickable btn-nostyle" id="viewer-copy-link">
|
||||||
<span class="material-icons-round"></span>
|
<span class="material-icons-round"></span>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</noscript>
|
</noscript>
|
||||||
|
<link rel="stylesheet" href="/static/css/style-imageloading.css">
|
||||||
<link rel="stylesheet" href="/static/css/style-imageviewer.css">
|
<link rel="stylesheet" href="/static/css/style-imageviewer.css">
|
||||||
<link rel="stylesheet" href="/static/css/style-fixedwidth.css">
|
<link rel="stylesheet" href="/static/css/style-fixedwidth.css">
|
||||||
<link rel="stylesheet" href="/static/css/style-menu.css">
|
<link rel="stylesheet" href="/static/css/style-menu.css">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue