lite-image-preview 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +24 -0
- package/README.md +286 -0
- package/dist/main.cjs +722 -0
- package/dist/main.d.ts +116 -0
- package/dist/main.js +719 -0
- package/package.json +63 -0
- package/rolldown.config.js +18 -0
- package/src/main.ts +11 -0
- package/src/preview.ts +834 -0
- package/src/types.ts +98 -0
- package/src/util.ts +102 -0
- package/tsconfig.app.json +47 -0
- package/tsconfig.json +11 -0
- package/tsconfig.node.json +24 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
|
2
|
+
|
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
4
|
+
distribute this software, either in source code form or as a compiled
|
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
6
|
+
means.
|
|
7
|
+
|
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
9
|
+
of this software dedicate any and all copyright interest in the
|
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
|
11
|
+
of the public at large and to the detriment of our heirs and
|
|
12
|
+
successors. We intend this dedication to be an overt act of
|
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
14
|
+
software under copyright law.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
For more information, please refer to <https://unlicense.org/>
|
package/README.md
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# lite-image-preview
|
|
2
|
+
|
|
3
|
+
A lightweight, dependency-free image preview dialog for the web.
|
|
4
|
+
|
|
5
|
+
It supports smooth pan and zoom for raster images and crisp SVG zooming with `viewBox`, while keeping the API small and easy to use. Touch gestures are handled separately from pointer gestures to improve mobile compatibility.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
* Dependency-free runtime
|
|
12
|
+
* Smooth pan and zoom for images
|
|
13
|
+
* Crisp SVG preview using `viewBox`-based scaling
|
|
14
|
+
* Mobile-friendly touch handling
|
|
15
|
+
* Pointer support for mouse, pen, and non-touch input
|
|
16
|
+
* Built-in modal preview dialog
|
|
17
|
+
* Reset-to-fit action in the toolbar
|
|
18
|
+
* Small public API, with advanced customization hooks
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm i lite-image-preview
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
or
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm i lite-image-preview
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
### Preview an image from a URL
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { previewImage } from 'lite-image-preview'
|
|
42
|
+
|
|
43
|
+
const close = await previewImage('/assets/photo.jpg')
|
|
44
|
+
|
|
45
|
+
// Close the dialog later
|
|
46
|
+
close?.()
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Preview an existing SVG element
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { previewSvg } from 'lite-image-preview'
|
|
53
|
+
|
|
54
|
+
const svg = document.querySelector('svg')
|
|
55
|
+
if (svg) {
|
|
56
|
+
const close = await previewSvg(svg)
|
|
57
|
+
// close?.()
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Basic usage
|
|
64
|
+
|
|
65
|
+
`previewImage()` and `previewSvg()` both open a modal preview dialog.
|
|
66
|
+
|
|
67
|
+
The returned promise resolves to a close handle once the preview is ready.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { previewImage } from 'lite-image-preview'
|
|
71
|
+
|
|
72
|
+
const close = await previewImage('https://example.com/image.png')
|
|
73
|
+
|
|
74
|
+
if (close) {
|
|
75
|
+
// You can close programmatically later.
|
|
76
|
+
close()
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
If the image fails to load, `previewImage()` resolves to `null`.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## API overview
|
|
85
|
+
|
|
86
|
+
### `previewImage(url, dispose?)`
|
|
87
|
+
|
|
88
|
+
Opens a preview dialog for a raster image.
|
|
89
|
+
|
|
90
|
+
* `url` — Image URL.
|
|
91
|
+
* `dispose?` — Optional callback invoked after the dialog fully closes.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
|
|
95
|
+
* `Promise<PreviewCloseHandle | null>`
|
|
96
|
+
|
|
97
|
+
### `previewSvg(svg, dispose?)`
|
|
98
|
+
|
|
99
|
+
Opens a preview dialog for an existing SVG element.
|
|
100
|
+
|
|
101
|
+
* `svg` — The SVG element to preview.
|
|
102
|
+
* `dispose?` — Optional callback invoked after the dialog fully closes.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
|
|
106
|
+
* `Promise<PreviewCloseHandle>`
|
|
107
|
+
|
|
108
|
+
### `createPreview(content, initAdapter, dispose?)`
|
|
109
|
+
|
|
110
|
+
Advanced API for custom preview content.
|
|
111
|
+
|
|
112
|
+
* `content` — The DOM element to mount into the preview stage.
|
|
113
|
+
* `initAdapter` — Adapter factory used to implement zoom, pan, reset, and cleanup behavior.
|
|
114
|
+
* `dispose?` — Optional callback invoked after the dialog fully closes.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
|
|
118
|
+
* `PreviewCloseHandle`
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Example: basic image preview
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { previewImage } from 'lite-image-preview'
|
|
126
|
+
|
|
127
|
+
async function openPhoto() {
|
|
128
|
+
const close = await previewImage('/assets/photo.jpg')
|
|
129
|
+
|
|
130
|
+
if (!close) {
|
|
131
|
+
console.warn('Image failed to load')
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// close after 3 seconds
|
|
136
|
+
setTimeout(() => close(), 3000)
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Example: basic SVG preview
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { previewSvg } from 'lite-image-preview'
|
|
146
|
+
|
|
147
|
+
const svg = document.querySelector('svg')
|
|
148
|
+
|
|
149
|
+
if (svg) {
|
|
150
|
+
const close = await previewSvg(svg)
|
|
151
|
+
|
|
152
|
+
// close?.()
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Example: custom preview content
|
|
159
|
+
|
|
160
|
+
The package also exposes `createPreview()` and `PreviewAdapter` for advanced use cases.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import { createPreview, type PreviewAdapter } from 'lite-image-preview'
|
|
164
|
+
|
|
165
|
+
const el = document.createElement('div')
|
|
166
|
+
el.textContent = 'Custom content'
|
|
167
|
+
el.style.width = '400px'
|
|
168
|
+
el.style.height = '240px'
|
|
169
|
+
el.style.background = '#ddd'
|
|
170
|
+
|
|
171
|
+
const close = createPreview(el, (stage): PreviewAdapter => {
|
|
172
|
+
// Example adapter: no-op transform behavior.
|
|
173
|
+
return {
|
|
174
|
+
fitToStage() {},
|
|
175
|
+
panBy() {},
|
|
176
|
+
zoomAt() {},
|
|
177
|
+
beginPinch() {},
|
|
178
|
+
updatePinch() {},
|
|
179
|
+
zoomWithWheel(e) {
|
|
180
|
+
e.preventDefault()
|
|
181
|
+
},
|
|
182
|
+
destroy() {},
|
|
183
|
+
resetStyle() {},
|
|
184
|
+
}
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
// close()
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Keyboard and interaction behavior
|
|
193
|
+
|
|
194
|
+
* Click the close button to exit the dialog.
|
|
195
|
+
* Click **Reset** to return to the initial fitted view.
|
|
196
|
+
* Mouse wheel zooms around the pointer position.
|
|
197
|
+
* Drag to pan.
|
|
198
|
+
* Pinch with two fingers to zoom on touch devices.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## How the preview behaves
|
|
203
|
+
|
|
204
|
+
### Raster images
|
|
205
|
+
|
|
206
|
+
Raster images use a transform-based renderer.
|
|
207
|
+
|
|
208
|
+
* Initial state is fitted and centered in the stage.
|
|
209
|
+
* Dragging pans the image.
|
|
210
|
+
* Wheel and pinch gestures zoom around the gesture center.
|
|
211
|
+
* Reset returns to the initial fitted state.
|
|
212
|
+
|
|
213
|
+
### SVG
|
|
214
|
+
|
|
215
|
+
SVG uses `viewBox`-based scaling instead of CSS scaling.
|
|
216
|
+
|
|
217
|
+
This keeps zoomed SVG content crisp instead of rasterizing it too early.
|
|
218
|
+
|
|
219
|
+
* Initial state is fitted and centered.
|
|
220
|
+
* Dragging updates the `viewBox` position.
|
|
221
|
+
* Wheel and pinch gestures update the `viewBox` size and position.
|
|
222
|
+
* Reset returns to the initial fitted `viewBox`.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Public types
|
|
227
|
+
|
|
228
|
+
The package exports the main types so advanced consumers can build custom adapters.
|
|
229
|
+
|
|
230
|
+
* `PreviewController`
|
|
231
|
+
* `PreviewAdapter`
|
|
232
|
+
* `PreviewAdapterFactory`
|
|
233
|
+
* `Point`
|
|
234
|
+
* `TransformState`
|
|
235
|
+
* `ViewBox`
|
|
236
|
+
* `PreviewCloseHandle`
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Advanced customization
|
|
241
|
+
|
|
242
|
+
If you need to preview a different kind of element, use `createPreview()` plus a custom adapter.
|
|
243
|
+
|
|
244
|
+
A custom adapter can decide how to implement:
|
|
245
|
+
|
|
246
|
+
* initial fitting
|
|
247
|
+
* panning
|
|
248
|
+
* zooming around a point
|
|
249
|
+
* pinch gesture updates
|
|
250
|
+
* wheel zoom
|
|
251
|
+
* cleanup
|
|
252
|
+
* style restoration
|
|
253
|
+
|
|
254
|
+
This design lets the container stay simple while each rendering backend keeps its own optimal strategy.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Notes on browser support
|
|
259
|
+
|
|
260
|
+
This package is designed for modern browsers.
|
|
261
|
+
|
|
262
|
+
It uses:
|
|
263
|
+
|
|
264
|
+
* `<dialog>`
|
|
265
|
+
* Pointer Events for non-touch input
|
|
266
|
+
* Touch Events for mobile pinch handling
|
|
267
|
+
* `requestAnimationFrame`
|
|
268
|
+
* CSS transforms and SVG `viewBox`
|
|
269
|
+
|
|
270
|
+
If you need to support old browsers, consider using polyfills.
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Development notes
|
|
275
|
+
|
|
276
|
+
* No runtime dependencies are required.
|
|
277
|
+
* SVG preview is intentionally implemented with `viewBox` so zoomed content stays sharp.
|
|
278
|
+
* Touch gestures are handled separately from pointer gestures to improve mobile browser behavior.
|
|
279
|
+
|
|
280
|
+
*Note*: We might add EventTarget support so that a 'close' event can be dispatched when the user closed the dialog, providing more customability.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## License
|
|
285
|
+
|
|
286
|
+
Unlicense
|