My personal photography website steve.phot
portfolio photography svelte sveltekit
at main 70 lines 1.3 kB view raw
1<script lang="ts"> 2 let { 3 src, 4 thumb, 5 alt, 6 class: className = "", 7 }: { 8 src: string; 9 thumb: string; 10 alt: string; 11 class?: string; 12 } = $props(); 13 14 let loaded = $state(false); 15 let thumbAspect = $state(0); 16 let thumbImg: HTMLImageElement; 17 18 function onThumbLoad() { 19 if (thumbImg.naturalWidth && thumbImg.naturalHeight) { 20 thumbAspect = thumbImg.naturalWidth / thumbImg.naturalHeight; 21 } 22 } 23 24 $effect(() => { 25 loaded = false; 26 const img = new Image(); 27 img.onload = () => { 28 loaded = true; 29 }; 30 img.src = src; 31 32 return () => { 33 img.onload = null; 34 }; 35 }); 36</script> 37 38<div 39 class="progressive-container" 40 style="max-width: 4000px; {thumbAspect ? `aspect-ratio: ${thumbAspect};` : ''}" 41> 42 <img 43 bind:this={thumbImg} 44 src={loaded ? src : thumb} 45 {alt} 46 class="{className} progressive-image" 47 class:progressive-loading={!loaded} 48 onload={onThumbLoad} 49 /> 50</div> 51 52<style> 53 .progressive-container { 54 width: 100%; 55 } 56 57 .progressive-container .progressive-image { 58 width: 100%; 59 height: 100%; 60 object-fit: contain; 61 } 62 63 .progressive-image { 64 transition: filter 0.6s ease-out; 65 } 66 67 .progressive-loading { 68 filter: blur(20px); 69 } 70</style>