Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/zerodevx/svelte-img
High-performance responsive/progressive images for SvelteKit
https://github.com/zerodevx/svelte-img
progressive-image-loading responsive-images svelte sveltekit vite-plugin
Last synced: 6 days ago
JSON representation
High-performance responsive/progressive images for SvelteKit
- Host: GitHub
- URL: https://github.com/zerodevx/svelte-img
- Owner: zerodevx
- License: isc
- Created: 2020-09-23T08:20:48.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-11-25T16:12:25.000Z (about 2 months ago)
- Last Synced: 2025-01-10T20:05:06.498Z (13 days ago)
- Topics: progressive-image-loading, responsive-images, svelte, sveltekit, vite-plugin
- Language: Svelte
- Homepage: https://zerodevx.github.io/svelte-img/
- Size: 13.2 MB
- Stars: 341
- Watchers: 6
- Forks: 13
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# svelte-img
> High-performance responsive/progressive images for SvelteKit.
Automatically transform local images into multiple widths and next-gen formats, then render a
minimally invasive LQIP-included HTML representation into your SvelteKit project.Includes special effects:
- [x] Fade-in on image reveal
- [x] Parallax vertical scroll effectHope you like cats. Demo: https://zerodevx.github.io/svelte-img/
## Install
Install the package:
```
$ npm i -D @zerodevx/svelte-img
```Add `imagetools` plugin into your `vite.config.js`:
```js
import { defineConfig } from 'vite'
import { sveltekit } from '@sveltejs/kit/vite'
import { imagetools } from '@zerodevx/svelte-img/vite'export default defineConfig({
plugins: [sveltekit(), imagetools()]
})
```Optionally, to silence typescript
[warnings](https://github.com/JonasKruckenberg/imagetools/issues/160) on image imports, create a new
file at `src/ambient.d.ts`:```js
// Squelch warnings of image imports from your assets dir
declare module '$lib/assets/*' {
var meta
export default meta
}
```### Under the hood
Local image transformations are delegated to the excellent
[`vite-imagetools`](https://github.com/JonasKruckenberg/imagetools) with a custom `run` directive.
This preset generates optimised images with sensible defaults, including a `base64` low-quality
image placeholder.Invoke the preset with the `?as=run` query param:
```js
import imageMeta from 'path/to/asset?as=run'
```## Usage
Use anywhere in your Svelte app:
```html
// Import original full-sized image with `?as=run` query param
import cat from '$lib/assets/cat.jpg?as=run'
import Img from '@zerodevx/svelte-img'
```The image component renders into:
```html
```
## Features
### Change default widths/formats
By default, `svelte-img` generates 9 variants of an original full-sized image - at `480/1024/1920`
widths in `avif/webp/jpg` formats; and a `16px webp/base64` low-quality image placeholder (LQIP).To change this globally, edit your `vite.config.js`:
```js
import ...// By default, `run` is set to 'w=480;1024;1920&format=avif;webp;jpg' (9 variants)
export default defineConfig({
plugins: [
sveltekit(),
imagetools({
profiles: {
// Now we change `run` to generate 4 variants instead: 640/1280w in webp/jpg
run: new URLSearchParams('w=640;1280&format=webp;jpg')
}
})
]
})
```> [!NOTE]
> `runDefaultDirectives` is deprecated and will be removed in the next major; use `profiles`
> instead. When a profile is not used, behaviour falls back to standard `vite-imagetools`, which in
> turn take defaults from `defaultDirectives` as usual, so both can co-exist.### Profiles
Use profiles to manage multiple defaults. Define in your `vite.config.js`:
```js
export default defineConfig({
plugins: [
sveltekit(),
imagetools({
profiles: {
sm: new URLSearchParams('w=640&format=webp;jpg'),
lg: new URLSearchParams('w=640;1280;1920&format=webp;jpg')
}
})
]
})
```Then invoke in your app:
```js
import sm from '$lib/a/1.jpg?as=sm' // use `sm` profile
import lg from '$lib/a/2.jpg?as=lg' // use `lg` profile
import normal from '$lib/a/3.jpg?as=run'
```### On a per-image basis
Widths/formats can be applied to a particular image. From your `.svelte` file:
```html
// We override defaults to generate 4 variants: 720/1560w in webp/jpg
import src from '$lib/a/cat.jpg?w=720;1560&format=webp;jpg&as=run'
import Img from '@zerodevx/svelte-img'
```> [!NOTE]
> Order of `format` matters - the _last_ format is used as the fallback image.If just **one** variant is generated, then only the `` tag renders, so:
```html
// Generate only 1 variant: 640x640 in jpg
import src from '$lib/a/cat.jpg?w=640&h=640&format=jpg&as=run'
import Img from '@zerodevx/svelte-img'
```Renders into:
```html
```### Change LQIP width
The `run` directive takes an optional parameter that sets the LQIP's width. Using `?as=run` defaults
to `16px` LQIP - functionally equivalent to `?as=run:16`. Increase for a higher quality LQIP (eg.
`?as=run:32` for `32px` LQIP) at the expense of a larger inline `base64` (larger HTML size).To disable LQIP, set `?as=run:0`.
For a dominant single-colour background, set `?as=run:1`, so:
```html
import src from '$lib/a/cat.jpg?as=run:1'
import Img from '@zerodevx/svelte-img'
```Renders into:
```html
```
### Other transformations
The full [repertoire](https://github.com/JonasKruckenberg/imagetools/blob/main/docs/directives.md)
of transformation directives offered by
[`vite-imagetools`](https://github.com/JonasKruckenberg/imagetools) can be used.```html
// Generate all 9 variants at fixed 600px height
import src from '$lib/a/cat.jpg?h=600&fit=cover&normalize&as=run'
import Img from '@zerodevx/svelte-img'
```### Responsive Image Sizes
Use the `sizes` attribute to define media conditions that provide hints as to which image size to
select when those conditions are true. Read up more on
[responsive images and the picture element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture).```html
import src from '$lib/a/cat.jpg?w=480;800&as=run'
import Img from '@zerodevx/svelte-img'
```Renders into:
```html
```
### Lazy loading
`svelte-img` utilises the browser's native lazy loading capability by setting the `loading="lazy"`
attribute on the rendered `` tag by default. This is supported by
[most modern browsers](https://caniuse.com/loading-lazy-attr). To load an image eagerly instead:```html
import src from '$lib/a/cat.jpg?as=run'
import Img from '@zerodevx/svelte-img'
```### Batch loading local images
Use `Vite`'s `import.meta.glob` [feature](https://vitejs.dev/guide/features.html#glob-import).
```html
import Img from '@zerodevx/svelte-img'
const modules = import.meta.glob('$lib/a/cats/*.*', {
import: 'default',
eager: true,
query: { w: 640, h: 640, fit: 'cover', as: 'run' }
})
const images = Object.entries(modules).map((i) => i[1]){#each images as src}
{/each}
```### Remote images from an API
Use the `svelte-img` component on its own by passing a `src` object, like so:
```html
import Img from '@zerodevx/svelte-img'
const src = {
sources: {
// Order is important; last format is fallback img
webp: 'path/to/480.webp 480w, ...', //srcset
jpeg: '...'
},
img: { src: 'path/to/img', w: 1920, h: 1080 },
}
```### Blurred image placeholders
Natively, browsers do already apply _some_ blur when displaying low resolution images. That's enough
for me, but you can apply your own using CSS.```html
import Img from '@zerodevx/svelte-img'
import src from '$lib/a/cat.jpg?as=run'
import { onMount } from 'svelte'let ref, loaded
onMount(() => {
if (ref.complete) loaded = true
})
(loaded = true)} />
.wrap {
position: relative;
overflow: hidden;
}
.blur {
position: absolute;
inset: 0;
backdrop-filter: blur(20px);
pointer-events: none;
}
.loaded {
display: none;
}```
## Special Effects
### Fade-in on reveal
Reveal images with a fade-in effect (aka medium.com) when they are loaded **and** in the viewport.
```html
import src from '$lib/a/cat.jpg?as=run'
import { FxReveal as Img } from '@zerodevx/svelte-img':global(.my-img) {
width: 640px;
height: 480px;
/* These CSS vars (with their default values) are exposed */
--reveal-transform: scale(1.02);
--reveal-transition: opacity 1s ease-in, transform 0.8s ease-out;
--reveal-filter: blur(20px);
}```
### Parallax
Apply a vertical parallax scrolling effect to an image, where `factor` is a decimal value between 0
and 1, that controls how much slower the element scrolls, relative to the scrolling speed:- A value closer to 0 is faster, while a value closer to 1 is slower.
- A value of 1 behaves normally.
- A value of 0 effectively makes the element fixed on the page.The default factor is `0.75`.
```html
import src from '$lib/a/cat.jpg?as=run'
import { FxParallax as Img } from '@zerodevx/svelte-img':global(.my-img) {
width: 100%;
height: 28rem;
}```
## Development
Library is packaged via [SvelteKit](https://kit.svelte.dev/docs/packaging). Standard Github
[contribution workflow](https://docs.github.com/en/get-started/quickstart/contributing-to-projects)
applies.### Tests
End-to-end testing via [Playwright](https://github.com/microsoft/playwright). To run tests
headlessly:```
$ npm run test
```## Changelog
Please refer to the [releases](https://github.com/zerodevx/svelte-img/releases) page.
## License
ISC