Skip to content

Commit 4d53db4

Browse files
committed
Update demo
1 parent 2946f2b commit 4d53db4

File tree

5 files changed

+211
-144
lines changed

5 files changed

+211
-144
lines changed

src/ambient.d.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
declare module '*?run' {
2-
const image: Record<string, any>[]
3-
export default image
1+
declare module '*?as=run' {
2+
var img
3+
export default img
44
}
5-
declare module '*&run' {
6-
const image: Record<string, any>[]
7-
export default image
5+
declare module '*&as=run' {
6+
var img
7+
export default img
88
}

src/routes/+layout.svelte

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
<script>
2+
import '@fontsource-variable/inter'
23
import '../app.postcss'
34
import { dev } from '$app/environment'
45
</script>
56

67
<svelte:head>
7-
<title>svelte-img</title>
8-
<meta name="description" content="Elegant responsive images for SvelteKit." />
8+
<title>DEMO | svelte-img</title>
9+
<meta
10+
name="description"
11+
content="High-performance responsive/progressive images for SvelteKit."
12+
/>
913
{#if !dev}
1014
<script async src="https://www.googletagmanager.com/gtag/js?id=G-6QMRQS31JH"></script>
1115
<script>

src/routes/+page.svelte

Lines changed: 199 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,215 @@
11
<script>
2-
import cat01 from './cat01.jpg?width=480;1024;1920;2560&height=1024&run'
3-
import cat02 from './cat02.jpg?run'
4-
import cat03 from './cat03.jpg?run'
5-
import cat04 from './cat04.jpg?run'
6-
import cat05 from './cat05.jpg?width=640&height=640&fit=cover&run'
7-
import cat06 from './cat06.jpg?width=640&height=640&fit=cover&run'
8-
import cat07 from './cat07.jpg?width=640&height=640&fit=cover&run'
9-
import cat08 from './cat08.jpg?width=640&height=640&fit=cover&run'
10-
import cat09 from './cat09.jpg?width=640&height=640&fit=cover&run'
11-
import cat10 from './cat10.jpg?width=640&height=640&fit=cover&run'
12-
import cat11 from './cat11.jpg?width=640&height=640&fit=cover&run'
13-
import cat12 from './cat12.jpg?width=640&height=640&fit=cover&run'
14-
import cat13 from './cat13.jpg?width=640&height=640&fit=cover&run'
15-
import cat14 from './cat14.jpg?width=640&height=640&fit=cover&run'
16-
import cat15 from './cat15.jpg?width=640&height=640&fit=cover&run'
2+
/* eslint-disable no-useless-escape */
3+
import hero from './assets/hero.jpg?w=480;1024;1920;2560;h=720&as=run'
4+
import i1 from './assets/1920/1.jpg?h=720&as=run'
5+
import i2 from './assets/1920/2.jpg?h=720&as=run:1'
6+
import i3 from './assets/1920/3.jpg?h=720&as=run'
7+
import i4 from './assets/1920/4.jpg?h=720&as=run'
8+
import i5 from './assets/1920/5.jpg?h=720&as=run'
9+
import pllx from './assets/pllx.jpg?h=1024&as=run'
1710
import Img, { FxReveal, FxParallax } from '$lib/index.js'
11+
import { version } from '$app/environment'
12+
import testSingle from './assets/640/01.jpg?w=80&h=80&as=run:0'
13+
import testFallback from './assets/640/01.jpg?h=80'
1814
19-
const dynamic = [cat05, cat06, cat07, cat08, cat09, cat10, cat11, cat12, cat13, cat14, cat15]
15+
const modules = import.meta.glob('./assets/640/*.jpg', {
16+
import: 'default',
17+
eager: true,
18+
query: { w: 640, h: 640, fit: 'cover', as: 'run' }
19+
})
20+
21+
const esc = (i) => i
22+
23+
const images = Object.entries(modules).map((i) => i[1])
2024
let selected = 0
2125
</script>
2226

23-
<div class="relative bg-gray-900 text-white text-center mb-20">
24-
<Img class="w-full h-screen object-cover" src={cat01} alt="cat" loading="eager" />
25-
<div class="absolute inset-0 flex flex-col items-center justify-center prose-2xl max-w-none px-2">
26-
<h1>svelte-img</h1>
27-
<p>High-performance responsive images for SvelteKit.</p>
28-
<a
29-
class="h-14 flex items-center justify-center rounded-full text-xs font-bold tracking-wider bg-blue-600 hover:bg-blue-800 px-6 mt-8 mb-6"
30-
href="https://github.com/zerodevx/svelte-img">VISIT GITHUB REPO</a
31-
>
27+
<div class="relative mb-16 test-basic">
28+
<Img class="w-full h-[32rem] object-cover" src={hero} alt="cat" loading="eager" />
29+
<div class="absolute inset-0 flex flex-col justify-center">
30+
<div class="prose prose-h1:text-white prose-p:text-white mx-auto text-center px-4">
31+
<h1>svelte-img</h1>
32+
<div class="badge badge-neutral font-mono text-xs ml-2">v{version}</div>
33+
<p>High-performance responsive/progressive images for SvelteKit.</p>
34+
<a class="btn btn-primary" href="https://github.com/zerodevx/svelte-img">
35+
<span class="w-6 h-6 icon-[mdi--github]" />
36+
View Github Repo
37+
</a>
38+
</div>
3239
</div>
3340
</div>
3441

35-
<div class="max-w-3xl mx-auto prose px-4">
36-
<h1>svelte-img</h1>
42+
<div class="prose mx-auto px-4 mb-8">
3743
<blockquote>
3844
Render the bare minimum, minimally invasive, LQIP-included HTML code to represent responsive
3945
images, served in multiple widths and next-gen formats.
4046
</blockquote>
41-
<ol>
42-
<li>
43-
<p>
44-
Easily render a responsive image in 10 variants - <code>avif/webp/jpg</code> formats at
45-
<code>480/1024/1920</code> widths, with a low-quality image placeholder (LQIP) background.
46-
</p>
47-
</li>
48-
</ol>
49-
</div>
50-
<div class="max-w-7xl mx-auto px-4 mb-12">
51-
<Img class="w-full h-[32rem] object-cover" src={cat02} alt="cat" />
52-
</div>
53-
54-
<div class="max-w-3xl mx-auto prose px-4">
55-
<ol start="2">
56-
<li>
57-
<p>
58-
Or reveal images with fade-in special effects. Delegate the heavy lifting to native browser
59-
handlers and existing build pipelines. The <code>svelte-img</code>
60-
component is intended to be a drop-in replacement of the native <code>&lt;img&gt;</code> tag
61-
and tries to work as equivalently as possible.
62-
</p>
63-
</li>
64-
</ol>
65-
</div>
66-
<div class="max-w-7xl mx-auto px-4 mb-12">
67-
<FxReveal class="w-full h-[32rem] object-cover" src={cat03} alt="cat" />
68-
</div>
69-
70-
<div class="max-w-3xl mx-auto prose px-4">
71-
<ol start="3">
72-
<li>
73-
<p>
74-
Or add parallax special effects to images. All images should still appear even without
75-
Javascript. Try disabling JS and refreshing the page. Also check out the lighthouse score.
76-
</p>
77-
</li>
78-
</ol>
79-
</div>
80-
<div class="max-w-7xl mx-auto px-4 mb-12">
81-
<FxParallax class="w-full h-[32rem]" src={cat04} alt="cat" />
82-
</div>
83-
84-
<div class="max-w-3xl mx-auto prose px-4">
85-
<ol start="4">
86-
<li>
87-
<p>
88-
Image <code>src</code> can be dynamically updated - well, this requires Javascript because
89-
<em>interactivity</em>.
90-
</p>
91-
</li>
92-
</ol>
93-
</div>
94-
95-
<div class="max-w-7xl mx-auto px-4 mb-96">
96-
<div class="flex flex-col md:flex-row">
97-
<div class="flex justify-center">
98-
<div class="w-80 h-80 md:w-[32rem] md:h-[32rem]">
99-
<Img class="w-full h-full not-prose" src={dynamic[selected]} alt="cat" />
47+
<h2>Install</h2>
48+
<pre><code>{esc(`$ npm i -D @zerodevx/svelte-img`)}</code></pre>
49+
<p>Add <code>imagetools</code> plugin into your <code>vite.config.js</code>:</p>
50+
<pre><code
51+
>{esc(`import { defineConfig } from 'vite'
52+
import { sveltekit } from '@sveltejs/kit/vite'
53+
import { imagetools } from '@zerodevx/svelte-img/vite'
54+
55+
export default defineConfig({
56+
plugins: [sveltekit(), imagetools()]
57+
})`)}</code
58+
></pre>
59+
<h2>Use</h2>
60+
<p>Anywhere in your <code>svelte</code> app:</p>
61+
<pre><code
62+
>{esc(`<script>
63+
import cat from '$lib/assets/cat.jpg?as=run'
64+
import Img from '@zerodevx/svelte-img'
65+
<\/script>
66+
67+
<Img class="cool kitty" src={cat} alt="Very meow" />`)}</code
68+
></pre>
69+
<h2>Showcase</h2>
70+
<blockquote>
71+
By default, the original image is transformed into 9 variants - <code>480/1024/1920</code>
72+
widths at <code>avif/webp/jpg</code> formats, with an inline <code>base64</code> low-quality image
73+
placeholder (LQIP) background.
74+
</blockquote>
75+
</div>
76+
77+
<Img class="w-full h-[32rem] max-w-[1920px] mx-auto object-cover mb-16" src={i1} alt="cat" />
78+
79+
<div class="prose mx-auto px-4 mb-8">
80+
<blockquote>
81+
The LQIP is usually a 16px <code>webp;base64</code> data URI at about ≈150 bytes.
82+
</blockquote>
83+
</div>
84+
85+
<img
86+
class="w-full h-[32rem] max-w-[1920px] mx-auto object-cover mb-16"
87+
src="data:image/webp;base64,{i1.img.lqip}"
88+
alt="cat lqip"
89+
/>
90+
91+
<div class="prose mx-auto px-4 mb-8">
92+
<blockquote>
93+
Though not recommended, you can apply a Gaussian blur <code>backdrop-filter</code>.
94+
</blockquote>
95+
</div>
96+
97+
<div class="w-full h-[32rem] max-w-[1920px] mx-auto overflow-hidden mb-16">
98+
<img
99+
class="w-full h-full object-cover blur scale-105"
100+
src="data:image/webp;base64,{i1.img.lqip}"
101+
alt="cat lqip"
102+
/>
103+
</div>
104+
105+
<div class="prose mx-auto px-4 mb-8">
106+
<blockquote>
107+
Not much difference, is there? The next image has a dominant colour placeholder instead.
108+
</blockquote>
109+
</div>
110+
111+
<Img
112+
class="w-full h-[32rem] max-w-[1920px] mx-auto object-cover mb-16 test-1px"
113+
src={i2}
114+
alt="cat"
115+
/>
116+
117+
<div class="prose mx-auto px-4 mb-8">
118+
<blockquote>Which looks like this.</blockquote>
119+
</div>
120+
121+
<div class="w-full h-[32rem] max-w-[1920px] mx-auto mb-16" style="background:{i2.img.lqip}" />
122+
123+
<div class="prose mx-auto px-4 mb-8">
124+
<blockquote>
125+
You can also reveal images with <code>fade-in/zoom</code> special effects.
126+
</blockquote>
127+
</div>
128+
129+
<div class="mb-16">
130+
<FxReveal class="w-full h-[32rem] max-w-[1920px] mx-auto object-cover" src={i3} alt="cat" />
131+
</div>
132+
133+
<div class="mb-16">
134+
<FxReveal class="w-full h-[32rem] max-w-[1920px] mx-auto object-cover" src={i4} alt="cat" />
135+
</div>
136+
137+
<div class="mb-16">
138+
<FxReveal class="w-full h-[32rem] max-w-[1920px] mx-auto object-cover" src={i5} alt="cat" />
139+
</div>
140+
141+
<div class="prose mx-auto px-4 mb-8">
142+
<blockquote>Or even apply parallax scrolling special effects.</blockquote>
143+
</div>
144+
145+
<div class="w-full max-w-[1920px] mx-auto mb-16">
146+
<FxParallax class="w-full h-[40rem]" src={pllx} alt="cat" />
147+
</div>
148+
149+
<div class="prose mx-auto px-4 mb-16">
150+
<blockquote>
151+
The <code>svelte-img</code> component tries, as much as possible, to be a drop-in replacement
152+
for the native HTML
153+
<code>{esc(`<img>`)}</code> tag. Side-effects are kept to a minimum, so things should still work
154+
even without JavaScript. Try it - disable JS on this page and refresh, and check out the Lighthouse
155+
score too.
156+
</blockquote>
157+
<blockquote>
158+
The next example however does require JavaScript, because interactivity. It uses the
159+
<code>Vite</code> pattern for glob imports to load a local dir of images, like so:
160+
</blockquote>
161+
<pre><code
162+
>{esc(`const modules = import.meta.glob('$lib/assets/sm/*.jpg', {
163+
import: 'default',
164+
eager: true,
165+
query: { w: 640, h: 640, fit: 'cover', as: 'run' }
166+
})
167+
168+
const images = Object.entries(modules).map((i) => i[1])
169+
`)}</code
170+
></pre>
171+
</div>
172+
173+
<div class="relative w-full flex flex-col lg:flex-row lg:justify-center items-center mb-16">
174+
<div class="w-full max-w-sm aspect-square shadow-md overflow-hidden sticky lg:relative top-0">
175+
<FxReveal class="w-full h-full" src={images[selected]} alt="cat" />
176+
</div>
177+
<div class="w-full max-w-xl flex flex-wrap justify-center mt-6 lg:mt-0">
178+
{#each images as src, i}
179+
<div class="w-28 aspect-square m-3">
180+
<Img
181+
class="w-full h-full border-4 cursor-pointer {selected === i
182+
? 'border-primary'
183+
: 'border-base-200'}"
184+
{src}
185+
alt="cat"
186+
on:click={() => (selected = i)}
187+
/>
100188
</div>
101-
</div>
102-
<div class="flex flex-wrap justify-center mt-4 md:flex-1 md:mt-6">
103-
{#each dynamic as src, i}
104-
<div class="w-32 h-32 md:w-36 md:h-36 m-2">
105-
<Img
106-
class="w-full h-full border-4 cursor-pointer {selected === i
107-
? 'border-red-500'
108-
: 'border-gray-100'}"
109-
{src}
110-
alt="cat"
111-
on:click={() => (selected = i)}
112-
/>
113-
</div>
114-
{/each}
115-
</div>
189+
{/each}
116190
</div>
117191
</div>
192+
193+
<!-- Start tests -->
194+
<div class="hidden test-single">
195+
<Img src={testSingle} alt="test" />
196+
</div>
197+
<div class="hidden test-fallback">{JSON.stringify(testFallback)}</div>
198+
<!-- End tests -->
199+
200+
<footer
201+
class="w-full h-96 bg-neutral text-neutral-content flex flex-row items-center justify-center"
202+
>
203+
<span class="icon-[mdi--email] w-6 h-6 mr-2" />
204+
<a class="link" href="mailto:[email protected]">[email protected]</a>
205+
</footer>
206+
207+
<style>
208+
:global(img.blur)::after {
209+
content: '';
210+
position: absolute;
211+
inset: 0;
212+
backdrop-filter: blur(20px);
213+
pointer-events: none;
214+
}
215+
</style>

src/routes/test/+page.js

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/routes/test/+page.svelte

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)