···
1
1
<script lang="ts">
2
2
import { reveal } from '$lib/actions/reveal';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
3
4
import type { CurrentlyReading, FinishedBook } from '$lib/types';
4
5
5
6
let {
···
27
28
<div class="card mx-auto mt-10 max-w-xl bg-base-100 shadow-sm">
28
29
<div class="card-body flex-row items-start gap-5">
29
30
{#if currentlyReading.cover}
30
30
-
<img
31
31
-
class="h-40 w-28 flex-none rounded-md object-cover shadow-sm"
31
31
+
<LazyLoadingImg
32
32
+
class="h-40 w-28 flex-none rounded-md shadow-sm"
32
33
src={currentlyReading.cover}
33
34
alt={currentlyReading.title}
34
34
-
loading="lazy"
35
35
/>
36
36
{/if}
37
37
<div class="flex flex-col">
···
64
64
<div class="card bg-base-100 shadow-sm transition duration-300 hover:-translate-y-1">
65
65
<div class="card-body flex-row items-start gap-4">
66
66
{#if book.cover}
67
67
-
<img
68
68
-
class="h-32 w-22 flex-none rounded-md object-cover shadow-sm"
67
67
+
<LazyLoadingImg
68
68
+
class="h-32 w-22 flex-none rounded-md shadow-sm"
69
69
src={book.cover}
70
70
alt={book.title}
71
71
-
loading="lazy"
72
71
/>
73
72
{/if}
74
73
<div class="flex min-w-0 flex-col">
···
1
1
<script lang="ts">
2
2
import { reveal } from '$lib/actions/reveal';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
3
4
import type { CurrentlyReading, NowPlaying } from '$lib/types';
4
5
5
6
let {
···
25
26
<div class="card bg-base-100 shadow-sm transition duration-300 hover:-translate-y-1">
26
27
<div class="card-body flex-row items-start gap-5">
27
28
{#if currentlyReading.cover}
28
28
-
<img
29
29
-
class="h-40 w-28 flex-none rounded-md object-cover shadow-sm"
29
29
+
<LazyLoadingImg
30
30
+
class="h-40 w-28 flex-none rounded-md shadow-sm"
30
31
src={currentlyReading.cover}
31
32
alt={currentlyReading.title}
32
32
-
loading="lazy"
33
33
/>
34
34
{/if}
35
35
<div class="flex flex-col">
···
58
58
<div class="card bg-base-100 shadow-sm transition duration-300 hover:-translate-y-1">
59
59
<div class="card-body flex-row items-start gap-5">
60
60
{#if nowPlaying.coverArt && !coverArtFailed}
61
61
-
<img
62
62
-
class="h-32 w-32 flex-none rounded-md object-cover shadow-sm"
61
61
+
<LazyLoadingImg
62
62
+
class="h-32 w-32 flex-none rounded-md shadow-sm"
63
63
src={nowPlaying.coverArt}
64
64
alt={nowPlaying.releaseName ?? nowPlaying.trackName}
65
65
onerror={() => (coverArtFailed = true)}
66
66
-
loading="lazy"
67
66
/>
68
67
{:else}
69
68
<div
···
1
1
<script lang="ts">
2
2
import { reveal } from '$lib/actions/reveal';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
3
4
import me from '$lib/assets/me.webp';
4
5
import mePumpkin from '$lib/assets/me_pumpkin.webp';
5
6
import GitHubButton from './buttons/GitHubButton.svelte';
···
8
9
9
10
<div id="home" class="hero flex justify-center py-10" use:reveal>
10
11
<div class="hero-content flex-col lg:flex-row-reverse">
11
11
-
<img
12
12
+
<LazyLoadingImg
12
13
src={me}
13
14
alt=""
14
15
class="max-w-xs rounded-t-[14rem] rounded-b-box shadow-2xl outline outline-base-content/5 md:max-w-md"
16
16
+
imgClass="block w-full"
15
17
/>
16
18
<div class="text-center lg:text-start">
17
19
<!-- <span class="badge badge-outline badge-lg">Award winning digital agency</span> -->
···
1
1
+
<script lang="ts">
2
2
+
import type { HTMLImgAttributes } from 'svelte/elements';
3
3
+
import type { Attachment } from 'svelte/attachments';
4
4
+
5
5
+
let {
6
6
+
src,
7
7
+
alt,
8
8
+
class: className = '',
9
9
+
imgClass = 'h-full w-full object-cover',
10
10
+
onload,
11
11
+
onerror,
12
12
+
...rest
13
13
+
}: {
14
14
+
src: string;
15
15
+
alt: string;
16
16
+
/** Classes for the wrapper box (sizing, rounding, ring, shadow, flex-none, etc.) */
17
17
+
class?: string;
18
18
+
/** Classes for the inner <img> (object-fit, padding). Defaults to fill+cover. */
19
19
+
imgClass?: string;
20
20
+
onload?: (e: Event) => void;
21
21
+
onerror?: (e: Event) => void;
22
22
+
} & HTMLImgAttributes = $props();
23
23
+
24
24
+
let loaded = $state(false);
25
25
+
26
26
+
// After SSR/hydration a cached image can already be complete before our
27
27
+
// onload handler is attached, so reconcile once on mount.
28
28
+
const reconcileCached: Attachment<HTMLImageElement> = (node) => {
29
29
+
if (node.complete && node.naturalWidth > 0) loaded = true;
30
30
+
};
31
31
+
</script>
32
32
+
33
33
+
<div class={['relative overflow-hidden', className]}>
34
34
+
{#if !loaded}
35
35
+
<div class="absolute inset-0 skeleton"></div>
36
36
+
{/if}
37
37
+
<img
38
38
+
{@attach reconcileCached}
39
39
+
{src}
40
40
+
{alt}
41
41
+
class={imgClass}
42
42
+
loading="lazy"
43
43
+
{...rest}
44
44
+
onload={(e) => {
45
45
+
loaded = true;
46
46
+
onload?.(e);
47
47
+
}}
48
48
+
onerror={(e) => {
49
49
+
loaded = true;
50
50
+
onerror?.(e);
51
51
+
}}
52
52
+
/>
53
53
+
</div>
···
1
1
<script lang="ts">
2
2
import { reveal } from '$lib/actions/reveal';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
3
4
import type { RecentPlay } from '$lib/types';
4
5
5
6
let { recentPlays }: { recentPlays: RecentPlay[] } = $props();
···
50
51
class="card flex-row items-center gap-4 bg-base-100 p-3 shadow-sm transition duration-300 hover:-translate-y-0.5"
51
52
>
52
53
{#if play.coverArt && !coverFailed[i]}
53
53
-
<img
54
54
-
class="h-16 w-16 flex-none rounded-md object-cover shadow-sm"
54
54
+
<LazyLoadingImg
55
55
+
class="h-16 w-16 flex-none rounded-md shadow-sm"
55
56
src={play.coverArt}
56
57
alt={play.releaseName ?? play.trackName}
57
58
onerror={() => (coverFailed[i] = true)}
58
58
-
loading="lazy"
59
59
/>
60
60
{:else}
61
61
<div
···
1
1
<script lang="ts">
2
2
import PumpkinHead from '$lib/assets/pumpkin_head.png';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
4
4
+
import { page } from '$app/stores'; // 1. Import the page store
3
5
4
6
type NavItem = {
5
7
name: string;
···
44
46
currentHeadSize = headSizes[(index + 1) % headSizes.length];
45
47
};
46
48
47
47
-
let active = $state(navigation[0].href);
49
49
+
let active = $derived.by(() => {
50
50
+
// if ($page.url.pathname;
51
51
+
const path = `${$page.url.pathname}${$page.url.hash}`;
52
52
+
let test = path === '/' || path === '' ? '/#home' : path;
53
53
+
console.log(test);
54
54
+
return test;
55
55
+
});
48
56
49
57
function onActivate(href: string | undefined) {
50
58
if (href) active = href;
···
194
202
onclick={increaseHeadSize}
195
203
class={['rounded-full', 'cursor-pointer', currentHeadSize]}
196
204
>
197
197
-
<img alt="A cartoon Jack-o'-lantern " src={PumpkinHead} />
205
205
+
<LazyLoadingImg
206
206
+
class="w-full"
207
207
+
imgClass="block w-full"
208
208
+
alt="A cartoon Jack-o'-lantern "
209
209
+
src={PumpkinHead}
210
210
+
/>
198
211
</button>
199
212
</div>
200
213
<!-- <ThemeToggle /> -->
···
1
1
<script lang="ts">
2
2
import { reveal } from '$lib/actions/reveal';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
3
4
import moover from '$lib/assets/projects/moover.webp';
4
5
import npmx from '$lib/assets/projects/npmx.png';
5
6
import gatekeeper from '$lib/assets/projects/gatekeeper.jpg';
···
92
93
{#each visibleProjects as item (item.name)}
93
94
<div class="card bg-base-100 shadow-sm transition duration-300 hover:-translate-y-1">
94
95
<figure>
95
95
-
<img class="h-48 w-full object-cover" src={item.image} alt={item.name} loading="lazy" />
96
96
+
<LazyLoadingImg class="h-48 w-full" src={item.image} alt={item.name} />
96
97
</figure>
97
98
<div class="card-body">
98
99
<h2 class="card-title font-urbanist text-2xl font-black">{item.name}</h2>
···
1
1
<script lang="ts">
2
2
import { reveal } from '$lib/actions/reveal';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
3
4
4
5
const services = [
5
6
{
···
53
54
<div class="card max-w-2xl shadow-sm transition duration-300 hover:-translate-y-1">
54
55
<div class="card-body">
55
56
<div class="h-16 w-16 rounded-full bg-gradient-to-t from-base-300/20 to-base-content/10">
56
56
-
<img class="p-4" src={item.icon} alt={item.name} loading="lazy" />
57
57
+
<LazyLoadingImg
58
58
+
class="h-full w-full rounded-full"
59
59
+
imgClass="h-full w-full object-contain p-4"
60
60
+
src={item.icon}
61
61
+
alt={item.name}
62
62
+
/>
57
63
</div>
58
64
<h2 class="card-title font-urbanist text-3xl font-black">{item.name}</h2>
59
65
<p class="text-md font-urbanist font-medium opacity-60">{item.description}</p>
···
1
1
<script lang="ts">
2
2
import { reveal } from '$lib/actions/reveal';
3
3
+
import LazyLoadingImg from './LazyLoadingImg.svelte';
3
4
import type { Publication } from '$lib/types';
4
5
5
6
let { publications }: { publications: Publication[] } = $props();
···
24
25
<div class="card bg-base-100 shadow-sm transition duration-300 hover:-translate-y-1">
25
26
{#if item.image}
26
27
<figure>
27
27
-
<img class="h-48 w-full object-cover" src={item.image} alt={item.name} loading="lazy" />
28
28
+
<LazyLoadingImg class="h-48 w-full" src={item.image} alt={item.name} />
28
29
</figure>
29
30
{/if}
30
31
<div class="card-body">