global : reveal images only once fully loaded, prevent printer effect. related to #55
All checks were successful
Deploy / Deploy to Production (push) Successful in 5m25s

Images start at opacity:0 and fade in on load event. MutationObserver
catches cached images before first paint to show them instantly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-04-03 12:09:26 +02:00
parent e2939da0ee
commit 701c5d1f56

View file

@ -117,6 +117,31 @@
})
onMount(() => {
// --- Global image reveal: hide until loaded, then fade in ---
const onImgLoad = (e) => {
if (e.target.tagName === 'IMG') e.target.classList.add('loaded')
}
document.addEventListener('load', onImgLoad, true)
// MutationObserver: catch cached images before first paint
const imgObserver = new MutationObserver((mutations) => {
for (const m of mutations) {
for (const node of m.addedNodes) {
if (node.nodeType !== 1) continue
const imgs = node.tagName === 'IMG' ? [node] : node.querySelectorAll?.('img') ?? []
for (const img of imgs) {
if (img.complete && img.naturalWidth > 0) img.classList.add('loaded')
}
}
}
})
imgObserver.observe(document.body, { childList: true, subtree: true })
// Already-present images
document.querySelectorAll('img').forEach(img => {
if (img.complete && img.naturalWidth > 0) img.classList.add('loaded')
})
const handleResize = () => {
isResizing = true
clearTimeout(resizeTimer)
@ -181,6 +206,8 @@
window.addEventListener('touchend', handleTouchEnd, { passive: true })
return () => {
document.removeEventListener('load', onImgLoad, true)
imgObserver.disconnect()
window.removeEventListener('resize', handleResize)
window.removeEventListener('keydown', handleKeydown)
window.removeEventListener('touchstart', handleTouchStart)
@ -255,6 +282,12 @@
:global(img) {
max-width: 100%;
height: auto;
opacity: 0;
transition: opacity 0.3s ease;
}
:global(img.loaded) {
opacity: 1;
}
.main {