@meonode/canvas 2.0.0 → 2.0.2

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.
Files changed (118) hide show
  1. package/README.md +272 -256
  2. package/dist/cjs/canvas/canvas.helper.js.map +1 -1
  3. package/dist/cjs/canvas/{chart.canvas.util.js → chart.canvas.js} +23 -23
  4. package/dist/cjs/canvas/chart.canvas.js.map +1 -0
  5. package/dist/cjs/canvas/{grid.canvas.util.js → grid.canvas.js} +4 -4
  6. package/dist/cjs/canvas/grid.canvas.js.map +1 -0
  7. package/dist/cjs/canvas/{image.canvas.util.js → image.canvas.js} +3 -3
  8. package/dist/cjs/canvas/image.canvas.js.map +1 -0
  9. package/dist/cjs/canvas/{layout.canvas.util.js → layout.canvas.js} +18 -11
  10. package/dist/cjs/canvas/layout.canvas.js.map +1 -0
  11. package/dist/cjs/canvas/{root.canvas.util.js → root.canvas.js} +17 -17
  12. package/dist/cjs/canvas/root.canvas.js.map +1 -0
  13. package/dist/cjs/canvas/{text.canvas.util.js → text.canvas.js} +3 -3
  14. package/dist/cjs/canvas/text.canvas.js.map +1 -0
  15. package/dist/cjs/constant/common.const.js.map +1 -1
  16. package/dist/cjs/index.js +17 -17
  17. package/dist/cjs/src/canvas/canvas.helper.d.ts.map +1 -0
  18. package/dist/{esm → cjs/src}/canvas/canvas.type.d.ts +4 -4
  19. package/dist/cjs/src/canvas/canvas.type.d.ts.map +1 -0
  20. package/dist/cjs/{canvas/chart.canvas.util.d.ts → src/canvas/chart.canvas.d.ts} +2 -2
  21. package/dist/cjs/src/canvas/chart.canvas.d.ts.map +1 -0
  22. package/dist/{esm/canvas/grid.canvas.util.d.ts → cjs/src/canvas/grid.canvas.d.ts} +2 -2
  23. package/dist/cjs/src/canvas/grid.canvas.d.ts.map +1 -0
  24. package/dist/{esm/canvas/image.canvas.util.d.ts → cjs/src/canvas/image.canvas.d.ts} +2 -2
  25. package/dist/cjs/src/canvas/image.canvas.d.ts.map +1 -0
  26. package/dist/{esm/canvas/layout.canvas.util.d.ts → cjs/src/canvas/layout.canvas.d.ts} +1 -1
  27. package/dist/cjs/src/canvas/layout.canvas.d.ts.map +1 -0
  28. package/dist/{esm/canvas/root.canvas.util.d.ts → cjs/src/canvas/root.canvas.d.ts} +2 -2
  29. package/dist/cjs/src/canvas/root.canvas.d.ts.map +1 -0
  30. package/dist/cjs/{canvas/text.canvas.util.d.ts → src/canvas/text.canvas.d.ts} +2 -2
  31. package/dist/cjs/src/canvas/text.canvas.d.ts.map +1 -0
  32. package/dist/cjs/src/constant/common.const.d.ts +18 -0
  33. package/dist/cjs/src/constant/common.const.d.ts.map +1 -0
  34. package/dist/cjs/src/index.d.ts +11 -0
  35. package/dist/cjs/src/index.d.ts.map +1 -0
  36. package/dist/cjs/src/util/disk.cache.d.ts.map +1 -0
  37. package/dist/cjs/src/worker/render.worker.d.ts.map +1 -0
  38. package/dist/cjs/src/worker/worker.types.d.ts.map +1 -0
  39. package/dist/cjs/util/disk.cache.js +9 -3
  40. package/dist/cjs/util/disk.cache.js.map +1 -1
  41. package/dist/cjs/worker/render.worker.js +2 -2
  42. package/dist/cjs/worker/render.worker.js.map +1 -1
  43. package/dist/esm/canvas/{chart.canvas.util.js → chart.canvas.js} +4 -4
  44. package/dist/esm/canvas/{grid.canvas.util.js → grid.canvas.js} +1 -1
  45. package/dist/esm/canvas/{image.canvas.util.js → image.canvas.js} +1 -1
  46. package/dist/esm/canvas/{layout.canvas.util.js → layout.canvas.js} +17 -10
  47. package/dist/esm/canvas/{root.canvas.util.js → root.canvas.js} +5 -5
  48. package/dist/esm/canvas/{text.canvas.util.js → text.canvas.js} +1 -1
  49. package/dist/esm/index.js +6 -6
  50. package/dist/esm/src/canvas/canvas.helper.d.ts.map +1 -0
  51. package/dist/{cjs → esm/src}/canvas/canvas.type.d.ts +4 -4
  52. package/dist/esm/src/canvas/canvas.type.d.ts.map +1 -0
  53. package/dist/esm/{canvas/chart.canvas.util.d.ts → src/canvas/chart.canvas.d.ts} +2 -2
  54. package/dist/esm/src/canvas/chart.canvas.d.ts.map +1 -0
  55. package/dist/{cjs/canvas/grid.canvas.util.d.ts → esm/src/canvas/grid.canvas.d.ts} +2 -2
  56. package/dist/esm/src/canvas/grid.canvas.d.ts.map +1 -0
  57. package/dist/{cjs/canvas/image.canvas.util.d.ts → esm/src/canvas/image.canvas.d.ts} +2 -2
  58. package/dist/esm/src/canvas/image.canvas.d.ts.map +1 -0
  59. package/dist/{cjs/canvas/layout.canvas.util.d.ts → esm/src/canvas/layout.canvas.d.ts} +1 -1
  60. package/dist/esm/src/canvas/layout.canvas.d.ts.map +1 -0
  61. package/dist/{cjs/canvas/root.canvas.util.d.ts → esm/src/canvas/root.canvas.d.ts} +2 -2
  62. package/dist/esm/src/canvas/root.canvas.d.ts.map +1 -0
  63. package/dist/esm/{canvas/text.canvas.util.d.ts → src/canvas/text.canvas.d.ts} +2 -2
  64. package/dist/esm/src/canvas/text.canvas.d.ts.map +1 -0
  65. package/dist/esm/src/constant/common.const.d.ts +18 -0
  66. package/dist/esm/src/constant/common.const.d.ts.map +1 -0
  67. package/dist/esm/src/index.d.ts +11 -0
  68. package/dist/esm/src/index.d.ts.map +1 -0
  69. package/dist/esm/src/util/disk.cache.d.ts.map +1 -0
  70. package/dist/esm/src/worker/render.worker.d.ts.map +1 -0
  71. package/dist/esm/src/worker/worker.types.d.ts.map +1 -0
  72. package/dist/esm/util/disk.cache.js +9 -3
  73. package/dist/esm/worker/render.worker.js +1 -1
  74. package/package.json +9 -8
  75. package/dist/cjs/canvas/canvas.helper.d.ts.map +0 -1
  76. package/dist/cjs/canvas/canvas.type.d.ts.map +0 -1
  77. package/dist/cjs/canvas/chart.canvas.util.d.ts.map +0 -1
  78. package/dist/cjs/canvas/chart.canvas.util.js.map +0 -1
  79. package/dist/cjs/canvas/grid.canvas.util.d.ts.map +0 -1
  80. package/dist/cjs/canvas/grid.canvas.util.js.map +0 -1
  81. package/dist/cjs/canvas/image.canvas.util.d.ts.map +0 -1
  82. package/dist/cjs/canvas/image.canvas.util.js.map +0 -1
  83. package/dist/cjs/canvas/layout.canvas.util.d.ts.map +0 -1
  84. package/dist/cjs/canvas/layout.canvas.util.js.map +0 -1
  85. package/dist/cjs/canvas/root.canvas.util.d.ts.map +0 -1
  86. package/dist/cjs/canvas/root.canvas.util.js.map +0 -1
  87. package/dist/cjs/canvas/text.canvas.util.d.ts.map +0 -1
  88. package/dist/cjs/canvas/text.canvas.util.js.map +0 -1
  89. package/dist/cjs/constant/common.const.d.ts +0 -37
  90. package/dist/cjs/constant/common.const.d.ts.map +0 -1
  91. package/dist/cjs/index.d.ts +0 -11
  92. package/dist/cjs/index.d.ts.map +0 -1
  93. package/dist/cjs/util/disk.cache.d.ts.map +0 -1
  94. package/dist/cjs/worker/render.worker.d.ts.map +0 -1
  95. package/dist/cjs/worker/worker.types.d.ts.map +0 -1
  96. package/dist/esm/canvas/canvas.helper.d.ts.map +0 -1
  97. package/dist/esm/canvas/canvas.type.d.ts.map +0 -1
  98. package/dist/esm/canvas/chart.canvas.util.d.ts.map +0 -1
  99. package/dist/esm/canvas/grid.canvas.util.d.ts.map +0 -1
  100. package/dist/esm/canvas/image.canvas.util.d.ts.map +0 -1
  101. package/dist/esm/canvas/layout.canvas.util.d.ts.map +0 -1
  102. package/dist/esm/canvas/root.canvas.util.d.ts.map +0 -1
  103. package/dist/esm/canvas/text.canvas.util.d.ts.map +0 -1
  104. package/dist/esm/constant/common.const.d.ts +0 -37
  105. package/dist/esm/constant/common.const.d.ts.map +0 -1
  106. package/dist/esm/index.d.ts +0 -11
  107. package/dist/esm/index.d.ts.map +0 -1
  108. package/dist/esm/util/disk.cache.d.ts.map +0 -1
  109. package/dist/esm/worker/render.worker.d.ts.map +0 -1
  110. package/dist/esm/worker/worker.types.d.ts.map +0 -1
  111. /package/dist/cjs/{canvas → src/canvas}/canvas.helper.d.ts +0 -0
  112. /package/dist/cjs/{util → src/util}/disk.cache.d.ts +0 -0
  113. /package/dist/cjs/{worker → src/worker}/render.worker.d.ts +0 -0
  114. /package/dist/cjs/{worker → src/worker}/worker.types.d.ts +0 -0
  115. /package/dist/esm/{canvas → src/canvas}/canvas.helper.d.ts +0 -0
  116. /package/dist/esm/{util → src/util}/disk.cache.d.ts +0 -0
  117. /package/dist/esm/{worker → src/worker}/render.worker.d.ts +0 -0
  118. /package/dist/esm/{worker → src/worker}/worker.types.d.ts +0 -0
package/README.md CHANGED
@@ -43,18 +43,21 @@ rendering to a canvas.
43
43
  yarn add @meonode/canvas
44
44
  ```
45
45
 
46
- ## Basic Usage
46
+ ## Usage
47
47
 
48
- Here's a simple example of how to create an image with a title and a description:
48
+ ### Simple Example
49
+
50
+ A minimal example that renders a title and description to a PNG file:
49
51
 
50
52
  ```typescript
51
53
  import {Root, Box, Text} from '@meonode/canvas';
52
- import {writeFile} from 'fs/promises';
53
54
 
54
55
  async function generateImage() {
55
56
  const canvas = await Root({
56
57
  width: 500,
57
58
  height: 300,
59
+ scale: 1, // increase to 2 for 2× retina resolution
60
+ workerMode: true, // renders in a worker thread — keeps the main thread free (default)
58
61
  fonts: [
59
62
  {
60
63
  family: 'Roboto',
@@ -85,26 +88,28 @@ async function generateImage() {
85
88
  ],
86
89
  });
87
90
 
88
- const buffer = await canvas.toBuffer('png');
89
- await writeFile('output.png', buffer);
91
+ await canvas.toFile('output.png'); // saves directly to disk
92
+ canvas.release(); // free worker memory after use
90
93
  }
91
94
 
92
95
  generateImage().catch(console.error);
93
96
  ```
94
97
 
95
- ## Wider Usage Example
98
+ ### Complex Layout
96
99
 
97
- This example demonstrates a more complex layout using various components, including `Image` and advanced flexbox
98
- properties.
100
+ A more complete example using `Column`, `Row`, `Image`, and advanced flexbox properties to build a structured page
101
+ layout with a header, content area, and footer:
99
102
 
100
103
  ```typescript
101
104
  import {Root, Column, Row, Text, Image, Style} from '@meonode/canvas';
102
- import {writeFile} from 'fs/promises';
103
105
 
104
106
  async function generateComplexImage() {
105
107
  const canvas = await Root({
106
108
  width: 800,
107
109
  height: 600,
110
+ scale: 2, // 2× resolution — canvas output will be 1600×1200px
111
+ workerMode: true, // renders off the main thread (default)
112
+ useDiskCache: true, // caches fetched remote images to disk for faster re-decode
108
113
  fonts: [
109
114
  {
110
115
  family: 'Roboto',
@@ -121,9 +126,9 @@ async function generateComplexImage() {
121
126
  height: '100%',
122
127
  backgroundColor: '#f0f0f0',
123
128
  padding: 20,
124
- justifyContent: Style.Justify.SpaceBetween,
129
+ justifyContent: Style.Justify.SpaceBetween, // evenly space header, body, footer
125
130
  children: [
126
- // Header Section
131
+ // Header: avatar + title side by side
127
132
  Row({
128
133
  width: '100%',
129
134
  alignItems: Style.Align.Center,
@@ -133,7 +138,7 @@ async function generateComplexImage() {
133
138
  src: 'https://via.placeholder.com/80x80/FF0000/FFFFFF?text=Logo',
134
139
  width: 80,
135
140
  height: 80,
136
- borderRadius: 40,
141
+ borderRadius: 40, // circle crop
137
142
  marginRight: 20,
138
143
  objectFit: 'cover',
139
144
  }),
@@ -146,7 +151,7 @@ async function generateComplexImage() {
146
151
  ],
147
152
  }),
148
153
 
149
- // Main Content Section
154
+ // Body: grows to fill remaining vertical space
150
155
  Column({
151
156
  flexGrow: 1,
152
157
  width: '100%',
@@ -180,12 +185,12 @@ async function generateComplexImage() {
180
185
  marginTop: 20,
181
186
  borderRadius: 8,
182
187
  objectFit: 'contain',
183
- objectPosition: {Top: '50%', Left: '50%'},
188
+ objectPosition: {Top: '50%', Left: '50%'}, // center within box
184
189
  }),
185
190
  ],
186
191
  }),
187
192
 
188
- // Footer Section
193
+ // Footer: centered copyright line
189
194
  Row({
190
195
  width: '100%',
191
196
  marginTop: 20,
@@ -203,27 +208,29 @@ async function generateComplexImage() {
203
208
  ],
204
209
  });
205
210
 
206
- const buffer = await canvas.toBuffer('png');
207
- await writeFile('complex_output.png', buffer);
211
+ await canvas.toFile('complex_output.png'); // saves directly to disk
212
+ canvas.release(); // free worker memory after use
208
213
  }
209
214
 
210
215
  generateComplexImage().catch(console.error);
211
216
  ```
212
217
 
213
- ## Chart Examples
218
+ ## Examples
214
219
 
215
- You can easily create charts by providing data and options to the `Chart` component.
220
+ ### Charts
216
221
 
217
- ### Bar Chart
222
+ The `Chart` component supports `bar`, `line`, `pie`, and `doughnut` chart types.
223
+
224
+ #### Bar Chart
218
225
 
219
226
  ```typescript
220
227
  import {Root, Chart} from '@meonode/canvas';
221
- import {writeFile} from 'fs/promises';
222
228
 
223
229
  async function generateBarChart() {
224
230
  const canvas = await Root({
225
231
  width: 600,
226
232
  height: 400,
233
+ workerMode: true, // default — render in a worker thread
227
234
  children: [
228
235
  Chart({
229
236
  type: 'bar',
@@ -240,35 +247,35 @@ async function generateBarChart() {
240
247
  ],
241
248
  },
242
249
  options: {
243
- gridOptions: {show: true, style: 'dashed'},
250
+ grid: {show: true, style: 'dashed'},
244
251
  axisColor: '#333',
245
252
  labelColor: '#333',
246
- showValues: true,
253
+ showValues: true, // display value labels above each bar
247
254
  valueFontSize: 12,
248
- showYAxis: true,
255
+ showYAxis: true, // show Y-axis tick labels on the left
249
256
  yAxisColor: '#666',
250
257
  },
251
258
  }),
252
259
  ],
253
260
  });
254
261
 
255
- const buffer = await canvas.toBuffer('png');
256
- await writeFile('bar_chart.png', buffer);
262
+ await canvas.toFile('bar_chart.png');
263
+ canvas.release();
257
264
  }
258
265
 
259
266
  generateBarChart().catch(console.error);
260
267
  ```
261
268
 
262
- ### Doughnut Chart with Custom Legend
269
+ #### Doughnut Chart with Custom Legend
263
270
 
264
271
  ```typescript
265
272
  import {Root, Chart, Row, Box, Text} from '@meonode/canvas';
266
- import {writeFile} from 'fs/promises';
267
273
 
268
274
  async function generateDoughnutChart() {
269
275
  const canvas = await Root({
270
276
  width: 600,
271
277
  height: 400,
278
+ workerMode: true, // default — render in a worker thread
272
279
  children: [
273
280
  Chart({
274
281
  type: 'doughnut',
@@ -280,8 +287,9 @@ async function generateDoughnutChart() {
280
287
  {label: 'Yellow', value: 100, color: '#FFCE56'},
281
288
  ],
282
289
  options: {
283
- innerRadius: 0.7,
284
- sliceBorderRadius: 5,
290
+ innerRadius: 0.7, // 0 = full pie, 1 = empty ring; 0.7 gives a thick doughnut
291
+ sliceBorderRadius: 5, // rounded corners on each slice
292
+ // custom legend item: colored dot + "Label: value" text
285
293
  renderLegendItem: ({item, color}) =>
286
294
  Row({
287
295
  alignItems: 'center',
@@ -295,51 +303,52 @@ async function generateDoughnutChart() {
295
303
  ],
296
304
  });
297
305
 
298
- const buffer = await canvas.toBuffer('png');
299
- await writeFile('doughnut_chart.png', buffer);
306
+ await canvas.toFile('doughnut_chart.png');
307
+ canvas.release();
300
308
  }
301
309
 
302
310
  generateDoughnutChart().catch(console.error);
303
311
  ```
304
312
 
305
- ## Grid Layout Examples
313
+ ### Grid
306
314
 
307
315
  The `Grid` component simplifies creating complex layouts. It mimics CSS Grid Layout.
308
316
 
309
- ### Basic Grid
317
+ #### Basic Grid
310
318
 
311
319
  A simple grid with 3 columns, each 100 pixels wide.
312
320
 
313
321
  ```typescript
314
322
  import {Root, Grid, Box, Text} from '@meonode/canvas';
315
- import {writeFile} from 'fs/promises';
316
323
 
317
324
  async function generateBasicGrid() {
318
325
  const canvas = await Root({
319
326
  width: 400,
320
327
  height: 300,
328
+ workerMode: true, // default — render in a worker thread
321
329
  children: [
322
330
  Grid({
323
331
  columns: 3,
324
- templateColumns: [100, 100, 100], // or ['100px', '100px', '100px']
332
+ templateColumns: [100, 100, 100], // fixed widths; also accepts ['100px', '100px', '100px']
325
333
  gap: 10,
326
334
  children: [
327
335
  Box({backgroundColor: 'red', height: 50, children: [Text('1')]}),
328
336
  Box({backgroundColor: 'blue', height: 50, children: [Text('2')]}),
329
337
  Box({backgroundColor: 'green', height: 50, children: [Text('3')]}),
330
- Box({backgroundColor: 'yellow', height: 50, children: [Text('4')]}),
338
+ Box({backgroundColor: 'yellow', height: 50, children: [Text('4')]}), // wraps to row 2
331
339
  ],
332
340
  }),
333
341
  ],
334
342
  });
335
343
 
336
344
  await canvas.toFile('grid_basic.png');
345
+ canvas.release();
337
346
  }
338
347
 
339
- generateBasicGrid();
348
+ generateBasicGrid().catch(console.error);
340
349
  ```
341
350
 
342
- ### Responsive Grid (Fractional Units)
351
+ #### Responsive Grid (Fractional Units)
343
352
 
344
353
  Using fractional units (`fr`) allows columns to take up proportional space.
345
354
 
@@ -356,9 +365,9 @@ Grid({
356
365
  });
357
366
  ```
358
367
 
359
- ### Spanning Items
368
+ #### Spanning Items
360
369
 
361
- Use `GridItem` (or just passing `gridColumn`/`gridRow` props to any child) to span multiple columns or rows.
370
+ Use `GridItem` (or pass `gridColumn`/`gridRow` props directly to any child) to span multiple columns or rows.
362
371
 
363
372
  ```typescript
364
373
  import {Grid, GridItem, Box, Text} from '@meonode/canvas';
@@ -388,13 +397,11 @@ Grid({
388
397
  });
389
398
  ```
390
399
 
391
- ## Using Yoga Layout Properties
400
+ ## Yoga Layout
392
401
 
393
402
  This library leverages `yoga-layout` for its powerful flexbox engine. Many layout properties directly map to Yoga's
394
403
  concepts. You can access Yoga-specific constants through the `Style` export from `@meonode/canvas`.
395
404
 
396
- For example, to set `flexDirection` to `row` or `positionType` to `absolute`, you would use:
397
-
398
405
  ```typescript
399
406
  import {Box, Style} from '@meonode/canvas';
400
407
 
@@ -418,9 +425,98 @@ Box({
418
425
  Refer to the [Yoga Layout documentation](https://yogalayout.dev/docs/) for a comprehensive understanding of these
419
426
  properties.
420
427
 
421
- ## Component API Reference
428
+ ## API Reference
429
+
430
+ ### Root
431
+
432
+ The `Root` function is the entry point for rendering. It returns a `Canvas` object. It is a specialized `ColumnNode`
433
+ that inherits all `BoxProps`.
434
+
435
+ #### Root Props
436
+
437
+
438
+ | Prop | Type | Default | Description |
439
+ | -------------- | --------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------- |
440
+ | `width` | `number` | - | **Required.** Width of the canvas in pixels. |
441
+ | `height` | `number` | - | Optional height of the canvas. If not set, it's calculated from content. |
442
+ | `children` | `CanvasElement | CanvasElement[]` | - | **Required.** The component tree to render. |
443
+ | `scale` | `number` | `1` | Scale factor for rendering (e.g., 2 for 2x resolution). |
444
+ | `fonts` | `FontRegistrationInfo[]` | - | An array of font files to register for use in the canvas. |
445
+ | `useDiskCache` | `boolean` | `false` | Write fetched images to disk during render for faster re-decode. Entries are cleaned up after render. |
446
+ | `workerMode` | `boolean` | `true` | Enable worker thread rendering for non-blocking operation. |
447
+ | `workers` | `number` | `cpus().length - 1` | Number of worker threads to use (only applies on first render with`workerMode: true`). |
448
+
449
+ Since `Root` extends `BoxProps`, it also accepts `backgroundColor`, `padding`, `gradient`, `boxShadow`, and all other
450
+ layout props. See [Box, Row, and Column](#box-row-and-column) for the full list.
451
+
452
+ #### Canvas Methods
453
+
454
+ The `Root()` function returns a Canvas object with the following methods and properties.
455
+
456
+ ##### Export Methods
457
+
458
+
459
+ | Method | Signature | Description |
460
+ | -------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
461
+ | `toBufferSync` | `(format?: ExportFormat, options?: ExportOptions) => Buffer` | Synchronously returns a buffer. In worker mode, returns the pre-encoded PNG. |
462
+ | `toBuffer` | `(format: ExportFormat, options?: ExportOptions) => Promise<Buffer>` | Asynchronously encodes to the specified format. |
463
+ | `toURL` | `(format: ExportFormat, options?: ExportOptions) => Promise<string>` | Returns a data URL. |
464
+ | `toURLSync` | `(format?: ExportFormat, options?: ExportOptions) => string` | Synchronously returns a data URL (from pre-encoded PNG in worker mode). |
465
+ | `toFile` | `(filename: string, options?: SaveOptions) => Promise<void>` | Saves the canvas to a file. |
466
+ | `toSharp` | `(options?: RenderOptions) => Promise<Buffer>` | Returns a Sharp instance buffer for further processing. |
467
+ | `toSharpSync` | `(options?: RenderOptions) => never` | **Throws error.** Use `toSharp()` instead in worker mode. |
468
+
469
+ **Supported Export Formats:** `'png'`, `'jpg'` (or `'jpeg'`), `'webp'`, `'pdf'`, `'svg'`, `'raw'`
470
+
471
+ ##### Convenience Getters
472
+
473
+
474
+ | Getter | Returns | Description |
475
+ | ------- | ----------------- | ----------------------------------------------- |
476
+ | `.png` | `Promise<Buffer>` | Shortcut for`toBuffer('png')` |
477
+ | `.jpg` | `Promise<Buffer>` | Shortcut for`toBuffer('jpg')` |
478
+ | `.webp` | `Promise<Buffer>` | Shortcut for`toBuffer('webp')` |
479
+ | `.svg` | `Promise<Buffer>` | Shortcut for`toBuffer('svg')` |
480
+ | `.pdf` | `Promise<Buffer>` | Shortcut for`toBuffer('pdf')` |
481
+ | `.raw` | `Promise<Buffer>` | Shortcut for`toBuffer('raw')` — raw pixel data |
482
+
483
+ ##### Canvas Properties
484
+
485
+
486
+ | Property | Type | Description |
487
+ | --------- | -------- | -------------------------------------- |
488
+ | `.width` | `number` | Canvas width in pixels (after scale). |
489
+ | `.height` | `number` | Canvas height in pixels (after scale). |
490
+
491
+ ##### Memory Management (Worker Mode)
422
492
 
423
- This section details the props available for each component.
493
+
494
+ | Method | Description |
495
+ | ------------ | ------------------------------------------------------------------------------------------------------------ |
496
+ | `.release()` | **Required in worker mode.** Releases the Canvas from worker memory. Call when done to prevent memory leaks. |
497
+
498
+ ```typescript
499
+ import {Root} from '@meonode/canvas'
500
+
501
+ // Render with default worker mode (enabled)
502
+ const canvas = await Root({width: 400, height: 400, children: [...]})
503
+
504
+ // Or explicitly disable worker mode
505
+ const canvas = await Root({width: 400, height: 400, children: [...], workerMode: false})
506
+
507
+ // Use the canvas
508
+ const png = await canvas.png
509
+ const jpg = await canvas.jpg
510
+ await canvas.toFile('output.png')
511
+
512
+ // Release memory (worker mode only)
513
+ canvas.release()
514
+ ```
515
+
516
+ > **Note:** A FinalizationRegistry provides automatic cleanup for forgotten `.release()` calls, but explicit cleanup is
517
+ > recommended for deterministic memory management in production.
518
+
519
+ ---
424
520
 
425
521
  ### Box, Row, and Column
426
522
 
@@ -429,64 +525,68 @@ These are the fundamental layout components. `Row` and `Column` are wrappers aro
429
525
 
430
526
  #### Layout Props
431
527
 
432
- | Prop | Type | Description |
433
- |-------------------------|------------------------------|--------------------------------------------------------------------------------|
434
- | `width`, `height` | `number \| string` | Sets the size of the node in pixels or percentage. |
435
- | `minWidth`, `minHeight` | `number \| string` | Sets the minimum size of the node. |
436
- | `maxWidth`, `maxHeight` | `number \| string` | Sets the maximum size of the node. |
437
- | `flexDirection` | `Style.FlexDirection` | Defines the direction of the main axis (`Row`, `Column`, etc.). |
438
- | `justifyContent` | `Style.Justify` | Defines how items are distributed along the main axis. |
439
- | `alignItems` | `Style.Align` | Defines how items are aligned along the cross axis. |
440
- | `alignSelf` | `Style.Align` | Overrides the parent's `alignItems` for a specific item. |
441
- | `alignContent` | `Style.Align` | Defines how lines are distributed when content wraps. |
442
- | `flexGrow` | `number` | Defines the ability of an item to grow. |
443
- | `flexShrink` | `number` | Defines the ability of an item to shrink. |
444
- | `flexBasis` | `number \| 'auto' \| string` | Defines the default size of an item along the main axis. |
445
- | `flexWrap` | `Style.Wrap` | Controls whether flex items wrap to multiple lines. |
446
- | `positionType` | `Style.PositionType` | Sets the positioning method (`Relative` or `Absolute`). |
447
- | `position` | `object \| number \| string` | Sets the offset for a positioned element. |
448
- | `margin` | `object \| number \| string` | Sets the margin space on the outside of the node. |
449
- | `padding` | `object \| number \| string` | Sets the padding space on the inside of the node. |
450
- | `border` | `object \| number` | Sets the width of the node's border. |
451
- | `aspectRatio` | `number` | Locks the aspect ratio (width / height) of the node. |
452
- | `overflow` | `Style.Overflow` | Defines how content that overflows is handled (`Visible`, `Hidden`). |
453
- | `display` | `Style.Display` | Controls if the node is included in layout (`Flex`, `None`). |
454
- | `direction` | `Style.Direction` | Sets the primary layout direction (`LTR`, `RTL`). |
455
- | `gap` | `object \| number \| string` | Defines the space between flex items. |
456
- | `boxSizing` | `Style.BoxSizing` | Defines how `width` and `height` are interpreted (`ContentBox`, `BorderBox`). |
457
- | `zIndex` | `number` | Specifies the stack order of an element (only for `positionType: 'absolute'`). |
528
+
529
+ | Prop | Type | Description |
530
+ | ----------------------- | -------------------------- | ----------------------------------------------------------------------------- |
531
+ | `width`, `height` | `number | string` | Sets the size of the node in pixels or percentage. |
532
+ | `minWidth`, `minHeight` | `number | string` | Sets the minimum size of the node. |
533
+ | `maxWidth`, `maxHeight` | `number | string` | Sets the maximum size of the node. |
534
+ | `flexDirection` | `Style.FlexDirection` | Defines the direction of the main axis (`Row`, `Column`, etc.). |
535
+ | `justifyContent` | `Style.Justify` | Defines how items are distributed along the main axis. |
536
+ | `alignItems` | `Style.Align` | Defines how items are aligned along the cross axis. |
537
+ | `alignSelf` | `Style.Align` | Overrides the parent's`alignItems` for a specific item. |
538
+ | `alignContent` | `Style.Align` | Defines how lines are distributed when content wraps. |
539
+ | `flexGrow` | `number` | Defines the ability of an item to grow. |
540
+ | `flexShrink` | `number` | Defines the ability of an item to shrink. |
541
+ | `flexBasis` | `number | 'auto' | string` | Defines the default size of an item along the main axis. |
542
+ | `flexWrap` | `Style.Wrap` | Controls whether flex items wrap to multiple lines. |
543
+ | `positionType` | `Style.PositionType` | Sets the positioning method (`Relative` or `Absolute`). |
544
+ | `position` | `object | number | string` | Sets the offset for a positioned element. |
545
+ | `margin` | `object | number | string` | Sets the margin space on the outside of the node. |
546
+ | `padding` | `object | number | string` | Sets the padding space on the inside of the node. |
547
+ | `border` | `object | number` | Sets the width of the node's border. |
548
+ | `aspectRatio` | `number` | Locks the aspect ratio (width / height) of the node. |
549
+ | `overflow` | `Style.Overflow` | Defines how content that overflows is handled (`Visible`, `Hidden`). |
550
+ | `display` | `Style.Display` | Controls if the node is included in layout (`Flex`, `None`). |
551
+ | `direction` | `Style.Direction` | Sets the primary layout direction (`LTR`, `RTL`). |
552
+ | `gap` | `object | number | string` | Defines the space between flex items. |
553
+ | `boxSizing` | `Style.BoxSizing` | Defines how`width` and `height` are interpreted (`ContentBox`, `BorderBox`). |
554
+ | `zIndex` | `number` | Specifies the stack order of an element (only for`positionType: 'absolute'`). |
555
+ | `children` | `CanvasElement \| CanvasElement[]` | Child nodes to render inside this node. |
458
556
 
459
557
  #### Styling Props
460
558
 
461
- | Prop | Type | Description |
462
- |-------------------|--------------------------------------|--------------------------------------------------------|
463
- | `backgroundColor` | `string` | Sets the background color of the node. |
464
- | `borderColor` | `string` | Sets the color of the node's border. |
465
- | `borderStyle` | `Style.Border` | Sets the style of the border (`Solid`, `Dashed`). |
466
- | `borderRadius` | `object \| number` | Sets the radius of the node's corners. |
467
- | `opacity` | `number` | Sets the opacity of the node and its children (0-1). |
468
- | `gradient` | `object` | Sets a linear or radial gradient as the background. |
469
- | `boxShadow` | `BoxShadowProps \| BoxShadowProps[]` | Applies one or more box-shadow effects. |
470
- | `transform` | `TransformProps` | Applies 2D transformations (translate, rotate, scale). |
559
+
560
+ | Prop | Type | Description |
561
+ | ----------------- | ----------------------------------- | ------------------------------------------------------ |
562
+ | `backgroundColor` | `string` | Sets the background color of the node. |
563
+ | `borderColor` | `string` | Sets the color of the node's border. |
564
+ | `borderStyle` | `Style.Border` | Sets the style of the border (`Solid`, `Dashed`, `Dotted`). |
565
+ | `borderRadius` | `object | number` | Sets the radius of the node's corners. |
566
+ | `opacity` | `number` | Sets the opacity of the node and its children (0-1). |
567
+ | `gradient` | `object` | Sets a linear or radial gradient as the background. |
568
+ | `boxShadow` | `BoxShadowProps | BoxShadowProps[]` | Applies one or more box-shadow effects. |
569
+ | `transform` | `TransformProps` | Applies 2D transformations (translate, rotate, scale). |
471
570
 
472
571
  #### Font & Text Props (Inheritable)
473
572
 
474
573
  These props, when set on a `Box`, `Row`, or `Column`, are inherited by any descendant `Text` nodes.
475
574
 
476
- | Prop | Type | Description |
477
- |-----------------|------------------------------------------------------------------|--------------------------------------------|
478
- | `fontSize` | `number` | Font size in pixels. |
479
- | `fontFamily` | `string` | Font family name. |
480
- | `fontWeight` | `string \| number` | Font weight ('normal', 'bold', 400, etc.). |
481
- | `fontStyle` | `'normal' \| 'italic'` | Font style. |
482
- | `color` | `string` | Text color. |
483
- | `textAlign` | `'start' \| 'end' \| 'left' \| 'center' \| 'right' \| 'justify'` | Horizontal text alignment. |
484
- | `verticalAlign` | `'top' \| 'middle' \| 'bottom'` | Vertical text alignment. |
485
- | `lineHeight` | `number` | Line height in pixels. |
486
- | `lineGap` | `number` | Additional vertical spacing between lines. |
487
- | `letterSpacing` | `number \| string` | Spacing between letters. |
488
- | `wordSpacing` | `number \| string` | Spacing between words. |
489
- | `fontVariant` | `FontVariantSetting` | Specifies font variation settings. |
575
+
576
+ | Prop | Type | Description |
577
+ | --------------- | ----------------------------------------------------------- | ------------------------------------------ |
578
+ | `fontSize` | `number` | Font size in pixels. |
579
+ | `fontFamily` | `string` | Font family name. |
580
+ | `fontWeight` | `string | number` | Font weight ('normal', 'bold', 400, etc.). |
581
+ | `fontStyle` | `'normal' | 'italic'` | Font style. |
582
+ | `color` | `string` | Text color. |
583
+ | `textAlign` | `'start' | 'end' | 'left' | 'center' | 'right' | 'justify'` | Horizontal text alignment. |
584
+ | `verticalAlign` | `'top' | 'middle' | 'bottom'` | Vertical text alignment. |
585
+ | `lineHeight` | `number` | Line height in pixels. |
586
+ | `lineGap` | `number` | Additional vertical spacing between lines. |
587
+ | `letterSpacing` | `number | string` | Spacing between letters. |
588
+ | `wordSpacing` | `number | string` | Spacing between words. |
589
+ | `fontVariant` | `FontVariantSetting` | Specifies font variation settings. |
490
590
 
491
591
  ---
492
592
 
@@ -497,11 +597,12 @@ properties.
497
597
 
498
598
  #### Text-Specific Props
499
599
 
500
- | Prop | Type | Description |
501
- |--------------|----------------------------------------|----------------------------------------------------------------------------|
502
- | `maxLines` | `number` | Maximum number of lines to display before truncating. |
503
- | `ellipsis` | `boolean \| string` | If `true`, adds '...' when text is truncated. Can also be a custom string. |
504
- | `textShadow` | `TextShadowProps \| TextShadowProps[]` | Applies one or more shadow effects to the text itself. |
600
+
601
+ | Prop | Type | Description |
602
+ | ------------ | ------------------------------------- | ------------------------------------------------------------------------- |
603
+ | `maxLines` | `number` | Maximum number of lines to display before truncating. |
604
+ | `ellipsis` | `boolean | string` | If`true`, adds '...' when text is truncated. Can also be a custom string. |
605
+ | `textShadow` | `TextShadowProps | TextShadowProps[]` | Applies one or more shadow effects to the text itself. |
505
606
 
506
607
  ---
507
608
 
@@ -511,16 +612,17 @@ The `Image` component renders an image. It inherits all `BoxProps` except for `c
511
612
 
512
613
  #### Image-Specific Props
513
614
 
514
- | Prop | Type | Description |
515
- |------------------|------------------------------------------------------------|-----------------------------------------------------------------------|
516
- | `src` | `string \| Buffer` | The source URL, file path, or buffer of the image. |
517
- | `objectFit` | `'fill' \| 'contain' \| 'cover' \| 'none' \| 'scale-down'` | Specifies how the image should be resized to fit its container. |
518
- | `objectPosition` | `object` | Specifies the alignment of the image within its box. |
519
- | `saturate` | `number` | Adjusts the image's saturation level (0 is grayscale, 1 is original). |
520
- | `dropShadow` | `DropShadowProps` | Applies a drop-shadow effect based on the image's alpha channel. |
521
- | `alt` | `string` | Alternative text description (for accessibility). |
522
- | `onLoad` | `() => void` | Callback function that executes when the image loads successfully. |
523
- | `onError` | `(error: Error) => void` | Callback function that executes when the image fails to load. |
615
+
616
+ | Prop | Type | Description |
617
+ | ---------------- | ------------------------------------------------------ | --------------------------------------------------------------------- |
618
+ | `src` | `string | Buffer` | The source URL, file path, or buffer of the image. |
619
+ | `objectFit` | `'fill' | 'contain' | 'cover' | 'none' | 'scale-down'` | Specifies how the image should be resized to fit its container. |
620
+ | `objectPosition` | `object` | Specifies the alignment of the image within its box. |
621
+ | `saturate` | `number` | Adjusts the image's saturation level (0 is grayscale, 1 is original). |
622
+ | `dropShadow` | `DropShadowProps` | Applies a drop-shadow effect based on the image's alpha channel. |
623
+ | `alt` | `string` | Alternative text description (for accessibility). |
624
+ | `onLoad` | `() => void` | Callback function that executes when the image loads successfully. |
625
+ | `onError` | `(error: Error) => void` | Callback function that executes when the image fails to load. |
524
626
 
525
627
  ---
526
628
 
@@ -530,33 +632,35 @@ The `Grid` component arranges its children in a grid layout. It is a specialized
530
632
 
531
633
  #### Grid-Specific Props
532
634
 
533
- | Prop | Type | Description |
534
- |-------------------|----------------------------------------------------------|---------------------------------------------------------|
535
- | `columns` | `number` | The number of columns in the grid. Default is 1. |
536
- | `templateColumns` | `GridTrackSize[]` | Defines the columns of the grid (e.g., `[100, '1fr']`). |
537
- | `templateRows` | `GridTrackSize[]` | Defines the rows of the grid. |
538
- | `autoRows` | `GridTrackSize` | Specifies the size of implicitly created rows. |
539
- | `autoFlow` | `'row' \| 'column' \| 'row-dense' \| 'column-dense'` | Controls how the auto-placement algorithm works. |
540
- | `gap` | `number \| string` | Defines the gap between grid items. |
541
- | `rowGap` | `number \| string` | Defines the row gap. |
542
- | `columnGap` | `number \| string` | Defines the column gap. |
543
- | `direction` | `'row' \| 'column' \| 'row-reverse' \| 'column-reverse'` | The direction of the grid layout. Default is 'row'. |
635
+
636
+ | Prop | Type | Description |
637
+ | ----------------- | ----------------------------------------------------- | ------------------------------------------------------ |
638
+ | `columns` | `number` | The number of columns in the grid. Default is 1. |
639
+ | `templateColumns` | `GridTrackSize[]` | Defines the columns of the grid (e.g.,`[100, '1fr']`). |
640
+ | `templateRows` | `GridTrackSize[]` | Defines the rows of the grid. |
641
+ | `autoRows` | `GridTrackSize` | Specifies the size of implicitly created rows. |
642
+ | `autoFlow` | `'row' \| 'column' \| 'row-dense' \| 'column-dense'` | Controls how the auto-placement algorithm works. Default is `'row'`. |
643
+
644
+ > **Gap control:** `gap` is inherited from `BoxProps`. Pass a number for uniform spacing, or an object for per-axis control: `gap: { Row: 10, Column: 20 }`.
544
645
 
545
646
  ---
546
647
 
547
648
  ### GridItem
548
649
 
549
- The `GridItem` component represents a child item within a `Grid`. It inherits all `BoxProps` and adds grid placement properties.
650
+ The `GridItem` component represents a child item within a `Grid`. It inherits all `BoxProps` and adds grid placement
651
+ properties.
550
652
 
551
653
  #### GridItem-Specific Props
552
654
 
553
- | Prop | Type | Description |
554
- |------|------|-------------|
555
- | `gridColumn` | `string` | Specifies the column span (e.g., `'span 2'`, `'1 / 3'`). |
556
- | `gridRow` | `string` | Specifies the row span (e.g., `'span 2'`, `'1 / 3'`). |
557
- | `gridArea` | `string` | Shorthand for `gridRow` and `gridColumn` (e.g., `'header'`). |
558
655
 
559
- > **Note:** You can also use `gridColumn` and `gridRow` props directly on any child component (`Box`, `Text`, etc.) without wrapping in `GridItem`.
656
+ | Prop | Type | Description |
657
+ | ------------ | -------- | ----------------------------------------------------------- |
658
+ | `gridColumn` | `string` | Specifies the column span (e.g.,`'span 2'`, `'1 / 3'`). |
659
+ | `gridRow` | `string` | Specifies the row span (e.g.,`'span 2'`, `'1 / 3'`). |
660
+ | `gridArea` | `string` | Shorthand for`gridRow` and `gridColumn` (e.g., `'header'`). |
661
+
662
+ > **Note:** You can also use `gridColumn` and `gridRow` props directly on any child component (`Box`, `Text`, etc.)
663
+ > without wrapping in `GridItem`.
560
664
 
561
665
  ---
562
666
 
@@ -566,11 +670,12 @@ The `Chart` component renders various types of charts. It inherits all `BoxProps
566
670
 
567
671
  #### Chart-Specific Props
568
672
 
569
- | Prop | Type | Description |
570
- |-----------|---------------------------------------------|-------------------------------------------------------------------------------|
571
- | `type` | `'bar' \| 'line' \| 'pie' \| 'doughnut'` | The type of chart to render. |
572
- | `data` | `CartesianChartData \| PieChartDataPoint[]` | The data for the chart, which varies based on the `type`. |
573
- | `options` | `ChartOptions<T>` | An object containing rendering and style options, specific to the chart type. |
673
+
674
+ | Prop | Type | Description |
675
+ | --------- | ------------------------------------------ | ----------------------------------------------------------------------------- |
676
+ | `type` | `'bar' | 'line' | 'pie' | 'doughnut'` | The type of chart to render. |
677
+ | `data` | `CartesianChartData | PieChartDataPoint[]` | The data for the chart, which varies based on the`type`. |
678
+ | `options` | `ChartOptions<T>` | An object containing rendering and style options, specific to the chart type. |
574
679
 
575
680
  #### ChartOptions
576
681
 
@@ -578,34 +683,38 @@ The `options` prop is a conditional type that changes based on the chart `type`.
578
683
 
579
684
  ##### Common Options (All Chart Types)
580
685
 
686
+
581
687
  | Prop | Type | Description |
582
- |--------------------|----------------------------------------------|---------------------------------------------------|
583
- | `showLabels` | `boolean` | If `true`, displays labels on the chart. |
584
- | `showLegend` | `boolean` | If `true`, displays the chart legend. |
688
+ | ------------------ | -------------------------------------------- | ------------------------------------------------- |
689
+ | `showLabels` | `boolean` | If`true`, displays labels on the chart. |
690
+ | `showLegend` | `boolean` | If`true`, displays the chart legend. |
585
691
  | `labelFontSize` | `number` | Font size for labels and legend text. |
586
692
  | `labelColor` | `string` | Color for labels and legend text. |
587
- | `legendPosition` | `'top' \| 'bottom' \| 'left' \| 'right'` | The position of the legend relative to the chart. |
693
+ | `legendPosition` | `'top' | 'bottom' | 'left' | 'right'` | The position of the legend relative to the chart. |
588
694
  | `renderLabelItem` | `(props: { item, index }) => BoxNode` | A custom render function for chart labels. |
589
695
  | `renderLegendItem` | `(props: { item, index, color }) => BoxNode` | A custom render function for legend items. |
590
696
 
591
697
  ##### Cartesian Chart Options (`bar`, `line`)
592
698
 
593
- | Prop | Type | Description |
594
- |-----------------------|-----------------------------|-------------------------------------------------------------------|
595
- | `gridOptions` | `GridOptions` | An object to configure the grid lines (`show`, `color`, `style`). |
596
- | `axisColor` | `string` | The color of the chart axes. |
597
- | `showValues` | `boolean` | If `true`, displays values on top of bars or points. |
598
- | `valueColor` | `string` | Color of the value labels. |
599
- | `valueFontSize` | `number` | Font size of the value labels. |
600
- | `showYAxis` | `boolean` | If `true`, displays the Y-axis labels on the left. |
601
- | `yAxisColor` | `string` | Color of the Y-axis labels. |
602
- | `yAxisFontSize` | `number` | Font size of the Y-axis labels. |
603
- | `yAxisLabelFormatter` | `(value: number) => string` | Custom formatter for Y-axis labels. Smart defaults adjust decimal precision based on value range. |
604
- | `xAxisLabelFormatter` | `(value: string, index: number) => string` | Custom formatter for X-axis labels. Useful for truncating or transforming labels. |
699
+
700
+ | Prop | Type | Description |
701
+ | --------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
702
+ | `grid` | `GridOptions` | Configures grid lines (`show`, `color`, `style: 'solid' \| 'dashed' \| 'dotted'`). |
703
+ | `axisColor` | `string` | The color of the chart axes. |
704
+ | `showValues` | `boolean` | If `true`, displays values on top of bars or points. |
705
+ | `valueColor` | `string` | Color of the value labels. |
706
+ | `valueFontSize` | `number` | Font size of the value labels. |
707
+ | `renderValueItem` | `(props: { item: number; index: number; datasetIndex: number }) => BoxNode` | Custom render function for each value label above a bar or point. |
708
+ | `showYAxis` | `boolean` | If `true`, displays the Y-axis labels on the left. |
709
+ | `yAxisColor` | `string` | Color of the Y-axis labels. |
710
+ | `yAxisFontSize` | `number` | Font size of the Y-axis labels. |
711
+ | `yAxisLabelFormatter` | `(value: number) => string` | Custom formatter for Y-axis labels. Smart defaults adjust decimal precision based on value range. |
712
+ | `xAxisLabelFormatter` | `(value: string, index: number) => string` | Custom formatter for X-axis labels. Useful for truncating or transforming labels. |
605
713
 
606
714
  ###### Y-Axis Label Formatter
607
715
 
608
716
  The `yAxisLabelFormatter` enables custom Y-axis label formatting. By default, it uses smart formatting:
717
+
609
718
  - **Values < 1**: 4 decimals (e.g., `0.0025`)
610
719
  - **Values 1-100**: 2 decimals (e.g., `25.43`)
611
720
  - **Values 100-1000**: 1 decimal (e.g., `250.5`)
@@ -613,6 +722,7 @@ The `yAxisLabelFormatter` enables custom Y-axis label formatting. By default, it
613
722
  - **Values ≥ 1M**: 1 decimal with "M" suffix (e.g., `1.5M`)
614
723
 
615
724
  Custom example:
725
+
616
726
  ```typescript
617
727
  options: {
618
728
  yAxisLabelFormatter: (value) => `$${value.toFixed(2)}`,
@@ -624,118 +734,24 @@ options: {
624
734
  The `xAxisLabelFormatter` allows custom X-axis label transformations. It receives the label string and its index.
625
735
 
626
736
  Custom example:
737
+
627
738
  ```typescript
628
739
  options: {
629
- xAxisLabelFormatter: (label, index) =>
740
+ xAxisLabelFormatter: (label, index) =>
630
741
  label.length > 5 ? label.substring(0, 5) + '...' : label,
631
742
  }
632
743
  ```
633
744
 
634
745
  ##### Pie & Doughnut Chart Options (`pie`, `doughnut`)
635
746
 
747
+
636
748
  | Prop | Type | Description |
637
- |---------------------|----------|------------------------------------------------------------------------------|
749
+ | ------------------- | -------- | ---------------------------------------------------------------------------- |
638
750
  | `innerRadius` | `number` | The radius of the inner circle in a doughnut chart (0 to 1). Default is 0.6. |
639
751
  | `sliceBorderRadius` | `number` | The border radius for the corners of each slice. Default is 0. |
640
752
 
641
753
  ---
642
754
 
643
- ### Root
644
-
645
- The `Root` component is the entry point for rendering. It is a specialized `ColumnNode` that inherits all `BoxProps`.
646
-
647
- #### Root-Specific Props
648
-
649
- | Prop | Type | Default | Description |
650
- |----------|--------------------------|-------------|----------------------------------------------------------------------|
651
- | `width` | `number` | - | **Required.** Width of the canvas in pixels. |
652
- | `height` | `number` | - | Optional height of the canvas. If not set, it's calculated from content. |
653
- | `scale` | `number` | `1` | Scale factor for rendering (e.g., 2 for 2x resolution). |
654
- | `fonts` | `FontRegistrationInfo[]` | - | An array of font files to register for use in the canvas. |
655
- | `useDiskCache` | `boolean` | `false` | Write fetched images to disk during render for faster re-decode. Disk entries are cleaned up automatically after render completes. |
656
- | `workerMode` | `boolean` | `true` | Enable worker thread rendering for non-blocking operation. |
657
- | `workers` | `number` | `cpus().length - 1` | Number of worker threads to use (only applies on first render with `workerMode: true`). |
658
-
659
- #### Common Inherited Props (from BoxProps)
660
-
661
- Since `Root` extends `BoxProps`, it also accepts:
662
-
663
- | Prop | Type | Description |
664
- |------|------|-------------|
665
- | `children` | `CanvasElement \| CanvasElement[]` | **Required.** The component tree to render. |
666
- | `backgroundColor` | `string` | Canvas background color. |
667
- | `padding` | `number \| object \| string` | Canvas padding. |
668
- | `gradient` | `object` | Background gradient (overrides `backgroundColor`). |
669
- | `boxShadow` | `object \| object[]` | Box shadow effects. |
670
-
671
- > For a complete list of inherited props, see [Box, Row, and Column](#box-row-and-column) above.
672
-
673
- ---
674
-
675
- ### Canvas Methods
676
-
677
- The `Root()` function returns a Canvas object with the following methods and properties:
678
-
679
- #### Export Methods
680
-
681
- | Method | Signature | Description |
682
- |--------|-----------|-------------|
683
- | `toBufferSync` | `(format?: ExportFormat, options?: ExportOptions) => Buffer` | Synchronously returns a buffer. In worker mode, returns the pre-encoded PNG from render. |
684
- | `toBuffer` | `(format: ExportFormat, options?: ExportOptions) => Promise<Buffer>` | Asynchronously encodes to the specified format. |
685
- | `toURL` | `(format: ExportFormat, options?: ExportOptions) => Promise<string>` | Returns a data URL. |
686
- | `toURLSync` | `(format?: ExportFormat, options?: ExportOptions) => string` | Synchronously returns a data URL (from pre-encoded PNG in worker mode). |
687
- | `toFile` | `(filename: string, options?: SaveOptions) => Promise<void>` | Saves the canvas to a file. |
688
- | `toSharp` | `(options?: RenderOptions) => Promise<Buffer>` | Returns a Sharp instance buffer for further processing. |
689
- | `toSharpSync` | `(options?: RenderOptions) => never` | **Throws error.** Use `toSharp()` instead in worker mode. |
690
-
691
- **Supported Export Formats:** `'png'`, `'jpg'` (or `'jpeg'`), `'webp'`, `'pdf'`, `'svg'`, `'raw'`
692
-
693
- #### Canvas Properties
694
-
695
- | Property | Type | Description |
696
- |----------|------|-------------|
697
- | `.width` | `number` | Canvas width in pixels (after scale). |
698
- | `.height` | `number` | Canvas height in pixels (after scale). |
699
-
700
- #### Convenience Getters
701
-
702
- | Getter | Returns | Description |
703
- |--------|---------|-------------|
704
- | `.png` | `Promise<Buffer>` | Shortcut for `toBuffer('png')` |
705
- | `.jpg` | `Promise<Buffer>` | Shortcut for `toBuffer('jpg')` |
706
- | `.webp` | `Promise<Buffer>` | Shortcut for `toBuffer('webp')` |
707
- | `.svg` | `Promise<Buffer>` | Shortcut for `toBuffer('svg')` |
708
- | `.pdf` | `Promise<Buffer>` | Shortcut for `toBuffer('pdf')` |
709
- | `.raw` | `Promise<Buffer>` | Shortcut for `toBuffer('raw')` - raw pixel data |
710
-
711
- #### Memory Management (Worker Mode)
712
-
713
- | Method | Description |
714
- |--------|-------------|
715
- | `.release()` | **Required in worker mode.** Releases the Canvas from worker memory. Call when done to prevent memory leaks. |
716
-
717
- ```typescript
718
- import { Root } from '@meonode/canvas'
719
-
720
- // Render with default worker mode (enabled)
721
- const canvas = await Root({ width: 400, height: 400, children: [...] })
722
-
723
- // Or explicitly disable worker mode
724
- const canvas = await Root({ width: 400, height: 400, children: [...], workerMode: false })
725
-
726
- // Use the canvas
727
- const png = await canvas.png
728
- const jpg = await canvas.jpg
729
- await canvas.toFile('output.png')
730
-
731
- // Release memory (worker mode only)
732
- canvas.release()
733
- ```
734
-
735
- > **Note:** A FinalizationRegistry provides automatic cleanup for forgotten `.release()` calls, but explicit cleanup is recommended for deterministic memory management in production.
736
-
737
- ---
738
-
739
755
  ### Cleanup Functions
740
756
 
741
757
  #### `terminate()`
@@ -743,7 +759,7 @@ canvas.release()
743
759
  Terminate all worker pools and free worker thread resources. Call this when shutting down a long-running server.
744
760
 
745
761
  ```typescript
746
- import { terminate } from '@meonode/canvas'
762
+ import {terminate} from '@meonode/canvas'
747
763
 
748
764
  // Call on server shutdown
749
765
  process.on('SIGTERM', () => {
@@ -759,9 +775,8 @@ process.on('SIGTERM', () => {
759
775
  Manually clear the entire disk cache directory. Useful for debugging or forced cleanup.
760
776
 
761
777
  ```typescript
762
- import { clearDiskCache } from '@meonode/canvas'
778
+ import {clearDiskCache} from '@meonode/canvas'
763
779
 
764
- // Clear all disk cache
765
780
  await clearDiskCache()
766
781
  ```
767
782
 
@@ -778,7 +793,7 @@ await clearDiskCache()
778
793
  Configure the canvas rendering engine. Call once at startup.
779
794
 
780
795
  ```typescript
781
- import { configure } from '@meonode/canvas'
796
+ import {configure} from '@meonode/canvas'
782
797
 
783
798
  configure({
784
799
  workerMode: true, // Default: true
@@ -786,10 +801,11 @@ configure({
786
801
  })
787
802
  ```
788
803
 
789
- | Option | Type | Default | Description |
790
- |--------|------|---------|-------------|
791
- | `workerMode` | `boolean` | `true` | Enable worker thread rendering for non-blocking operation |
792
- | `workers` | `number` | `cpus().length - 1` | Number of worker threads in the pool |
804
+
805
+ | Option | Type | Default | Description |
806
+ | ------------ | --------- | ------------------- | --------------------------------------------------------- |
807
+ | `workerMode` | `boolean` | `true` | Enable worker thread rendering for non-blocking operation |
808
+ | `workers` | `number` | `cpus().length - 1` | Number of worker threads in the pool |
793
809
 
794
810
  ## Contributing
795
811