@zumer/snapdom 1.9.9 → 1.9.10-dev.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/README.md +123 -84
- package/dist/snapdom.js +1511 -805
- package/dist/snapdom.min.js +5 -3
- package/dist/snapdom.min.mjs +5 -3
- package/dist/snapdom.mjs +1484 -759
- package/package.json +1 -1
- package/types/snapdom.d.ts +171 -60
package/README.md
CHANGED
|
@@ -89,10 +89,9 @@ import { snapdom } from './snapdom.mjs';
|
|
|
89
89
|
## Basic usage
|
|
90
90
|
|
|
91
91
|
### Reusable capture
|
|
92
|
-
|
|
93
92
|
```js
|
|
94
93
|
const el = document.querySelector('#target');
|
|
95
|
-
const result = await snapdom(el
|
|
94
|
+
const result = await snapdom(el);
|
|
96
95
|
|
|
97
96
|
const img = await result.toPng();
|
|
98
97
|
document.body.appendChild(img);
|
|
@@ -101,7 +100,6 @@ await result.download({ format: 'jpg', filename: 'my-capture' });
|
|
|
101
100
|
```
|
|
102
101
|
|
|
103
102
|
### One-step shortcuts
|
|
104
|
-
|
|
105
103
|
```js
|
|
106
104
|
const el = document.querySelector('#target');
|
|
107
105
|
const png = await snapdom.toPng(el);
|
|
@@ -132,132 +130,173 @@ Returns an object with reusable export methods:
|
|
|
132
130
|
|
|
133
131
|
### Shortcut methods
|
|
134
132
|
|
|
135
|
-
| Method | Description
|
|
136
|
-
| ------------------------------ |
|
|
137
|
-
| `snapdom.toImg(el, options?)` | Returns an `HTMLImageElement`
|
|
138
|
-
| `snapdom.toCanvas(el, options?)
|
|
139
|
-
| `snapdom.toBlob(el, options?)` | Returns an SVG `Blob`
|
|
140
|
-
| `snapdom.toPng(el, options?)` | Returns a PNG image
|
|
141
|
-
| `snapdom.toJpg(el, options?)` | Returns a JPG image
|
|
142
|
-
| `snapdom.toWebp(el, options?)` | Returns a WebP image
|
|
143
|
-
| `snapdom.download(el, options?)
|
|
133
|
+
| Method | Description |
|
|
134
|
+
| ------------------------------ | --------------------------------- |
|
|
135
|
+
| `snapdom.toImg(el, options?)` | Returns an `HTMLImageElement` |
|
|
136
|
+
| `snapdom.toCanvas(el, options?)` | Returns a `Canvas` |
|
|
137
|
+
| `snapdom.toBlob(el, options?)` | Returns an SVG or raster `Blob` |
|
|
138
|
+
| `snapdom.toPng(el, options?)` | Returns a PNG image |
|
|
139
|
+
| `snapdom.toJpg(el, options?)` | Returns a JPG image |
|
|
140
|
+
| `snapdom.toWebp(el, options?)` | Returns a WebP image |
|
|
141
|
+
| `snapdom.download(el, options?)` | Triggers a download |
|
|
144
142
|
|
|
145
143
|
## Options
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
| Option | Type | Default | Description |
|
|
150
|
-
| ----------------- | -------- | -------- | ------------------------------------------ |
|
|
151
|
-
| `compress` | boolean | `true` | Removes redundant styles |
|
|
152
|
-
| `fast` | boolean | `true` | Skips idle delay for faster results |
|
|
153
|
-
| `embedFonts` | boolean | `false` | Inlines fonts (icon fonts always embedded) |
|
|
154
|
-
| `localFonts` | array | `[]` | Array of local font descriptors `{ family, src, weight?, style? }` |
|
|
155
|
-
| `iconFonts` | string \| RegExp \| (string \| RegExp)[] | `[]` | Additional icon font families or patterns |
|
|
156
|
-
| `scale` | number | `1` | Output scale multiplier |
|
|
157
|
-
| `dpr` | number | `devicePixelRatio` | Device pixel ratio |
|
|
158
|
-
| `width` | number | - | Output specific width size |
|
|
159
|
-
| `height` | number | - | Output specific height size |
|
|
160
|
-
| `backgroundColor` | string | `"#fff"` | Fallback color for JPG/WebP |
|
|
161
|
-
| `quality` | number | `1` | Quality for JPG/WebP (0 to 1) |
|
|
162
|
-
| `useProxy` | string | '' | Specify a proxy for handling CORS images/fonts as fallback|
|
|
163
|
-
| `type` | string | `svg` | Select `png`, `jpg`, `webp` Blob type|
|
|
164
|
-
| `exclude` | string[] | - | CSS selectors for elements to exclude |
|
|
165
|
-
| `filter` | function | - | Custom filter function ie `(el) => !el.classList.contains('hidden')` |
|
|
166
|
-
|
|
167
|
-
### Setting custom dimensions with width and height options
|
|
168
|
-
|
|
169
|
-
Use the `width` and `height` options to generate an image with specific dimensions.
|
|
145
|
+
> ✅ **Note:** Style compression is now always on internally. The `compress` option has been removed.
|
|
170
146
|
|
|
171
|
-
|
|
147
|
+
All capture methods accept an `options` object:
|
|
172
148
|
|
|
173
|
-
|
|
174
|
-
|
|
149
|
+
| Option | Type | Default | Description |
|
|
150
|
+
| ----------------- | -------- | -------- | ----------------------------------------------- |
|
|
151
|
+
| `fast` | boolean | `true` | Skips small idle delays for faster results |
|
|
152
|
+
| `embedFonts` | boolean | `false` | Inlines non-icon fonts (icon fonts always on) |
|
|
153
|
+
| `localFonts` | array | `[]` | Local fonts `{ family, src, weight?, style? }` |
|
|
154
|
+
| `iconFonts` | string\|RegExp\|Array | `[]` | Extra icon font matchers |
|
|
155
|
+
| `excludeFonts` | object | `{}` | Exclude font families/domains/subsets during embedding |
|
|
156
|
+
| `scale` | number | `1` | Output scale multiplier |
|
|
157
|
+
| `dpr` | number | `devicePixelRatio` | Device pixel ratio |
|
|
158
|
+
| `width` | number | - | Output width |
|
|
159
|
+
| `height` | number | - | Output height |
|
|
160
|
+
| `backgroundColor` | string | `"#fff"` | Fallback color for JPG/WebP |
|
|
161
|
+
| `quality` | number | `1` | Quality for JPG/WebP (0 to 1) |
|
|
162
|
+
| `useProxy` | string | `''` | Proxy base for CORS fallbacks |
|
|
163
|
+
| `type` | string | `svg` | Default Blob type (`svg`\|`png`\|`jpg`\|`webp`) |
|
|
164
|
+
| `exclude` | string[] | - | CSS selectors to exclude |
|
|
165
|
+
| `filter` | function | - | Custom predicate `(el) => boolean` |
|
|
166
|
+
| `cache` | string | `"soft"` | Control internal caches: `disabled`, `soft`, `auto`, `full` |
|
|
167
|
+
|
|
168
|
+
### Dimensions (`scale`, `width`, `height`)
|
|
169
|
+
|
|
170
|
+
* If `scale` is provided, it **takes precedence** over `width`/`height`.
|
|
171
|
+
* If only `width` is provided, height scales proportionally (and vice versa).
|
|
172
|
+
* Providing both `width` and `height` forces an exact size (may distort).
|
|
173
|
+
|
|
174
|
+
### Cross-Origin Images & Fonts (`useProxy`)
|
|
175
|
+
|
|
176
|
+
By default snapDOM tries `crossOrigin="anonymous"` (or `use-credentials` for same-origin). If an asset is CORS-blocked, you can set `useProxy` to a prefix URL that forwards the actual `src`:
|
|
175
177
|
|
|
176
178
|
```js
|
|
177
|
-
|
|
178
|
-
|
|
179
|
+
await snapdom.toPng(el, {
|
|
180
|
+
useProxy: 'your-proxy' // Example 'https://api.allorigins.win/raw?url='
|
|
179
181
|
});
|
|
180
182
|
```
|
|
181
183
|
|
|
182
|
-
**
|
|
183
|
-
|
|
184
|
+
**Tips**
|
|
185
|
+
|
|
186
|
+
* Keep the proxy **fast** and **cache-friendly** (adds big wins on repeated captures).
|
|
187
|
+
* The proxy is only used as a **fallback**; same-origin and CORS-enabled assets skip it.
|
|
188
|
+
|
|
189
|
+
### Fonts
|
|
190
|
+
|
|
191
|
+
#### `embedFonts`
|
|
192
|
+
When `true`, snapDOM embeds **non-icon** `@font-face` rules detected as used within the captured subtree. Icon fonts (Font Awesome, Material Icons, etc.) are embedded **always**.
|
|
193
|
+
|
|
194
|
+
#### `localFonts`
|
|
195
|
+
If you serve fonts yourself or have data URLs, you can declare them here to avoid extra CSS discovery:
|
|
184
196
|
|
|
185
197
|
```js
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
await snapdom.toPng(el, {
|
|
199
|
+
embedFonts: true,
|
|
200
|
+
localFonts: [
|
|
201
|
+
{ family: 'Inter', src: '/fonts/Inter-Variable.woff2', weight: 400, style: 'normal' },
|
|
202
|
+
{ family: 'Inter', src: '/fonts/Inter-Italic.woff2', style: 'italic' }
|
|
203
|
+
]
|
|
188
204
|
});
|
|
189
205
|
```
|
|
190
206
|
|
|
191
|
-
|
|
192
|
-
|
|
207
|
+
#### `iconFonts`
|
|
208
|
+
Add custom icon families (names or regex matchers). Useful for private icon sets:
|
|
193
209
|
|
|
194
210
|
```js
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
height: 200
|
|
211
|
+
await snapdom.toPng(el, {
|
|
212
|
+
iconFonts: ['MyIcons', /^(Remix|Feather) Icons?$/i]
|
|
198
213
|
});
|
|
199
214
|
```
|
|
200
215
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
### Cross-Origin Images
|
|
206
|
-
|
|
207
|
-
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:
|
|
216
|
+
#### `excludeFonts`
|
|
217
|
+
Skip specific non-icon fonts to speed up capture or avoid unnecessary downloads.
|
|
208
218
|
|
|
209
219
|
```js
|
|
210
|
-
|
|
211
|
-
|
|
220
|
+
await snapdom.toPng(el, {
|
|
221
|
+
embedFonts: true,
|
|
222
|
+
excludeFonts: {
|
|
223
|
+
families: ['Noto Serif', 'SomeHeavyFont'], // skip by family name
|
|
224
|
+
domains: ['fonts.gstatic.com', 'cdn.example'], // skip by source host
|
|
225
|
+
subsets: ['cyrillic-ext'] // skip by unicode-range subset tag
|
|
226
|
+
}
|
|
212
227
|
});
|
|
213
228
|
```
|
|
229
|
+
*Notes*
|
|
230
|
+
- `excludeFonts` only applies to **non-icon** fonts. Icon fonts are always embedded.
|
|
231
|
+
- Matching is case-insensitive for `families`. Hosts are matched by substring against the resolved URL.
|
|
214
232
|
|
|
215
233
|
|
|
216
|
-
###
|
|
234
|
+
### Filtering nodes: `exclude` vs `filter`
|
|
217
235
|
|
|
236
|
+
* `exclude`: remove by **selector**.
|
|
237
|
+
* `filter`: advanced predicate per element (return `false` to drop).
|
|
238
|
+
|
|
239
|
+
**Example: filter out elements with `display:none`:**
|
|
218
240
|
```js
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
241
|
+
/**
|
|
242
|
+
* Example filter: skip elements with display:none
|
|
243
|
+
* @param {Element} el
|
|
244
|
+
* @returns {boolean} true = keep, false = exclude
|
|
245
|
+
*/
|
|
246
|
+
function filterHidden(el) {
|
|
247
|
+
const cs = window.getComputedStyle(el);
|
|
248
|
+
if (cs.display === 'none') return false;
|
|
249
|
+
return true;
|
|
223
250
|
}
|
|
224
|
-
```
|
|
225
251
|
|
|
252
|
+
await snapdom.toPng(document.body, { filter: filterHidden });
|
|
253
|
+
```
|
|
226
254
|
|
|
255
|
+
**Example with `exclude`:** remove banners or tooltips by selector
|
|
256
|
+
```js
|
|
257
|
+
await snapdom.toPng(el, {
|
|
258
|
+
exclude: ['.cookie-banner', '.tooltip', '[data-test="debug"]']
|
|
259
|
+
});
|
|
260
|
+
```
|
|
227
261
|
### `preCache()` – Optional helper
|
|
228
262
|
|
|
229
|
-
|
|
263
|
+
Preloads external resources to avoid first-capture stalls (helpful for big/complex trees).
|
|
230
264
|
|
|
231
265
|
```js
|
|
232
266
|
import { preCache } from '@zumer/snapdom';
|
|
233
267
|
|
|
234
|
-
await preCache(
|
|
268
|
+
await preCache({
|
|
269
|
+
root: document.body,
|
|
270
|
+
embedFonts: true,
|
|
271
|
+
localFonts: [{ family: 'Inter', src: '/fonts/Inter.woff2', weight: 400 }],
|
|
272
|
+
useProxy: 'your-proxy'
|
|
273
|
+
});
|
|
235
274
|
```
|
|
236
275
|
|
|
237
|
-
|
|
238
|
-
import { snapdom, preCache } from './snapdom.mjs';
|
|
239
|
-
window.addEventListener('load', async () => {
|
|
240
|
-
await preCache();
|
|
241
|
-
console.log('📦 Resources preloaded');
|
|
242
|
-
});
|
|
243
|
-
```
|
|
276
|
+
### Cache control
|
|
244
277
|
|
|
245
|
-
|
|
278
|
+
SnapDOM maintains internal caches for images, backgrounds, resources, styles, and fonts.
|
|
279
|
+
You can control how they are cleared between captures using the `cache` option:
|
|
246
280
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
281
|
+
| Mode | Description |
|
|
282
|
+
| ----------- | --------------------------------------------------------------------------- |
|
|
283
|
+
| `"disabled"`| No cache: clears absolutely everything on every capture |
|
|
284
|
+
| `"soft"` | Clears session caches (`styleMap`, `nodeMap`, `styleCache`) _(default)_ |
|
|
285
|
+
| `"auto"` | Minimal cleanup: only clears transient maps |
|
|
286
|
+
| `"full"` | Keeps all caches (nothing is cleared, maximum performance) |
|
|
250
287
|
|
|
288
|
+
**Examples:**
|
|
251
289
|
|
|
290
|
+
```js
|
|
291
|
+
// Use minimal but fast cache
|
|
292
|
+
await snapdom.toPng(el, { cache: 'auto' });
|
|
252
293
|
|
|
253
|
-
|
|
294
|
+
// Keep everything in memory between captures
|
|
295
|
+
await snapdom.toPng(el, { cache: 'full' });
|
|
254
296
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
* Handles **Font Awesome**, **Material Icons**, and more
|
|
259
|
-
* `data-capture="exclude"` to ignore an element
|
|
260
|
-
* `data-capture="placeholder"` with `data-placeholder-text` for masked replacements
|
|
297
|
+
// Force a full cleanup on every capture
|
|
298
|
+
await snapdom.toPng(el, { cache: 'disabled' });
|
|
299
|
+
```
|
|
261
300
|
|
|
262
301
|
## Limitations
|
|
263
302
|
|