wasm-html-to-image 1.0.5 → 1.0.7
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 +121 -147
- package/dist/core-orchestrate.js +6 -2
- package/dist/core-resources.d.ts +1 -0
- package/dist/core-resources.js +5 -2
- package/dist/core.d.ts +1 -1
- package/dist/core.js +2 -2
- package/dist/html-to-image-wasm.js +3 -3
- package/dist/html-to-image.wasm +0 -0
- package/dist/web-workers.js +5 -5
- package/dist/workers-parent.js +2 -2
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -7,27 +7,36 @@
|
|
|
7
7
|
[](https://sorakumo001.github.io/wasm-html-to-image/master/docs/)
|
|
8
8
|
[](https://github.com/SoraKumo001/wasm-html-to-image-samples)
|
|
9
9
|
|
|
10
|
-
A high-performance
|
|
10
|
+
A high-performance HTML-to-image renderer and image processing engine powered by a single WebAssembly module.
|
|
11
11
|
|
|
12
|
-
No
|
|
12
|
+
**No Chromium / Puppeteer.** **No native dependencies (Sharp / ImageMagick).**
|
|
13
|
+
Runs seamlessly across **Node.js**, **Cloudflare Workers**, **Edge runtimes**, **browsers**, and the **CLI**.
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
16
|
-
##
|
|
17
|
+
## ⚡ What Can It Do?
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
| Feature | Description | Formats |
|
|
20
|
+
| :--- | :--- | :--- |
|
|
21
|
+
| 🌐 **HTML / React to Image** | Render HTML/CSS strings or React components directly | PNG, JPEG, WebP, AVIF, JXL, SVG |
|
|
22
|
+
| 🔗 **URL to Screenshot** | Capture remote web pages without launching a browser | PNG, WebP, JPEG, AVIF |
|
|
23
|
+
| 📑 **Multi-Page Vector PDF** | Generate crisp, selectable vector PDFs from HTML or images | PDF |
|
|
24
|
+
| 🖼️ **Image Resizing & Optimization** | Fast format conversion, crop, and resize (Sharp alternative) | WebP, AVIF, JXL, PNG, JPEG |
|
|
25
|
+
| 🎬 **CSS Animation to WebP / GIF** | Record CSS `@keyframes` animations into animated images | Animated WebP, APNG, GIF |
|
|
26
|
+
| 🪶 **ThumbHash Blur Placeholder** | Generate compact blur placeholders for instant progressive loading | ThumbHash |
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
Supports vertical writing mode and CSS animations:
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<img src="./doc/image01.webp" alt="Vertical writing mode and animation preview" width="100%" />
|
|
33
|
+
</p>
|
|
25
34
|
|
|
26
35
|
---
|
|
27
36
|
|
|
28
37
|
## 📦 Installation
|
|
29
38
|
|
|
30
|
-
```bash
|
|
39
|
+
```bash
|
|
31
40
|
npm install wasm-html-to-image
|
|
32
41
|
```
|
|
33
42
|
|
|
@@ -35,151 +44,122 @@ npm install wasm-html-to-image
|
|
|
35
44
|
|
|
36
45
|
## 🚀 Quick Start
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
The easiest way to get started. WASM is embedded and loaded automatically (in Cloudflare Workers, the workerd-optimized module is automatically selected):
|
|
47
|
+
One single function — `render()` — handles all HTML rendering, URL capturing, and image processing:
|
|
41
48
|
|
|
42
49
|
```typescript
|
|
43
50
|
import { render } from "wasm-html-to-image";
|
|
44
51
|
|
|
45
|
-
// 1. Render HTML to PNG
|
|
52
|
+
// 1. Render HTML to PNG / WebP / AVIF
|
|
46
53
|
const result = await render({
|
|
47
|
-
value: `<div style="
|
|
48
|
-
<h1 style="margin: 0;
|
|
49
|
-
<p
|
|
54
|
+
value: `<div style="padding: 40px; background: #6366f1; color: white; border-radius: 12px; font-family: sans-serif;">
|
|
55
|
+
<h1 style="margin: 0;">Hello wasm-html-to-image</h1>
|
|
56
|
+
<p>High-performance serverless rendering</p>
|
|
50
57
|
</div>`,
|
|
51
58
|
width: 800,
|
|
52
59
|
format: "png",
|
|
53
60
|
});
|
|
54
|
-
|
|
55
61
|
console.log(result.data); // Uint8Array
|
|
56
62
|
console.log(result.width, result.height); // 800, 600
|
|
57
63
|
|
|
58
|
-
// 2.
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
width:
|
|
64
|
+
// 2. Capture a URL screenshot
|
|
65
|
+
const screenshot = await render({
|
|
66
|
+
url: "https://example.com",
|
|
67
|
+
width: 1200,
|
|
68
|
+
height: 630,
|
|
62
69
|
format: "webp",
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// 3. Convert & Resize an image (JPEG -> AVIF)
|
|
73
|
+
const avif = await render({
|
|
74
|
+
value: imageBuffer, // Pass raw Uint8Array / Buffer directly
|
|
75
|
+
width: 400,
|
|
76
|
+
format: "avif",
|
|
63
77
|
quality: 80,
|
|
64
78
|
});
|
|
65
79
|
|
|
66
|
-
|
|
67
|
-
|
|
80
|
+
// 4. Record CSS Animation -> Animated WebP / GIF / APNG
|
|
81
|
+
const animated = await render({
|
|
82
|
+
value: `<style>
|
|
83
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
84
|
+
.box { width: 100px; height: 100px; background: red; animation: spin 2s linear infinite; }
|
|
85
|
+
</style><div class="box"></div>`,
|
|
86
|
+
format: "webp",
|
|
87
|
+
animation: 2000, // duration in ms
|
|
88
|
+
animationFps: 20,
|
|
89
|
+
});
|
|
68
90
|
```
|
|
69
91
|
|
|
70
92
|
---
|
|
71
93
|
|
|
72
|
-
##
|
|
73
|
-
|
|
74
|
-
`wasm-html-to-image` is not only an HTML renderer — it also serves as a high-speed, self-contained **image-to-image converter, resizer, and compressor** without requiring heavy native libraries like Sharp or ImageMagick.
|
|
75
|
-
|
|
76
|
-
Simply pass raw image bytes (`Uint8Array` or `Buffer`) or a `data:image/...` URL to `render()`. It automatically identifies input magic bytes, skips the HTML layout pass, and routes straight into the native Skia image pipeline. Every call returns rich metadata (`width`, `height`, `originalWidth`, `originalHeight`, `format`, `isAnimated`) along with the output data in `.data`:
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
import fs from "node:fs/promises";
|
|
80
|
-
import { render } from "wasm-html-to-image/single";
|
|
81
|
-
|
|
82
|
-
const imageBuffer = await fs.readFile("photo.jpg");
|
|
94
|
+
## 💻 CLI Usage
|
|
83
95
|
|
|
84
|
-
|
|
85
|
-
const avif = await render({
|
|
86
|
-
value: imageBuffer,
|
|
87
|
-
width: 800,
|
|
88
|
-
format: "avif",
|
|
89
|
-
quality: 75,
|
|
90
|
-
speed: 6, // 0 (best quality) - 10 (fastest). AVIF default is 8; 6 trades time for ~15-20% smaller files
|
|
91
|
-
});
|
|
92
|
-
await fs.writeFile("photo.avif", Buffer.from(avif.data));
|
|
96
|
+
Render from your terminal without writing code:
|
|
93
97
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
crop: { x: 50, y: 50, width: 300, height: 300 },
|
|
98
|
-
width: 150,
|
|
99
|
-
height: 150,
|
|
100
|
-
format: "png",
|
|
101
|
-
});
|
|
102
|
-
await fs.writeFile("cropped.png", Buffer.from(cropped.data));
|
|
98
|
+
```bash
|
|
99
|
+
# Render HTML to WebP
|
|
100
|
+
npx wasm-html-to-image template.html -o banner.webp -w 1200 -h 630 -f webp -q 90
|
|
103
101
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
value: imageBuffer,
|
|
107
|
-
width: 100,
|
|
108
|
-
format: "thumbhash",
|
|
109
|
-
});
|
|
110
|
-
console.log("ThumbHash bytes:", thumbhash.data);
|
|
102
|
+
# Capture screenshot from URL
|
|
103
|
+
npx wasm-html-to-image https://example.com -o site.png -w 1280 -h 720
|
|
111
104
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
value: imageBuffer,
|
|
115
|
-
format: "pdf",
|
|
116
|
-
});
|
|
117
|
-
await fs.writeFile("photo.pdf", Buffer.from(pdf.data));
|
|
105
|
+
# Convert and resize an image (JPEG -> AVIF)
|
|
106
|
+
npx wasm-html-to-image photo.jpg -o photo.avif -w 800 -f avif -q 80
|
|
118
107
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
format: "webp",
|
|
123
|
-
animation: true,
|
|
124
|
-
});
|
|
125
|
-
await fs.writeFile("animation.webp", Buffer.from(animatedWebp.data));
|
|
108
|
+
# Convert CSS animation into Animated WebP or GIF
|
|
109
|
+
npx wasm-html-to-image loader.html -o loader.webp -f webp --animation 2000 --animation-fps 20
|
|
110
|
+
npx wasm-html-to-image loader.html -o loader.gif -f gif --animation 2000
|
|
126
111
|
```
|
|
127
112
|
|
|
128
113
|
---
|
|
129
114
|
|
|
130
|
-
## 📊
|
|
115
|
+
## 📊 Supported Formats
|
|
131
116
|
|
|
132
117
|
### Inputs (`value` / `url`)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
| **HTML Array (`string[]`)** | Array of HTML strings | Multi-page PDF generation (one page per item) |
|
|
138
|
-
| **URL (`url`)** | `http://` or `https://` | Automatically fetches and renders remote web pages |
|
|
139
|
-
| **Image Buffer** | `Uint8Array` / `Buffer` | Magic-byte recognition for PNG, JPEG, WebP, GIF, AVIF, BMP |
|
|
140
|
-
| **Data URL** | `data:image/*;base64,...` | Inlined image data URL, routed straight to image pipeline |
|
|
118
|
+
- **HTML String**: Standard HTML & CSS (Flexbox, Grid, gradients, custom fonts, `@keyframes`).
|
|
119
|
+
- **HTML Array (`string[]`)**: Multi-page PDF generation (one page per array item).
|
|
120
|
+
- **URL (`url`)**: Automatically fetches and renders remote web pages.
|
|
121
|
+
- **Image Buffer / Data URL**: `PNG`, `JPEG`, `WebP`, `GIF`, `AVIF`, `JXL`, `BMP`.
|
|
141
122
|
|
|
142
123
|
### Outputs (`format`)
|
|
124
|
+
`png`, `jpeg`, `webp`, `avif`, `jxl`, `apng`, `gif`, `svg`, `pdf`, `thumbhash`, `raw` (uncompressed RGBA).
|
|
143
125
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
| `pdf` | `Uint8Array` | SkPDFDocument vector PDF | Single-page centered PDF |
|
|
126
|
+
Every call returns a `RenderResult` object:
|
|
127
|
+
```typescript
|
|
128
|
+
interface RenderResult {
|
|
129
|
+
data: Uint8Array | string; // Binary bytes (or string for SVG)
|
|
130
|
+
width: number;
|
|
131
|
+
height: number;
|
|
132
|
+
originalWidth: number;
|
|
133
|
+
originalHeight: number;
|
|
134
|
+
format: string;
|
|
135
|
+
isAnimated: boolean;
|
|
136
|
+
}
|
|
137
|
+
```
|
|
157
138
|
|
|
158
139
|
---
|
|
159
140
|
|
|
160
|
-
##
|
|
141
|
+
## 🌐 Environments & Subpaths
|
|
161
142
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
|
165
|
-
|
|
|
166
|
-
| `wasm-html-to-image`
|
|
167
|
-
| `wasm-html-to-image/
|
|
168
|
-
| `wasm-html-to-image/
|
|
169
|
-
| `wasm-html-to-image/
|
|
170
|
-
| `wasm-html-to-image/
|
|
171
|
-
| `wasm-html-to-image/
|
|
172
|
-
| `wasm-html-to-image/
|
|
173
|
-
| `wasm-html-to-image/preact` | Preact integration | Directly render Preact JSX element trees |
|
|
174
|
-
| `wasm-html-to-image/tailwind` | Utility styling | Inlines UnoCSS / Tailwind classes |
|
|
143
|
+
| Subpath | Target Environment | Highlights |
|
|
144
|
+
| :--- | :--- | :--- |
|
|
145
|
+
| `wasm-html-to-image` | Universal (Node, Edge, Cloudflare, Deno) | **Zero-config default**: auto-routes to single or workerd |
|
|
146
|
+
| `wasm-html-to-image/single` | Node.js, Bundlers | Single bundled WASM binary |
|
|
147
|
+
| `wasm-html-to-image/index` | High-throughput servers | Explicit `loadHtmlToImageModule()` & instance reuse |
|
|
148
|
+
| `wasm-html-to-image/workerd` | Cloudflare Workers | Optimized for `WebAssembly.Module` compilation |
|
|
149
|
+
| `wasm-html-to-image/edge-light` | Vercel Edge Runtime | Tailored for strict Edge constraints |
|
|
150
|
+
| `wasm-html-to-image/workers` | Node.js, Web Workers | Multi-threaded worker pool for high concurrency |
|
|
151
|
+
| `wasm-html-to-image/react` | React integration | Directly render React JSX element trees |
|
|
152
|
+
| `wasm-html-to-image/preact` | Preact integration | Directly render Preact JSX element trees |
|
|
153
|
+
| `wasm-html-to-image/tailwind` | Utility styling | UnoCSS / Tailwind v4 utilities (`createCSS`, `tailwind()`) |
|
|
175
154
|
|
|
176
155
|
---
|
|
177
156
|
|
|
178
|
-
## 💡
|
|
157
|
+
## 💡 Advanced Examples
|
|
179
158
|
|
|
180
|
-
|
|
159
|
+
<details>
|
|
160
|
+
<summary><b>1. High-Throughput Node.js Server (Module Instance Reuse)</b></summary>
|
|
181
161
|
|
|
182
|
-
Reuse the WASM module across incoming HTTP requests for maximum performance:
|
|
162
|
+
Reuse the compiled WASM module across incoming HTTP requests for maximum performance:
|
|
183
163
|
|
|
184
164
|
```typescript
|
|
185
165
|
import { loadHtmlToImageModule, htmlToImage } from "wasm-html-to-image";
|
|
@@ -202,19 +182,13 @@ app.get("/ogp", async (req, res) => {
|
|
|
202
182
|
|
|
203
183
|
app.listen(3000);
|
|
204
184
|
```
|
|
185
|
+
</details>
|
|
205
186
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
Generate dynamic social preview images at the edge:
|
|
187
|
+
<details>
|
|
188
|
+
<summary><b>2. Cloudflare Workers (Edge OGP Generator)</b></summary>
|
|
209
189
|
|
|
210
190
|
```typescript
|
|
211
|
-
|
|
212
|
-
// `import ... from "*.wasm"` is bundled as WebAssembly.Module by default.
|
|
213
|
-
// Minimal wrangler.jsonc: { "main": "src/index.ts", "compatibility_date": "2026-09-01" }
|
|
214
|
-
// (Only configure "rules" yourself if you customize bundling rules or use a very old Wrangler.
|
|
215
|
-
// Note: @cloudflare/vite-plugin ignores "rules".)
|
|
216
|
-
|
|
217
|
-
import { render } from "wasm-html-to-image"; // auto-selects the workerd build on Cloudflare ("wasm-html-to-image/workerd" also works)
|
|
191
|
+
import { render } from "wasm-html-to-image"; // auto-selects the workerd build
|
|
218
192
|
|
|
219
193
|
export default {
|
|
220
194
|
async fetch(request: Request): Promise<Response> {
|
|
@@ -236,10 +210,12 @@ export default {
|
|
|
236
210
|
},
|
|
237
211
|
};
|
|
238
212
|
```
|
|
213
|
+
</details>
|
|
239
214
|
|
|
240
|
-
|
|
215
|
+
<details>
|
|
216
|
+
<summary><b>3. Multi-Threaded Batch Generation (`workers`)</b></summary>
|
|
241
217
|
|
|
242
|
-
Leverage multi-core CPUs to
|
|
218
|
+
Leverage multi-core CPUs with worker threads to render hundreds of images in parallel:
|
|
243
219
|
|
|
244
220
|
```typescript
|
|
245
221
|
import { render } from "wasm-html-to-image/workers";
|
|
@@ -255,38 +231,36 @@ const tasks = items.map((item) =>
|
|
|
255
231
|
|
|
256
232
|
const images = await Promise.all(tasks);
|
|
257
233
|
```
|
|
234
|
+
</details>
|
|
258
235
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
Render directly from your shell without writing code:
|
|
262
|
-
|
|
263
|
-
```bash
|
|
264
|
-
# Render HTML to WebP
|
|
265
|
-
npx wasm-html-to-image template.html -o banner.webp -w 1200 -h 630 -f webp -q 90
|
|
266
|
-
|
|
267
|
-
# Capture screenshot from URL
|
|
268
|
-
npx wasm-html-to-image https://example.com -o site.png -w 1280 -h 720
|
|
269
|
-
|
|
270
|
-
# Pin the base for relative resources (default: URL input follows redirects,
|
|
271
|
-
# file input uses the file's own directory)
|
|
272
|
-
npx wasm-html-to-image https://example.com/news -o news.png --base-url https://example.com/
|
|
236
|
+
<details>
|
|
237
|
+
<summary><b>4. Image Cropping & ThumbHash</b></summary>
|
|
273
238
|
|
|
274
|
-
|
|
275
|
-
|
|
239
|
+
```typescript
|
|
240
|
+
import { render } from "wasm-html-to-image";
|
|
276
241
|
|
|
277
|
-
|
|
278
|
-
|
|
242
|
+
// Crop and resize
|
|
243
|
+
const cropped = await render({
|
|
244
|
+
value: imageBuffer,
|
|
245
|
+
crop: { x: 50, y: 50, width: 300, height: 300 },
|
|
246
|
+
width: 150,
|
|
247
|
+
height: 150,
|
|
248
|
+
format: "png",
|
|
249
|
+
});
|
|
279
250
|
|
|
280
|
-
|
|
281
|
-
|
|
251
|
+
// Generate ThumbHash blur placeholder
|
|
252
|
+
const thumbhash = await render({
|
|
253
|
+
value: imageBuffer,
|
|
254
|
+
width: 100,
|
|
255
|
+
format: "thumbhash",
|
|
256
|
+
});
|
|
282
257
|
```
|
|
258
|
+
</details>
|
|
283
259
|
|
|
284
260
|
---
|
|
285
261
|
|
|
286
262
|
## 📖 Documentation & Examples
|
|
287
263
|
|
|
288
|
-
For full guides, architecture deep-dives, font management, and advanced recipes:
|
|
289
|
-
|
|
290
264
|
👉 **[Read the Official Documentation](https://sorakumo001.github.io/wasm-html-to-image/master/docs/)**
|
|
291
265
|
👉 **[Sample Code & Projects (GitHub)](https://github.com/SoraKumo001/wasm-html-to-image-samples)**
|
|
292
266
|
|
package/dist/core-orchestrate.js
CHANGED
|
@@ -14,7 +14,7 @@ import { pdfFirstPageSize, svgRootHeight } from "./output-size.js";
|
|
|
14
14
|
import { FIT_INT, FORMAT_INT } from "./encode-args.js";
|
|
15
15
|
import { imageBytesFromUnknown, toBytes, } from "./input.js";
|
|
16
16
|
import { DIAGNOSTIC_CODES, LogLevel, } from "./diagnostics.js";
|
|
17
|
-
import { now, resolveHtmlResources, } from "./core-resources.js";
|
|
17
|
+
import { isNodeRuntime, now, resolveHtmlResources, } from "./core-resources.js";
|
|
18
18
|
const DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
|
|
19
19
|
export { DEFAULT_USER_AGENT };
|
|
20
20
|
export function requireBindingError(name) {
|
|
@@ -193,7 +193,11 @@ export async function resolveHtmlSource(orch) {
|
|
|
193
193
|
return value;
|
|
194
194
|
}
|
|
195
195
|
if (typeof url === "string") {
|
|
196
|
-
|
|
196
|
+
// Same as resource fetch: User-Agent override is Node-only. In browsers
|
|
197
|
+
// it is forbidden and triggers a Firefox preflight that breaks CORS.
|
|
198
|
+
const headers = isNodeRuntime()
|
|
199
|
+
? { "User-Agent": userAgent ?? DEFAULT_USER_AGENT }
|
|
200
|
+
: undefined;
|
|
197
201
|
const fetchStart = now();
|
|
198
202
|
// Post-redirect document URL (`Response.url`). Relative resources must
|
|
199
203
|
// resolve against the final URL, not the stale request URL: a 301 to a new
|
package/dist/core-resources.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { type HtmlToImageModule } from "./loader.js";
|
|
|
10
10
|
import { LogLevel, type DiagnosticMessage, type FontDiagnostic, type RenderLimits, type ResolveResourceHook, type ResourceDiagnostic } from "./diagnostics.js";
|
|
11
11
|
/** Drop every cached resource (e.g. after the source assets changed). */
|
|
12
12
|
export declare function clearResourceCache(): void;
|
|
13
|
+
export declare function isNodeRuntime(): boolean;
|
|
13
14
|
/**
|
|
14
15
|
* Fetch external resource bytes. `data:` URLs resolve inline in C++
|
|
15
16
|
* (`request()`), so they are skipped here. Relative URLs resolve against
|
package/dist/core-resources.js
CHANGED
|
@@ -56,7 +56,7 @@ const resourceCache = new ResourceCache();
|
|
|
56
56
|
export function clearResourceCache() {
|
|
57
57
|
resourceCache.clear();
|
|
58
58
|
}
|
|
59
|
-
function isNodeRuntime() {
|
|
59
|
+
export function isNodeRuntime() {
|
|
60
60
|
const proc = globalThis
|
|
61
61
|
.process;
|
|
62
62
|
return typeof proc?.versions?.node === "string";
|
|
@@ -102,7 +102,10 @@ async function isInsideDir(fs, path, root, target) {
|
|
|
102
102
|
}
|
|
103
103
|
/** Built-in resolution behind the `resolveResource` hook (see above). */
|
|
104
104
|
async function fetchResourceBytesInner(url, baseUrl, userAgent, timeoutMs, confineFiles) {
|
|
105
|
-
|
|
105
|
+
// Browser fetch forbids overriding User-Agent (and Firefox preflights it,
|
|
106
|
+
// breaking Google Fonts/jsDelivr CORS). Spoof only in Node where we
|
|
107
|
+
// control the UA to get woff2 CSS.
|
|
108
|
+
const headers = userAgent && isNodeRuntime() ? { "User-Agent": userAgent } : undefined;
|
|
106
109
|
// Abort hung connections so one stalled server cannot outlive `timeoutMs`.
|
|
107
110
|
const signal = timeoutMs !== undefined
|
|
108
111
|
? AbortSignal.timeout(Math.max(1, timeoutMs))
|
package/dist/core.d.ts
CHANGED
|
@@ -63,7 +63,7 @@ export interface RenderOptions {
|
|
|
63
63
|
export interface HtmlToImageOptions extends RenderOptions {
|
|
64
64
|
/** Encode quality 0-100 (encode stage only, default 85; ignored for svg/pdf). */
|
|
65
65
|
quality?: number;
|
|
66
|
-
/** Encode speed 0-10
|
|
66
|
+
/** Encode speed 0-10 for AVIF, JXL and animated (lossy) WebP (encode stage only; default 8 for AVIF, 6 otherwise). Animated WebP uses libwebp method `8 - speed`: the default 6 is method 2, 5 is method 3 (Skia's, smaller by ~4%), 9 is method 0 (fastest, ~30% larger). */
|
|
67
67
|
speed?: number;
|
|
68
68
|
/**
|
|
69
69
|
* Animation handling.
|
package/dist/core.js
CHANGED
|
@@ -15,8 +15,8 @@ const EMOJI_URL = "https://cdn.jsdelivr.net/npm/@fontsource/noto-color-emoji/fil
|
|
|
15
15
|
* UA so woff2 is served); fetched at render time, nothing bundled.
|
|
16
16
|
*/
|
|
17
17
|
export const DEFAULT_FONT_MAP = {
|
|
18
|
-
"sans-serif": "https://fonts.googleapis.com/css2?family=Noto+Sans+JP",
|
|
19
|
-
serif: "https://fonts.googleapis.com/css2?family=Noto+Serif+JP",
|
|
18
|
+
"sans-serif": "https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900",
|
|
19
|
+
serif: "https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@200..900",
|
|
20
20
|
monospace: "https://fonts.googleapis.com/css2?family=M+PLUS+1+Code",
|
|
21
21
|
cursive: "https://fonts.googleapis.com/css2?family=Yuji+Syuku",
|
|
22
22
|
fantasy: "https://fonts.googleapis.com/css2?family=Reggae+One",
|