@zumer/snapdom 1.7.1 → 1.9.3

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
@@ -7,7 +7,25 @@
7
7
  </p>
8
8
 
9
9
  <p align="center">
10
- <a href="https://www.npmjs.com/package/@zumer/snapdom"><img src="https://img.shields.io/github/package-json/v/zumerlab/snapdom"></a>
10
+ <a href="https://www.npmjs.com/package/@zumer/snapdom">
11
+ <img alt="NPM version" src="https://img.shields.io/npm/v/@zumer/snapdom?style=flat-square&label=Version">
12
+ </a>
13
+ <a href="https://github.com/zumerlab/snapdom/graphs/contributors">
14
+ <img alt="GitHub contributors" src="https://img.shields.io/github/contributors/zumerlab/snapdom?style=flat-square&label=Contributors">
15
+ </a>
16
+ <a href="https://github.com/zumerlab/snapdom/stargazers">
17
+ <img alt="GitHub stars" src="https://img.shields.io/github/stars/zumerlab/snapdom?style=flat-square&label=Stars">
18
+ </a>
19
+ <a href="https://github.com/zumerlab/snapdom/network/members">
20
+ <img alt="GitHub forks" src="https://img.shields.io/github/forks/zumerlab/snapdom?style=flat-square&label=Forks">
21
+ </a>
22
+ <a href="https://github.com/sponsors/tinchox5">
23
+ <img alt="Sponsor tinchox5" src="https://img.shields.io/github/sponsors/tinchox5?style=flat-square&label=Sponsor">
24
+ </a>
25
+
26
+ <a href="https://github.com/zumerlab/snapdom/blob/main/LICENSE">
27
+ <img alt="License" src="https://img.shields.io/github/license/zumerlab/snapdom?style=flat-square">
28
+ </a>
11
29
  </p>
12
30
 
13
31
  **snapDOM** is a fast and accurate DOM-to-image capture tool built for **Zumly**, a zoom-based view transition framework.
@@ -128,28 +146,60 @@ All capture methods accept an `options` object:
128
146
  | `fast` | boolean | `true` | Skips idle delay for faster results |
129
147
  | `embedFonts` | boolean | `false` | Inlines fonts (icon fonts always embedded) |
130
148
  | `scale` | number | `1` | Output scale multiplier |
149
+ | `width` | number | - | Output specific width size |
150
+ | `height` | number | - | Output specific height size |
131
151
  | `backgroundColor` | string | `"#fff"` | Fallback color for JPG/WebP |
132
152
  | `quality` | number | `1` | Quality for JPG/WebP (0 to 1) |
133
- | `crossOrigin` | function | - | Function to determine CORS mode per image URL |
153
+ | `useProxy` | string | '' | Specify a proxy for handling CORS images as fallback|
154
+
155
+ ### Setting custom dimensions with width and height options
156
+
157
+ Use the `width` and `height` options to generate an image with specific dimensions.
158
+
159
+ **Examples:**
160
+
161
+ **1. Fixed width (proportional height)**
162
+ Sets a specific width while maintaining the aspect ratio. Height adjusts proportionally.
163
+
164
+ ```js
165
+ const result = await snapdom(element, {
166
+ width: 400 // Outputs a 400px-wide image with auto-scaled height
167
+ });
168
+ ```
169
+
170
+ **2. Fixed height (proportional width)**
171
+ Sets a specific height while maintaining the aspect ratio. Width adjusts proportionally.
172
+
173
+ ```js
174
+ const result = await snapdom(element, {
175
+ height: 200 // Outputs a 200px-tall image with auto-scaled width
176
+ });
177
+ ```
178
+
179
+ **3. Fixed width and height (may distort image)**
180
+ Forces exact dimensions, potentially distorting the image if the aspect ratio differs.
181
+
182
+ ```js
183
+ const result = await snapdom(element, {
184
+ width: 800, // Outputs an 800px × 200px image (may stretch/squish content)
185
+ height: 200
186
+ });
187
+ ```
188
+
189
+ **Note:** If `scale` is different from 1, it takes priority over width and height.
190
+ Example: `{ scale: 3, width: 500 }` ignores width and scales the image 3x instead.
191
+
134
192
 
135
193
  ### Cross-Origin Images
136
194
 
137
- By default, snapDOM loads images with `crossOrigin="anonymous"`. You can customize this behavior using the `crossOrigin` option:
195
+ By default, snapDOM loads images with `crossOrigin="anonymous"` or `crossOrigin="use-credentials"`. In case fails to get the images, `useProxy` can be used to deal with CORS images:
138
196
 
139
197
  ```js
140
198
  const result = await snapdom(element, {
141
- crossOrigin: (url) => {
142
- // Use credentials for same-origin images
143
- if (url.startsWith(window.location.origin)) {
144
- return "use-credentials";
145
- }
146
- // Use anonymous for cross-origin images
147
- return "anonymous";
148
- }
199
+ useProxy: 'your/proxy/' //Example: 'https://corsproxy.io/?url=' or 'https://api.allorigins.win/raw?url='
149
200
  });
150
201
  ```
151
202
 
152
- This is useful when your images require authentication or when dealing with credentialed requests.
153
203
 
154
204
  ### Download options
155
205
 
@@ -184,13 +234,13 @@ import { snapdom, preCache } from './snapdom.mjs';
184
234
 
185
235
  * `embedFonts` *(boolean, default: true)* — Inlines non-icon fonts during preload.
186
236
  * `reset` *(boolean, default: false)* — Clears all existing internal caches.
187
- * `crossOrigin` *(function)* — Function to determine CORS mode per image URL during preload.
237
+ * `useProxy` *(string)* — Proxy for handling CORS images as fallback.
188
238
 
189
239
 
190
240
  ## Features
191
241
 
192
242
  * Captures **shadow DOM** and Web Components
193
- * Supports `::before` and `::after` pseudo-elements
243
+ * Supports `::before`, `::after` and `::first-letter` pseudo-elements
194
244
  * Inlines background images and fonts
195
245
  * Handles **Font Awesome**, **Material Icons**, and more
196
246
  * `data-capture="exclude"` to ignore an element
@@ -198,30 +248,58 @@ import { snapdom, preCache } from './snapdom.mjs';
198
248
 
199
249
  ## Limitations
200
250
 
201
- * External images must be CORS-accessible (use `crossOrigin` option for credentialed requests)
251
+ * External images shloud be CORS-accessible (use `useProxy` option for handling CORS denied)
202
252
  * Iframes are not supported
203
253
  * When WebP format is used on Safari, it will fallback to PNG rendering.
204
254
  * `@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)
205
255
 
206
- ## Benchmarks
207
256
 
208
- `snapDOM` is not only highly accurate — it’s **extremely fast**.
257
+ ## ⚡ Performance Benchmarks
209
258
 
259
+ Snapdom has received **major performance improvements** since version `v1.8.0`. Below are benchmark results comparing:
210
260
 
211
- Latest benchmarks show significant performance improvements against other libraries:
261
+ * 🔷 **Snapdom (current)**
262
+ * 🔸 **Snapdom v1.8.0**
263
+ * 🟥 `html2canvas`
264
+ * 🟨 `modern-screenshot`
212
265
 
213
- | Scenario | vs. `modern-screenshot` | vs. `html2canvas` |
214
- | -------------------------------- | :---------------------: | :---------------: |
215
- | Small element (200×100) | 6.46× faster | 32.27× faster |
216
- | Modal size (400×300) | 7.28× faster | 32.66× faster |
217
- | Page view (1200×800) | 13.17× faster | 35.29× faster |
218
- | Large scroll area (2000×1500) | 38.23× faster | 68.85× faster |
219
- | Very large element (4000×2000) | 93.31× faster | 133.12× faster |
220
- | Complex small element (200×100) | 3.97× faster | 15.23× faster |
221
- | Complex modal (400×300) | 2.32× faster | 5.33× faster |
222
- | Complex page (1200×800) | 1.62× faster | 1.65× faster |
223
- | Complex large scroll (2000×1500) | 1.66× faster | 1.24× faster |
224
- | Complex very large (4000×2000) | 1.52× faster | 1.28× faster |
266
+ Each benchmark shows the **fastest observed time** (lower is better), measured in **milliseconds (ms)**.
267
+
268
+ ---
269
+
270
+ ### Simple elements
271
+
272
+ | Scenario | Snapdom (current) | Snapdom v1.8.0 | html2canvas | modern-screenshot |
273
+ | ------------------------ | ----------------- | -------------- | ----------- | ----------------- |
274
+ | Small (200×100) | **0.4 ms** | 1.2 ms | 70.3 ms | 11.9 ms |
275
+ | Modal (400×300) | **0.4 ms** | 1.1 ms | 68.8 ms | 14.1 ms |
276
+ | Page View (1200×800) | **0.4 ms** | 1.0 ms | 100.5 ms | 34.2 ms |
277
+ | Large Scroll (2000×1500) | **0.4 ms** | 1.0 ms | 153.1 ms | 77.8 ms |
278
+ | Very Large (4000×2000) | **0.4 ms** | 1.0 ms | 278.9 ms | 194.7 ms |
279
+
280
+ ---
281
+
282
+ ### Complex elements
283
+
284
+ | Scenario | Snapdom (current) | Snapdom v1.8.0 | html2canvas | modern-screenshot |
285
+ | ------------------------ | ----------------- | -------------- | ----------- | ----------------- |
286
+ | Small (200×100) | **1.1 ms** | 3.2 ms | 72.5 ms | 16.1 ms |
287
+ | Modal (400×300) | **4.5 ms** | 14.0 ms | 90.1 ms | 34.6 ms |
288
+ | Page View (1200×800) | **32.9 ms** | 113.6 ms | 196.1 ms | 181.1 ms |
289
+ | Large Scroll (2000×1500) | **133.9 ms** | 387.4 ms | 446.6 ms | 635.9 ms |
290
+ | Very Large (4000×2000) | **364.0 ms** | 1,200.4 ms | 1,275.4 ms | 1,685.6 ms |
291
+
292
+ ---
293
+
294
+ ### Summary
295
+
296
+ * Snapdom (current) is consistently **2×–4× faster** than `v1.8.0`
297
+ * Up to **500× faster** than `html2canvas`
298
+ * Also significantly faster than `modern-screenshot`, especially for large DOMs
299
+
300
+ <sub>All benchmarks were run in Chromium using Vitest.<br>
301
+ Tests were performed on a 2018 MacBook Air.<br>
302
+ ⚠️ Performance can be even better on more modern hardware.</sub>
225
303
 
226
304
 
227
305
  ### Run the benchmarks
@@ -237,11 +315,53 @@ npm run test:benchmark
237
315
 
238
316
  They execute in **headless Chromium** using real DOM nodes.
239
317
 
318
+ ## Development
319
+
320
+ To contribute or build snapDOM locally:
321
+
322
+ ```sh
323
+ # Clone the repository
324
+ git clone https://github.com/zumerlab/snapdom.git
325
+ cd snapdom
326
+
327
+ # Install dependencies
328
+ npm install
329
+
330
+ # Compile the library (ESM, CJS, and minified versions)
331
+ npm run compile
332
+
333
+ # Run tests
334
+ npm test
335
+
336
+ # Run Benchmarks
337
+ npm run test:benchmark
338
+ ```
339
+
340
+ The main entry point is in `src/`, and output bundles are generated in the `dist/` folder.
341
+
342
+ For detailed contribution guidelines, please see [CONTRIBUTING](https://github.com/zumerlab/snapdom/blob/main/CONTRIBUTING.md).
343
+
344
+
240
345
  ## Contributors 🙌
241
346
 
242
- <a href="https://github.com/zumerlab/snapdom/graphs/contributors">
243
- <img src="https://contrib.rocks/image?repo=zumerlab/snapdom" />
244
- </a>
347
+ <!-- CONTRIBUTORS:START -->
348
+ <p>
349
+ <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>
350
+ <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>
351
+ <a href="https://github.com/pedrocateexte" title="pedrocateexte"><img src="https://avatars.githubusercontent.com/u/207524750?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="pedrocateexte"/></a>
352
+ <a href="https://github.com/domialex" title="domialex"><img src="https://avatars.githubusercontent.com/u/4694217?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="domialex"/></a>
353
+ <a href="https://github.com/elliots" title="elliots"><img src="https://avatars.githubusercontent.com/u/622455?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="elliots"/></a>
354
+ <a href="https://github.com/jswhisperer" title="jswhisperer"><img src="https://avatars.githubusercontent.com/u/1177690?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="jswhisperer"/></a>
355
+ <a href="https://github.com/simon1uo" title="simon1uo"><img src="https://avatars.githubusercontent.com/u/60037549?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="simon1uo"/></a>
356
+ <a href="https://github.com/jhbae200" title="jhbae200"><img src="https://avatars.githubusercontent.com/u/20170610?v=4&s=100" style="border-radius:10px; width:60px; height:60px; object-fit:cover; margin:5px;" alt="jhbae200"/></a>
357
+ </p>
358
+ <!-- CONTRIBUTORS:END -->
359
+
360
+ ## 💖 Sponsors
361
+
362
+ Special thanks to [@megaphonecolin](https://github.com/megaphonecolin) for supporting this project!
363
+
364
+ If you'd like to support this project too, you can [become a sponsor](https://github.com/sponsors/tinchox5).
245
365
 
246
366
  ## License
247
367