@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 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://zumerlab.github.io/snapdom/](https://zumerlab.github.io/snapdom/)
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
- - [preCache() – Optional helper](#precache--optional-helper)
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 | `{}` | Exclude font families/domains/subsets during embedding |
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` | string | 'hide' | Controls how `exclude` works with nodes |
215
+ | `excludeMode` | `"hide"`\|`"remove"` | `"hide"` | How `exclude` is applied |
211
216
  | `filter` | function | - | Custom predicate `(el) => boolean` |
212
- | `filterMode` | string | 'hide' | Controls how `filter` works with nodes |
213
- | `cache` | string | `"soft"` | Control internal caches: `disabled`, `soft`, `auto`, `full` |
214
- | `placeholders` | boolean | `true` | Show placeholders for images and cross-origin iframes |
215
- | `fallbackURL` | string \| function | - | Fallback image when an `<img>` fails. If a function is provided, it receives `{ width?, height?, src?, element }` and must return a URL (string or Promise<string>). Useful for placeholder services (e.g. `https://placehold.co/{width}x{height}`) |
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.toImg(element, {
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.toImg(element, {
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.toImg(element, {
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
- ### Filtering nodes: `exclude` vs `filter`
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
- Preloads external resources to avoid first-capture stalls (helpful for big/complex trees).
347
+ ### Straighten
342
348
 
343
- ```js
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
- await preCache({
347
- root: document.body,
348
- embedFonts: true,
349
- localFonts: [{ family: 'Inter', src: '/fonts/Inter.woff2', weight: 400 }],
350
- useProxy: 'https://proxy.corsfix.com/?'
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
- ### Cache control
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