@zumer/snapdom 1.9.10-dev.1 → 1.9.10

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
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <a href="http://zumerlab.github.io/snapdom">
3
- <img src="https://raw.githubusercontent.com/zumerlab/snapdom/main/docs/assets/newhero.png" width="70%">
3
+ <img src="https://raw.githubusercontent.com/zumerlab/snapdom/main/docs/assets/newhero.png" width="80%">
4
4
  </a>
5
5
  </p>
6
6
 
@@ -42,6 +42,46 @@ It captures any HTML element as a scalable SVG image, preserving styles, fonts,
42
42
 
43
43
  [https://zumerlab.github.io/snapdom/](https://zumerlab.github.io/snapdom/)
44
44
 
45
+
46
+ ## Table of Contents
47
+
48
+ - [Installation](#installation)
49
+ - [NPM / Yarn](#npm--yarn)
50
+ - [CDN](#cdn)
51
+ - [Script tag (local)](#script-tag-local)
52
+ - [ES Module](#es-module)
53
+ - [Module via CDN](#module-via-cdn)
54
+ - [Basic usage](#basic-usage)
55
+ - [Reusable capture](#reusable-capture)
56
+ - [One-step shortcuts](#one-step-shortcuts)
57
+ - [API](#api)
58
+ - [snapdom(el, options?)](#snapdomel-options)
59
+ - [Shortcut methods](#shortcut-methods)
60
+ - [Options](#options)
61
+ - [Fallback image on `<img>` load failure](#fallback-image-on-img-load-failure)
62
+ - [Dimensions (`scale`, `width`, `height`)](#dimensions-scale-width-height)
63
+ - [Cross-Origin Images & Fonts (`useProxy`)](#cross-origin-images--fonts-useproxy)
64
+ - [Fonts](#fonts)
65
+ - [embedFonts](#embedfonts)
66
+ - [localFonts](#localfonts)
67
+ - [iconFonts](#iconfonts)
68
+ - [excludeFonts](#excludefonts)
69
+ - [Filtering nodes: `exclude` vs `filter`](#filtering-nodes-exclude-vs-filter)
70
+ - [preCache() – Optional helper](#precache--optional-helper)
71
+ - [Cache control](#cache-control)
72
+ - [Limitations](#limitations)
73
+ - [⚡ Performance Benchmarks (Chromium)](#performance-benchmarks)
74
+ - [Simple elements](#simple-elements)
75
+ - [Complex elements](#complex-elements)
76
+ - [Run the benchmarks](#run-the-benchmarks)
77
+ - [Roadmap](#roadmap)
78
+ - [Development](#development)
79
+ - [Contributors 🙌](#contributors)
80
+ - [💖 Sponsors](#sponsors)
81
+ - [Star History](#star-history)
82
+ - [License](#license)
83
+
84
+
45
85
  ## Installation
46
86
 
47
87
  ### NPM / Yarn
@@ -164,6 +204,36 @@ All capture methods accept an `options` object:
164
204
  | `exclude` | string[] | - | CSS selectors to exclude |
165
205
  | `filter` | function | - | Custom predicate `(el) => boolean` |
166
206
  | `cache` | string | `"soft"` | Control internal caches: `disabled`, `soft`, `auto`, `full` |
207
+ | `defaultImageUrl` | 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}`) |
208
+
209
+ ### Fallback image on `<img>` load failure
210
+
211
+ Provide a default image for failed `<img>` loads. You can pass a fixed URL or a callback that receives measured dimensions and returns a URL (handy to generate dynamic placeholders).
212
+
213
+ ```js
214
+ // 1) Fixed URL fallback
215
+ await snapdom.toImg(element, {
216
+ defaultImageUrl: '/images/fallback.png'
217
+ });
218
+
219
+ // 2) Dynamic placeholder via callback
220
+ await snapdom.toImg(element, {
221
+ defaultImageUrl: ({ width = 300, height = 150 }) =>
222
+ `https://placehold.co/${Math.round(width)}x${Math.round(height)}`
223
+ });
224
+
225
+ // 3) With proxy (if your fallback host has no CORS)
226
+ await snapdom.toImg(element, {
227
+ defaultImageUrl: ({ width = 300, height = 150 }) =>
228
+ `https://dummyimage.com/${Math.round(width)}x${Math.round(height)}/cccccc/666.png&text=img`,
229
+ useProxy: 'https://corsproxy.io/?url='
230
+ });
231
+ ```
232
+
233
+ Notes:
234
+ - If the fallback image also fails to load, snapDOM replaces the `<img>` with a placeholder block preserving width/height.
235
+ - Width/height used by the callback are gathered from the original element (dataset, style/attrs, etc.) when available.
236
+
167
237
 
168
238
  ### Dimensions (`scale`, `width`, `height`)
169
239
 
@@ -280,7 +350,7 @@ You can control how they are cleared between captures using the `cache` option:
280
350
 
281
351
  | Mode | Description |
282
352
  | ----------- | --------------------------------------------------------------------------- |
283
- | `"disabled"`| No cache: clears absolutely everything on every capture |
353
+ | `"disabled"`| No cache |
284
354
  | `"soft"` | Clears session caches (`styleMap`, `nodeMap`, `styleCache`) _(default)_ |
285
355
  | `"auto"` | Minimal cleanup: only clears transient maps |
286
356
  | `"full"` | Keeps all caches (nothing is cleared, maximum performance) |
@@ -301,55 +371,36 @@ await snapdom.toPng(el, { cache: 'disabled' });
301
371
  ## Limitations
302
372
 
303
373
  * External images should be CORS-accessible (use `useProxy` option for handling CORS denied)
304
- * Iframes are not supported
305
374
  * When WebP format is used on Safari, it will fallback to PNG rendering.
306
375
  * `@font-face` CSS rule is well supported, but if need to use JS `FontFace()`, see this workaround [`#43`](https://github.com/zumerlab/snapdom/issues/43)
307
376
 
308
377
 
309
- ## ⚡ Performance Benchmarks
310
-
311
- Snapdom has received **significant performance improvements** since version `v1.8.0`. The following benchmarks compare:
312
-
313
- * **Snapdom (current)**
314
- * **Snapdom v1.8.0**
315
- * `html2canvas`
316
- * `html-to-image`
378
+ ## Performance Benchmarks
317
379
 
380
+ **Setup.** Vitest benchmarks on Chromium, repo tests. Hardware may affect results.
381
+ Values are **average capture time (ms)** → lower is better.
318
382
 
319
383
  ### Simple elements
320
384
 
321
- | Scenario | Snapdom (current) | Snapdom v1.8.0 | html2canvas | html-to-image |
322
- | ------------------------ | ----------------- | -------------- | ----------- | ------------- |
323
- | Small (200×100) | **0.4 ms** | 1.2 ms | 70.3 ms | 3.6 ms |
324
- | Modal (400×300) | **0.4 ms** | 1.1 ms | 68.8 ms | 3.6 ms |
325
- | Page View (1200×800) | **0.4 ms** | 1.0 ms | 100.5 ms | 3.4 ms |
326
- | Large Scroll (2000×1500) | **0.4 ms** | 1.0 ms | 153.1 ms | 3.4 ms |
327
- | Very Large (4000×2000) | **0.4 ms** | 1.0 ms | 278.9 ms | 4.3 ms |
328
-
385
+ | Scenario | SnapDOM v1.9.10 | SnapDOM v1.9.9 | html2canvas | html-to-image |
386
+ | ------------------------ | --------------- | -------------- | ----------- | ------------- |
387
+ | Small (200×100) | **0.5 ms** | 0.8 ms | 67.7 ms | 3.1 ms |
388
+ | Modal (400×300) | **0.5 ms** | 0.8 ms | 75.5 ms | 3.6 ms |
389
+ | Page View (1200×800) | **0.5 ms** | 0.8 ms | 114.2 ms | 3.3 ms |
390
+ | Large Scroll (2000×1500) | **0.5 ms** | 0.8 ms | 186.3 ms | 3.2 ms |
391
+ | Very Large (4000×2000) | **0.5 ms** | 0.9 ms | 425.9 ms | 3.3 ms |
329
392
 
393
+ ---
330
394
 
331
395
  ### Complex elements
332
396
 
333
- | Scenario | Snapdom (current) | Snapdom v1.8.0 | html2canvas | html-to-image |
334
- | ------------------------ | ----------------- | -------------- | ----------- | ------------- |
335
- | Small (200×100) | **1.1 ms** | 3.2 ms | 76.0 ms | 15.3 ms |
336
- | Modal (400×300) | **4.5 ms** | 14.0 ms | 133.2 ms | 55.4 ms |
337
- | Page View (1200×800) | **32.9 ms** | 113.6 ms | 303.4 ms | 369.1 ms |
338
- | Large Scroll (2000×1500) | **133.9 ms** | 387.4 ms | 594.4 ms | 1,163.0 ms |
339
- | Very Large (4000×2000) | **364.0 ms** | 1,200.4 ms | 1,380.8 ms | 3,023.9 ms |
340
-
341
-
342
-
343
- ### Summary
344
-
345
- * Snapdom (current) is **2×–6× faster** than `v1.8.0`
346
- * Up to **150× faster** than `html2canvas`
347
- * Up to **8× faster** than `html-to-image` in large scenarios
348
-
349
- <sub>Benchmarks run in Chromium using Vitest.<br>
350
- Hardware: MacBook Air 2018.<br>
351
- ⚠️ Performance may vary depending on device.</sub>
352
-
397
+ | Scenario | SnapDOM v1.9.10 | SnapDOM v1.9.9 | html2canvas | html-to-image |
398
+ | ------------------------ | --------------- | -------------- | ----------- | ------------- |
399
+ | Small (200×100) | **1.6 ms** | 3.3 ms | 68.0 ms | 14.3 ms |
400
+ | Modal (400×300) | **2.9 ms** | 6.8 ms | 87.5 ms | 34.8 ms |
401
+ | Page View (1200×800) | **17.5 ms** | 50.2 ms | 178.0 ms | 429.0 ms |
402
+ | Large Scroll (2000×1500) | **54.0 ms** | 201.8 ms | 735.2 ms | 984.2 ms |
403
+ | Very Large (4000×2000) | **171.4 ms** | 453.7 ms | 1,800.4 ms | 2,611.9 ms |
353
404
 
354
405
 
355
406
  ### Run the benchmarks
@@ -375,10 +426,10 @@ Planned improvements for future versions of SnapDOM:
375
426
  * [X] **Decouple internal logic from global options**
376
427
  Functions will be redesigned to avoid relying directly on `options`. A centralized capture context will improve clarity, autonomy, and testability. See [`next` branch](https://github.com/zumerlab/snapdom/tree/main)
377
428
 
378
- * [ ] **Expose cache control**
429
+ * [X] **Expose cache control**
379
430
  Users will be able to manually clear image and font caches or configure their own caching strategies.
380
431
 
381
- * [ ] **Auto font preloading**
432
+ * [X] **Auto font preloading**
382
433
  Required fonts will be automatically detected and preloaded before capture, reducing the need for manual `preCache()` calls.
383
434
 
384
435
  * [ ] **Document plugin development**
@@ -424,7 +475,7 @@ The main entry point is in `src/`, and output bundles are generated in the `dist
424
475
  For detailed contribution guidelines, please see [CONTRIBUTING](https://github.com/zumerlab/snapdom/blob/main/CONTRIBUTING.md).
425
476
 
426
477
 
427
- ## Contributors 🙌
478
+ ## Contributors
428
479
 
429
480
  <!-- CONTRIBUTORS:START -->
430
481
  <p>
@@ -449,7 +500,7 @@ For detailed contribution guidelines, please see [CONTRIBUTING](https://github.c
449
500
  </p>
450
501
  <!-- CONTRIBUTORS:END -->
451
502
 
452
- ## 💖 Sponsors
503
+ ## Sponsors
453
504
 
454
505
  Special thanks to [@megaphonecolin](https://github.com/megaphonecolin) for supporting this project!
455
506