Fix slideshow crossfade flash — wait for image load before fading in
Previously the active class was applied via requestAnimationFrame before the image had decoded, causing a brief blank-then-flash. Now loadSlide waits for onload before transitioning, and advanceSlide checks complete/naturalWidth (or waits for onload) on the preloaded slot before doing the swap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -302,10 +302,17 @@ function hideSlideshow() {
|
|||||||
|
|
||||||
function loadSlide(slot, url) {
|
function loadSlide(slot, url) {
|
||||||
const img = document.getElementById(`slide-${slot}`);
|
const img = document.getElementById(`slide-${slot}`);
|
||||||
img.src = url;
|
|
||||||
if (slot === activeSlot) {
|
if (slot === activeSlot) {
|
||||||
// Slight delay lets the browser decode before fading in
|
// Only fade in once the image is fully decoded — no blank-then-flash
|
||||||
requestAnimationFrame(() => requestAnimationFrame(() => img.classList.add('active')));
|
img.onload = () => { img.onload = null; img.classList.add('active'); };
|
||||||
|
img.src = url;
|
||||||
|
// Handle cached images that won't fire onload
|
||||||
|
if (img.complete && img.naturalWidth > 0) {
|
||||||
|
img.onload = null;
|
||||||
|
img.classList.add('active');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
img.src = url; // preload only
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,13 +321,20 @@ function advanceSlide() {
|
|||||||
const current = document.getElementById(`slide-${activeSlot}`);
|
const current = document.getElementById(`slide-${activeSlot}`);
|
||||||
const next = document.getElementById(`slide-${nextSlot}`);
|
const next = document.getElementById(`slide-${nextSlot}`);
|
||||||
|
|
||||||
// Fade in the preloaded next image, fade out current
|
const doSwap = () => {
|
||||||
next.classList.add('active');
|
next.onload = null;
|
||||||
current.classList.remove('active');
|
next.classList.add('active');
|
||||||
activeSlot = nextSlot;
|
current.classList.remove('active');
|
||||||
|
activeSlot = nextSlot;
|
||||||
|
// Preload the upcoming photo into the now-hidden slot
|
||||||
|
slideIndex = (slideIndex + 1) % photos.length;
|
||||||
|
current.src = photos[(slideIndex + 1) % photos.length];
|
||||||
|
};
|
||||||
|
|
||||||
// Preload the one after next into the now-hidden slot
|
// If the preloaded image is ready, swap immediately; otherwise wait for it
|
||||||
slideIndex = (slideIndex + 1) % photos.length;
|
if (next.complete && next.naturalWidth > 0) {
|
||||||
const upcoming = photos[(slideIndex + 1) % photos.length];
|
doSwap();
|
||||||
current.src = upcoming;
|
} else {
|
||||||
|
next.onload = doSwap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user