@zumer/snapdom 1.9.12-dev.4 → 1.9.14
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/README.md +58 -27
- package/dist/snapdom.js +621 -337
- package/dist/snapdom.min.js +8 -5
- package/dist/snapdom.min.mjs +8 -5
- package/dist/snapdom.mjs +609 -332
- package/package.json +7 -2
- package/types/snapdom.d.ts +18 -0
package/README.md
CHANGED
|
@@ -38,12 +38,12 @@ It captures any HTML element as a scalable SVG image, preserving styles, fonts,
|
|
|
38
38
|
* ⚡ Ultra fast, no dependencies
|
|
39
39
|
* 📦 100% based on standard Web APIs
|
|
40
40
|
* Support same-origin `ìframe`
|
|
41
|
-
* Support CSS counter() and counters()
|
|
41
|
+
* Support CSS counter() and CSS counters()
|
|
42
42
|
* Support `...` line-clamp
|
|
43
43
|
|
|
44
44
|
## Demo
|
|
45
45
|
|
|
46
|
-
[https://
|
|
46
|
+
[https://snapdom.dev](https://snapdom.dev)
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
## Table of Contents
|
|
@@ -69,8 +69,10 @@ It captures any HTML element as a scalable SVG image, preserving styles, fonts,
|
|
|
69
69
|
- [iconFonts](#iconfonts)
|
|
70
70
|
- [excludeFonts](#excludefonts)
|
|
71
71
|
- [Filtering nodes: `exclude` vs `filter`](#filtering-nodes-exclude-vs-filter)
|
|
72
|
-
- [
|
|
72
|
+
- [straighten](#straighten)
|
|
73
|
+
- [noShadows](#no-shadows)
|
|
73
74
|
- [Cache control](#cache-control)
|
|
75
|
+
- [preCache](#precache--optional-helper)
|
|
74
76
|
- [Limitations](#limitations)
|
|
75
77
|
- [⚡ Performance Benchmarks (Chromium)](#performance-benchmarks)
|
|
76
78
|
- [Simple elements](#simple-elements)
|
|
@@ -163,7 +165,8 @@ Returns an object with reusable export methods:
|
|
|
163
165
|
{
|
|
164
166
|
url: string;
|
|
165
167
|
toRaw(): string;
|
|
166
|
-
toImg(): Promise<HTMLImageElement>;
|
|
168
|
+
toImg(): Promise<HTMLImageElement>; // deprecated
|
|
169
|
+
toSvg(): Promise<HTMLImageElement>;
|
|
167
170
|
toCanvas(): Promise<HTMLCanvasElement>;
|
|
168
171
|
toBlob(options?): Promise<Blob>;
|
|
169
172
|
toPng(options?): Promise<HTMLImageElement>;
|
|
@@ -177,7 +180,8 @@ Returns an object with reusable export methods:
|
|
|
177
180
|
|
|
178
181
|
| Method | Description |
|
|
179
182
|
| ------------------------------ | --------------------------------- |
|
|
180
|
-
| `snapdom.toImg(el, options?)` | Returns an `HTMLImageElement`
|
|
183
|
+
| `snapdom.toImg(el, options?)` | Returns an SVG `HTMLImageElement` (deprecated) |
|
|
184
|
+
| `snapdom.toSvg(el, options?)` | Returns an SVG `HTMLImageElement` |
|
|
181
185
|
| `snapdom.toCanvas(el, options?)` | Returns a `Canvas` |
|
|
182
186
|
| `snapdom.toBlob(el, options?)` | Returns an SVG or raster `Blob` |
|
|
183
187
|
| `snapdom.toPng(el, options?)` | Returns a PNG image |
|
|
@@ -191,13 +195,14 @@ Returns an object with reusable export methods:
|
|
|
191
195
|
|
|
192
196
|
All capture methods accept an `options` object:
|
|
193
197
|
|
|
198
|
+
|
|
194
199
|
| Option | Type | Default | Description |
|
|
195
200
|
| ----------------- | -------- | -------- | ----------------------------------------------- |
|
|
196
201
|
| `fast` | boolean | `true` | Skips small idle delays for faster results |
|
|
197
202
|
| `embedFonts` | boolean | `false` | Inlines non-icon fonts (icon fonts always on) |
|
|
198
203
|
| `localFonts` | array | `[]` | Local fonts `{ family, src, weight?, style? }` |
|
|
199
204
|
| `iconFonts` | string\|RegExp\|Array | `[]` | Extra icon font matchers |
|
|
200
|
-
| `excludeFonts` | object
|
|
205
|
+
| `excludeFonts` | object | `{}` | Exclude families/domains/subsets during embedding |
|
|
201
206
|
| `scale` | number | `1` | Output scale multiplier |
|
|
202
207
|
| `dpr` | number | `devicePixelRatio` | Device pixel ratio |
|
|
203
208
|
| `width` | number | - | Output width |
|
|
@@ -207,12 +212,14 @@ All capture methods accept an `options` object:
|
|
|
207
212
|
| `useProxy` | string | `''` | Proxy base for CORS fallbacks |
|
|
208
213
|
| `type` | string | `svg` | Default Blob type (`svg`\|`png`\|`jpg`\|`webp`) |
|
|
209
214
|
| `exclude` | string[] | - | CSS selectors to exclude |
|
|
210
|
-
| `excludeMode` |
|
|
215
|
+
| `excludeMode` | `"hide"`\|`"remove"` | `"hide"` | How `exclude` is applied |
|
|
211
216
|
| `filter` | function | - | Custom predicate `(el) => boolean` |
|
|
212
|
-
| `filterMode` |
|
|
213
|
-
| `cache` | string | `"soft"` |
|
|
214
|
-
| `placeholders`
|
|
215
|
-
| `fallbackURL`
|
|
217
|
+
| `filterMode` | `"hide"`\|`"remove"` | `"hide"` | How `filter` is applied |
|
|
218
|
+
| `cache` | string | `"soft"` | `disabled` \| `soft` \| `auto` \| `full` |
|
|
219
|
+
| `placeholders` | boolean | `true` | Show placeholders for images/CORS iframes |
|
|
220
|
+
| `fallbackURL` | string \| function | - | Fallback image for `<img>` load failure |
|
|
221
|
+
| `straighten` | boolean | `false` | Straightens the root: removes `translate/rotate` but preserves `scale/skew`, producing a flat, reusable capture |
|
|
222
|
+
| `noShadows` | boolean | `false` | Do not expand the root’s bounding box for shadows/blur/outline, and strip those visual effects from the cloned root |
|
|
216
223
|
|
|
217
224
|
### Fallback image on `<img>` load failure
|
|
218
225
|
|
|
@@ -220,18 +227,18 @@ Provide a default image for failed `<img>` loads. You can pass a fixed URL or a
|
|
|
220
227
|
|
|
221
228
|
```js
|
|
222
229
|
// 1) Fixed URL fallback
|
|
223
|
-
await snapdom.
|
|
230
|
+
await snapdom.toSvg(element, {
|
|
224
231
|
fallbackURL: '/images/fallback.png'
|
|
225
232
|
});
|
|
226
233
|
|
|
227
234
|
// 2) Dynamic placeholder via callback
|
|
228
|
-
await snapdom.
|
|
235
|
+
await snapdom.toSvg(element, {
|
|
229
236
|
fallbackURL: ({ width: 300, height: 150 }) =>
|
|
230
237
|
`https://placehold.co/${width}x${height}`
|
|
231
238
|
});
|
|
232
239
|
|
|
233
240
|
// 3) With proxy (if your fallback host has no CORS)
|
|
234
|
-
await snapdom.
|
|
241
|
+
await snapdom.toSvg(element, {
|
|
235
242
|
fallbackURL: ({ width = 300, height = 150 }) =>
|
|
236
243
|
`https://dummyimage.com/${width}x${height}/cccccc/666.png&text=img`,
|
|
237
244
|
useProxy: 'https://proxy.corsfix.com/?'
|
|
@@ -307,7 +314,7 @@ await snapdom.toPng(el, {
|
|
|
307
314
|
- Matching is case-insensitive for `families`. Hosts are matched by substring against the resolved URL.
|
|
308
315
|
|
|
309
316
|
|
|
310
|
-
|
|
317
|
+
#### Filtering nodes: `exclude` vs `filter`
|
|
311
318
|
|
|
312
319
|
* `exclude`: remove by **selector**.
|
|
313
320
|
* `excludeMode`: `hide` applies `visibility:hidden` CSS rule on excluded nodes and the layout remains as the original. `remove` do not clone excluded nodes at all.
|
|
@@ -336,22 +343,30 @@ await snapdom.toPng(el, {
|
|
|
336
343
|
exclude: ['.cookie-banner', '.tooltip', '[data-test="debug"]']
|
|
337
344
|
});
|
|
338
345
|
```
|
|
339
|
-
### `preCache()` – Optional helper
|
|
340
346
|
|
|
341
|
-
|
|
347
|
+
### Straighten
|
|
342
348
|
|
|
343
|
-
|
|
344
|
-
import { preCache } from '@zumer/snapdom';
|
|
349
|
+
When capturing rotated or translated elements, you may want to **straighten** the root so the snapshot can be reused in another layout without inheriting those transforms.
|
|
345
350
|
|
|
346
|
-
|
|
347
|
-
root:
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
351
|
+
- **`straighten: true`**
|
|
352
|
+
Straightens the cloned root: **removes `translate` and `rotate`** but **keeps `scale/skew`** to preserve proportions.
|
|
353
|
+
The output is **flat, upright, and ready** to embed elsewhere.
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
### noShadows
|
|
357
|
+
- **`noShadows: true`**
|
|
358
|
+
Prevents expanding the bounding box for shadows, blur, or outline on the root, and also strips `box-shadow`, `text-shadow`, `filter: blur()/drop-shadow()`, and `outline` from the cloned root.
|
|
359
|
+
|
|
360
|
+
> 💡 **Tip:** Using both (`straighten` + `noShadows`) produces a strict, minimal bounding box with no visual bleed.
|
|
361
|
+
|
|
362
|
+
**Example**
|
|
363
|
+
|
|
364
|
+
```js
|
|
365
|
+
// Straighten and remove shadow bleed
|
|
366
|
+
await snapdom.toSvg(el, { straighten: true, noShadows: true });
|
|
352
367
|
```
|
|
353
368
|
|
|
354
|
-
|
|
369
|
+
## Cache control
|
|
355
370
|
|
|
356
371
|
SnapDOM maintains internal caches for images, backgrounds, resources, styles, and fonts.
|
|
357
372
|
You can control how they are cleared between captures using the `cache` option:
|
|
@@ -376,6 +391,21 @@ await snapdom.toPng(el, { cache: 'full' });
|
|
|
376
391
|
await snapdom.toPng(el, { cache: 'disabled' });
|
|
377
392
|
```
|
|
378
393
|
|
|
394
|
+
## `preCache()` – Optional helper
|
|
395
|
+
|
|
396
|
+
Preloads external resources to avoid first-capture stalls (helpful for big/complex trees).
|
|
397
|
+
|
|
398
|
+
```js
|
|
399
|
+
import { preCache } from '@zumer/snapdom';
|
|
400
|
+
|
|
401
|
+
await preCache({
|
|
402
|
+
root: document.body,
|
|
403
|
+
embedFonts: true,
|
|
404
|
+
localFonts: [{ family: 'Inter', src: '/fonts/Inter.woff2', weight: 400 }],
|
|
405
|
+
useProxy: 'https://proxy.corsfix.com/?'
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
379
409
|
## Limitations
|
|
380
410
|
|
|
381
411
|
* External images should be CORS-accessible (use `useProxy` option for handling CORS denied)
|
|
@@ -490,6 +520,7 @@ For detailed contribution guidelines, please see [CONTRIBUTING](https://github.c
|
|
|
490
520
|
<a href="https://github.com/tinchox5" title="tinchox5"><img src="https://avatars.githubusercontent.com/u/11557901?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="tinchox5"/></a>
|
|
491
521
|
<a href="https://github.com/Jarvis2018" title="Jarvis2018"><img src="https://avatars.githubusercontent.com/u/36788851?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="Jarvis2018"/></a>
|
|
492
522
|
<a href="https://github.com/tarwin" title="tarwin"><img src="https://avatars.githubusercontent.com/u/646149?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="tarwin"/></a>
|
|
523
|
+
<a href="https://github.com/K1ender" title="K1ender"><img src="https://avatars.githubusercontent.com/u/146767945?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="K1ender"/></a>
|
|
493
524
|
<a href="https://github.com/17biubiu" title="17biubiu"><img src="https://avatars.githubusercontent.com/u/13295895?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="17biubiu"/></a>
|
|
494
525
|
<a href="https://github.com/av01d" title="av01d"><img src="https://avatars.githubusercontent.com/u/6247646?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="av01d"/></a>
|
|
495
526
|
<a href="https://github.com/CHOYSEN" title="CHOYSEN"><img src="https://avatars.githubusercontent.com/u/25995358?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="CHOYSEN"/></a>
|
|
@@ -512,7 +543,7 @@ For detailed contribution guidelines, please see [CONTRIBUTING](https://github.c
|
|
|
512
543
|
|
|
513
544
|
## Sponsors
|
|
514
545
|
|
|
515
|
-
Special thanks to [@megaphonecolin](https://github.com/megaphonecolin) for supporting this project!
|
|
546
|
+
Special thanks to [@megaphonecolin](https://github.com/megaphonecolin), [@sdraper69](https://github.com/sdraper69), [@reynaldichernando](https://github.com/reynaldichernando) and [@gamma-app](https://github.com/gamma-app), for supporting this project!
|
|
516
547
|
|
|
517
548
|
If you'd like to support this project too, you can [become a sponsor](https://github.com/sponsors/tinchox5).
|
|
518
549
|
|