@meonode/canvas 1.0.0-beta.3 → 1.0.0-beta.5

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 (48) hide show
  1. package/Readme.md +1 -1
  2. package/dist/cjs/canvas/canvas.helper.d.ts +9 -11
  3. package/dist/cjs/canvas/canvas.helper.d.ts.map +1 -1
  4. package/dist/cjs/canvas/canvas.helper.js +47 -48
  5. package/dist/cjs/canvas/canvas.helper.js.map +1 -1
  6. package/dist/cjs/canvas/canvas.type.d.ts +31 -31
  7. package/dist/cjs/canvas/canvas.type.d.ts.map +1 -1
  8. package/dist/cjs/canvas/grid.canvas.util.d.ts +4 -4
  9. package/dist/cjs/canvas/grid.canvas.util.d.ts.map +1 -1
  10. package/dist/cjs/canvas/grid.canvas.util.js +21 -4
  11. package/dist/cjs/canvas/grid.canvas.util.js.map +1 -1
  12. package/dist/cjs/canvas/image.canvas.util.d.ts +0 -1
  13. package/dist/cjs/canvas/image.canvas.util.d.ts.map +1 -1
  14. package/dist/cjs/canvas/image.canvas.util.js +72 -72
  15. package/dist/cjs/canvas/image.canvas.util.js.map +1 -1
  16. package/dist/cjs/canvas/layout.canvas.util.d.ts +16 -17
  17. package/dist/cjs/canvas/layout.canvas.util.d.ts.map +1 -1
  18. package/dist/cjs/canvas/layout.canvas.util.js +17 -24
  19. package/dist/cjs/canvas/layout.canvas.util.js.map +1 -1
  20. package/dist/cjs/canvas/root.canvas.util.d.ts +4 -2
  21. package/dist/cjs/canvas/root.canvas.util.d.ts.map +1 -1
  22. package/dist/cjs/canvas/root.canvas.util.js +7 -3
  23. package/dist/cjs/canvas/root.canvas.util.js.map +1 -1
  24. package/dist/cjs/canvas/text.canvas.util.d.ts +20 -27
  25. package/dist/cjs/canvas/text.canvas.util.d.ts.map +1 -1
  26. package/dist/cjs/canvas/text.canvas.util.js +27 -45
  27. package/dist/cjs/canvas/text.canvas.util.js.map +1 -1
  28. package/dist/esm/canvas/canvas.helper.d.ts +9 -11
  29. package/dist/esm/canvas/canvas.helper.d.ts.map +1 -1
  30. package/dist/esm/canvas/canvas.helper.js +47 -48
  31. package/dist/esm/canvas/canvas.type.d.ts +31 -31
  32. package/dist/esm/canvas/canvas.type.d.ts.map +1 -1
  33. package/dist/esm/canvas/grid.canvas.util.d.ts +4 -4
  34. package/dist/esm/canvas/grid.canvas.util.d.ts.map +1 -1
  35. package/dist/esm/canvas/grid.canvas.util.js +21 -4
  36. package/dist/esm/canvas/image.canvas.util.d.ts +0 -1
  37. package/dist/esm/canvas/image.canvas.util.d.ts.map +1 -1
  38. package/dist/esm/canvas/image.canvas.util.js +72 -72
  39. package/dist/esm/canvas/layout.canvas.util.d.ts +16 -17
  40. package/dist/esm/canvas/layout.canvas.util.d.ts.map +1 -1
  41. package/dist/esm/canvas/layout.canvas.util.js +17 -24
  42. package/dist/esm/canvas/root.canvas.util.d.ts +4 -2
  43. package/dist/esm/canvas/root.canvas.util.d.ts.map +1 -1
  44. package/dist/esm/canvas/root.canvas.util.js +7 -3
  45. package/dist/esm/canvas/text.canvas.util.d.ts +20 -27
  46. package/dist/esm/canvas/text.canvas.util.d.ts.map +1 -1
  47. package/dist/esm/canvas/text.canvas.util.js +27 -45
  48. package/package.json +16 -9
@@ -4,6 +4,7 @@ import { parseBorderRadius, drawRoundedRectPath } from './canvas.helper.js';
4
4
  import { promises } from 'fs';
5
5
  import { Style } from '../constant/common.const.js';
6
6
 
7
+ // TODO: Add comprehensive unit tests for this file.
7
8
  /**
8
9
  * Calculates pixel offset for image positioning based on percentage or pixel values.
9
10
  * This handles centering, edge alignment, and percentage-based positioning.
@@ -43,7 +44,6 @@ class ImageNode extends BoxNode {
43
44
  /**
44
45
  * Loads and processes an image from various sources (URL, file path, or Buffer).
45
46
  * Handles SVG color modifications and sets natural dimensions with an aspect ratio.
46
- *
47
47
  * @returns Promise that resolves when image loading completes
48
48
  * @throws Error if image loading fails
49
49
  */
@@ -59,92 +59,92 @@ class ImageNode extends BoxNode {
59
59
  this.naturalHeight = 0;
60
60
  return Promise.resolve();
61
61
  }
62
- return new Promise(async (resolve) => {
63
- const { fileTypeFromBuffer, fileTypeFromFile } = await import('file-type');
64
- let finalSource = this.props.src;
65
- let isSvg = false;
66
- let contentBuffer = null;
67
- let detectedMime;
68
- try {
69
- if (typeof this.props.src === 'string') {
70
- if (this.props.src.startsWith('http')) {
71
- const response = await fetch(this.props.src);
72
- if (!response.ok) {
73
- throw new Error(`HTTP error ${response.status} fetching image: ${this.props.src}`);
74
- }
75
- const imageArrayBuffer = await response.arrayBuffer();
76
- contentBuffer = Buffer.from(imageArrayBuffer);
77
- finalSource = contentBuffer;
78
- const fileTypeResult = await fileTypeFromBuffer(contentBuffer);
79
- detectedMime = fileTypeResult?.mime;
80
- isSvg = detectedMime === 'image/svg+xml';
81
- if ((!detectedMime || detectedMime === 'application/xml') &&
82
- contentBuffer.toString('utf-8').includes('<svg')) {
83
- isSvg = true;
84
- }
85
- }
86
- else {
87
- finalSource = this.props.src;
88
- const filePath = this.props.src;
89
- try {
90
- const fileTypeResult = await fileTypeFromFile(filePath);
62
+ return new Promise(resolve => {
63
+ const load = async () => {
64
+ const { fileTypeFromBuffer, fileTypeFromFile } = await import('file-type');
65
+ let finalSource = this.props.src;
66
+ let isSvg = false;
67
+ let contentBuffer = null;
68
+ let detectedMime;
69
+ try {
70
+ if (typeof this.props.src === 'string') {
71
+ if (this.props.src.startsWith('http')) {
72
+ const response = await fetch(this.props.src);
73
+ if (!response.ok) {
74
+ throw new Error(`HTTP error ${response.status} fetching image: ${this.props.src}`);
75
+ }
76
+ const imageArrayBuffer = await response.arrayBuffer();
77
+ contentBuffer = Buffer.from(imageArrayBuffer);
78
+ finalSource = contentBuffer;
79
+ const fileTypeResult = await fileTypeFromBuffer(contentBuffer);
91
80
  detectedMime = fileTypeResult?.mime;
92
81
  isSvg = detectedMime === 'image/svg+xml';
93
- if ((!detectedMime || detectedMime === 'application/xml') && filePath.toLowerCase().endsWith('.svg')) {
82
+ if ((!detectedMime || detectedMime === 'application/xml') && contentBuffer.toString('utf-8').includes('<svg')) {
94
83
  isSvg = true;
95
84
  }
96
85
  }
97
- catch {
98
- isSvg = filePath.toLowerCase().endsWith('.svg');
99
- }
100
- if (isSvg && this.props.color) {
86
+ else {
87
+ finalSource = this.props.src;
88
+ const filePath = this.props.src;
101
89
  try {
102
- contentBuffer = await promises.readFile(filePath);
90
+ const fileTypeResult = await fileTypeFromFile(filePath);
91
+ detectedMime = fileTypeResult?.mime;
92
+ isSvg = detectedMime === 'image/svg+xml';
93
+ if ((!detectedMime || detectedMime === 'application/xml') && filePath.toLowerCase().endsWith('.svg')) {
94
+ isSvg = true;
95
+ }
103
96
  }
104
97
  catch {
105
- isSvg = false;
106
- contentBuffer = null;
98
+ isSvg = filePath.toLowerCase().endsWith('.svg');
99
+ }
100
+ if (isSvg && this.props.color) {
101
+ try {
102
+ contentBuffer = await promises.readFile(filePath);
103
+ }
104
+ catch {
105
+ isSvg = false;
106
+ contentBuffer = null;
107
+ }
107
108
  }
108
109
  }
109
110
  }
110
- }
111
- else {
112
- contentBuffer = this.props.src;
113
- finalSource = contentBuffer;
114
- const fileTypeResult = await fileTypeFromBuffer(contentBuffer);
115
- detectedMime = fileTypeResult?.mime;
116
- isSvg = detectedMime === 'image/svg+xml';
117
- }
118
- if (isSvg && this.props.color && contentBuffer) {
119
- const svgString = contentBuffer.toString('utf-8');
120
- const modifiedSvgString = svgString.replace(/fill="[^"]*"/g, `fill="${this.props.color}"`);
121
- if (modifiedSvgString !== svgString) {
122
- finalSource = Buffer.from(modifiedSvgString);
123
- }
124
111
  else {
112
+ contentBuffer = this.props.src;
125
113
  finalSource = contentBuffer;
114
+ const fileTypeResult = await fileTypeFromBuffer(contentBuffer);
115
+ detectedMime = fileTypeResult?.mime;
116
+ isSvg = detectedMime === 'image/svg+xml';
126
117
  }
118
+ if (isSvg && this.props.color && contentBuffer) {
119
+ const svgString = contentBuffer.toString('utf-8');
120
+ const modifiedSvgString = svgString.replace(/fill="[^"]*"/g, `fill="${this.props.color}"`);
121
+ if (modifiedSvgString !== svgString) {
122
+ finalSource = Buffer.from(modifiedSvgString);
123
+ }
124
+ else {
125
+ finalSource = contentBuffer;
126
+ }
127
+ }
128
+ const img = await loadImage(finalSource);
129
+ this.loadedImage = img;
130
+ this.naturalWidth = img.width;
131
+ this.naturalHeight = img.height;
132
+ const calculatedAspectRatio = this.naturalWidth > 0 && this.naturalHeight > 0 ? this.naturalWidth / this.naturalHeight : undefined;
133
+ const finalAspectRatio = typeof this.props.aspectRatio === 'number' && this.props.aspectRatio > 0 ? this.props.aspectRatio : calculatedAspectRatio;
134
+ this.node.setAspectRatio(finalAspectRatio);
135
+ this.props.onLoad?.();
136
+ resolve();
127
137
  }
128
- const img = await loadImage(finalSource);
129
- this.loadedImage = img;
130
- this.naturalWidth = img.width;
131
- this.naturalHeight = img.height;
132
- const calculatedAspectRatio = this.naturalWidth > 0 && this.naturalHeight > 0 ? this.naturalWidth / this.naturalHeight : undefined;
133
- const finalAspectRatio = typeof this.props.aspectRatio === 'number' && this.props.aspectRatio > 0
134
- ? this.props.aspectRatio
135
- : calculatedAspectRatio;
136
- this.node.setAspectRatio(finalAspectRatio);
137
- this.props.onLoad?.();
138
- resolve();
139
- }
140
- catch (error) {
141
- this.naturalWidth = 0;
142
- this.naturalHeight = 0;
143
- const finalAspectRatioOnError = typeof this.props.aspectRatio === 'number' && this.props.aspectRatio > 0 ? this.props.aspectRatio : undefined;
144
- this.node.setAspectRatio(finalAspectRatioOnError);
145
- this.props.onError?.(error);
146
- resolve();
147
- }
138
+ catch (error) {
139
+ this.naturalWidth = 0;
140
+ this.naturalHeight = 0;
141
+ const finalAspectRatioOnError = typeof this.props.aspectRatio === 'number' && this.props.aspectRatio > 0 ? this.props.aspectRatio : undefined;
142
+ this.node.setAspectRatio(finalAspectRatioOnError);
143
+ this.props.onError?.(error);
144
+ resolve();
145
+ }
146
+ };
147
+ load();
148
148
  });
149
149
  }
150
150
  getLoadingPromise() {
@@ -33,7 +33,7 @@ export declare class BoxNode {
33
33
  key?: string;
34
34
  /**
35
35
  * Creates a new BoxNode instance
36
- * @param props - Initial box properties and styling
36
+ * @param props Initial box properties and styling
37
37
  */
38
38
  constructor(props?: BoxProps & BaseProps);
39
39
  /**
@@ -42,7 +42,7 @@ export declare class BoxNode {
42
42
  processInitialChildren(): void;
43
43
  /**
44
44
  * Inherits styles from the parent node.
45
- * @param {BoxProps & BaseProps} parentProps - Parent node properties to inherit from.
45
+ * @param {BoxProps & BaseProps} parentProps Parent node properties to inherit from.
46
46
  */
47
47
  protected resolveInheritedStyles(parentProps: BoxProps & BaseProps): void;
48
48
  /**
@@ -51,8 +51,8 @@ export declare class BoxNode {
51
51
  protected applyDefaults(): void;
52
52
  /**
53
53
  * Appends a child node at the specified index.
54
- * @param {BoxNode} child - Child node to append.
55
- * @param index - Index to insert child at
54
+ * @param {BoxNode} child Child node to append.
55
+ * @param index Index to insert child at
56
56
  */
57
57
  protected appendChild(child: BoxNode, index: number): void;
58
58
  /**
@@ -66,31 +66,30 @@ export declare class BoxNode {
66
66
  protected updateLayoutBasedOnComputedSize(): void;
67
67
  /**
68
68
  * Applies layout properties to the Yoga node.
69
- * @param props - Box properties containing layout values
69
+ * @param props Box properties containing layout values
70
70
  */
71
71
  protected setLayout(props: BoxProps): void;
72
72
  /**
73
73
  * Renders the node and its children to the canvas.
74
- * @param {CanvasRenderingContext2D} ctx - Canvas rendering context (from skia-canvas).
75
- * @param {number} offsetX - X offset for rendering.
76
- * @param {number} offsetY - Y offset for rendering.
74
+ * @param {CanvasRenderingContext2D} ctx Canvas rendering context (from skia-canvas).
75
+ * @param {number} offsetX X offset for rendering.
76
+ * @param {number} offsetY Y offset for rendering.
77
77
  */
78
78
  render(ctx: CanvasRenderingContext2D, offsetX?: number, offsetY?: number): void;
79
79
  /**
80
80
  * Renders the node's visual content including background fills, shadows, and borders.
81
81
  * This is an internal method used by the render() pipeline.
82
- *
83
- * @param ctx - The skia-canvas 2D rendering context to draw into
84
- * @param x - The absolute x-coordinate where drawing should begin
85
- * @param y - The absolute y-coordinate where drawing should begin
86
- * @param width - The width of the content area to render
87
- * @param height - The height of the content area to render
82
+ * @param ctx The skia-canvas 2D rendering context to draw into
83
+ * @param x The absolute x-coordinate where drawing should begin
84
+ * @param y The absolute y-coordinate where drawing should begin
85
+ * @param width The width of the content area to render
86
+ * @param height The height of the content area to render
88
87
  */
89
88
  protected _renderContent(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number): void;
90
89
  }
91
90
  /**
92
91
  * Creates a new BoxNode instance.
93
- * @param {BoxProps} props - Box properties and configuration.
92
+ * @param {BoxProps} props Box properties and configuration.
94
93
  * @returns {BoxNode} New BoxNode instance.
95
94
  */
96
95
  export declare const Box: (props: BoxProps) => BoxNode;
@@ -103,7 +102,7 @@ export declare class ColumnNode extends BoxNode {
103
102
  }
104
103
  /**
105
104
  * Creates a new ColumnNode instance.
106
- * @param {BoxProps} props - Column properties and configuration.
105
+ * @param {BoxProps} props Column properties and configuration.
107
106
  * @returns {ColumnNode} New ColumnNode instance.
108
107
  */
109
108
  export declare const Column: (props: BoxProps) => ColumnNode;
@@ -116,7 +115,7 @@ export declare class RowNode extends BoxNode {
116
115
  }
117
116
  /**
118
117
  * Creates a new RowNode instance.
119
- * @param {BoxProps} props - Row properties and configuration.
118
+ * @param {BoxProps} props Row properties and configuration.
120
119
  * @returns {RowNode} New RowNode instance.
121
120
  */
122
121
  export declare const Row: (props: BoxProps) => RowNode;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/layout.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,yBAAyB,CAAA;AAGlF,OAAa,EAAS,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAE9D;;;;GAIG;AACH,qBAAa,OAAO;IAClB;;OAEG;IACH,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/B;;OAEG;IACH,IAAI,EAAE,IAAI,CAAA;IACV;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB;;OAEG;IACH,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC3B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;gBACS,KAAK,GAAE,QAAQ,GAAG,SAAc;IAqB5C;;OAEG;IACI,sBAAsB;IAW7B;;;OAGG;IACH,SAAS,CAAC,sBAAsB,CAAC,WAAW,EAAE,QAAQ,GAAG,SAAS;IAkClE;;OAEG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAI/B;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAanD;;;OAGG;IACI,cAAc;IAiBrB;;OAEG;IACH,SAAS,CAAC,+BAA+B;IAIzC;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ;IAqInC;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,wBAAwB,EAAE,OAAO,SAAI,EAAE,OAAO,SAAI;IAqK9D;;;;;;;;;OASG;IACH,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CA6R5G;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,QAAQ,YAAuB,CAAA;AAE1D;;;GAGG;AACH,qBAAa,UAAW,SAAQ,OAAO;gBACzB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,OAAO,QAAQ,eAA0B,CAAA;AAEhE;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,OAAO;gBACtB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,QAAQ,YAAuB,CAAA"}
1
+ {"version":3,"file":"layout.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/layout.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,yBAAyB,CAAA;AAGlF,OAAa,EAAS,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAE9D;;;;GAIG;AACH,qBAAa,OAAO;IAClB;;OAEG;IACH,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE/B;;OAEG;IACH,IAAI,EAAE,IAAI,CAAA;IAEV;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAA;IAEnB;;OAEG;IACH,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAA;IAE3B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IAEtB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;OAGG;gBACS,KAAK,GAAE,QAAQ,GAAG,SAAc;IAqB5C;;OAEG;IACI,sBAAsB;IAW7B;;;OAGG;IACH,SAAS,CAAC,sBAAsB,CAAC,WAAW,EAAE,QAAQ,GAAG,SAAS;IAkClE;;OAEG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAI/B;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAanD;;;OAGG;IACI,cAAc,IAAI,OAAO;IAiBhC;;OAEG;IACH,SAAS,CAAC,+BAA+B;IAIzC;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ;IAqInC;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,wBAAwB,EAAE,OAAO,GAAE,MAAU,EAAE,OAAO,GAAE,MAAU;IA+J9E;;;;;;;;OAQG;IACH,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAoR5G;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,QAAQ,KAAG,OAA6B,CAAA;AAEnE;;;GAGG;AACH,qBAAa,UAAW,SAAQ,OAAO;gBACzB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,OAAO,QAAQ,KAAG,UAAmC,CAAA;AAE5E;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,OAAO;gBACtB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,QAAQ,KAAG,OAA6B,CAAA"}
@@ -37,7 +37,7 @@ class BoxNode {
37
37
  key;
38
38
  /**
39
39
  * Creates a new BoxNode instance
40
- * @param props - Initial box properties and styling
40
+ * @param props Initial box properties and styling
41
41
  */
42
42
  constructor(props = {}) {
43
43
  const children = (Array.isArray(props?.children) ? props.children : [props.children]).filter(child => child);
@@ -72,7 +72,7 @@ class BoxNode {
72
72
  }
73
73
  /**
74
74
  * Inherits styles from the parent node.
75
- * @param {BoxProps & BaseProps} parentProps - Parent node properties to inherit from.
75
+ * @param {BoxProps & BaseProps} parentProps Parent node properties to inherit from.
76
76
  */
77
77
  resolveInheritedStyles(parentProps) {
78
78
  if (parentProps.key) {
@@ -112,8 +112,8 @@ class BoxNode {
112
112
  }
113
113
  /**
114
114
  * Appends a child node at the specified index.
115
- * @param {BoxNode} child - Child node to append.
116
- * @param index - Index to insert child at
115
+ * @param {BoxNode} child Child node to append.
116
+ * @param index Index to insert child at
117
117
  */
118
118
  appendChild(child, index) {
119
119
  if (!child || !child.node) {
@@ -152,7 +152,7 @@ class BoxNode {
152
152
  }
153
153
  /**
154
154
  * Applies layout properties to the Yoga node.
155
- * @param props - Box properties containing layout values
155
+ * @param props Box properties containing layout values
156
156
  */
157
157
  setLayout(props) {
158
158
  // --- Yoga layout property application ---
@@ -295,9 +295,9 @@ class BoxNode {
295
295
  }
296
296
  /**
297
297
  * Renders the node and its children to the canvas.
298
- * @param {CanvasRenderingContext2D} ctx - Canvas rendering context (from skia-canvas).
299
- * @param {number} offsetX - X offset for rendering.
300
- * @param {number} offsetY - Y offset for rendering.
298
+ * @param {CanvasRenderingContext2D} ctx Canvas rendering context (from skia-canvas).
299
+ * @param {number} offsetX X offset for rendering.
300
+ * @param {number} offsetY Y offset for rendering.
301
301
  */
302
302
  render(ctx, offsetX = 0, offsetY = 0) {
303
303
  const layout = this.node.getComputedLayout();
@@ -322,13 +322,7 @@ class BoxNode {
322
322
  try {
323
323
  // --- Transformation Setup ---
324
324
  const transform = this.props.transform;
325
- const needsTransform = transform &&
326
- (transform.translateX ||
327
- transform.translateY ||
328
- transform.rotate ||
329
- transform.scale ||
330
- transform.scaleX ||
331
- transform.scaleY);
325
+ const needsTransform = transform && (transform.translateX || transform.translateY || transform.rotate || transform.scale || transform.scaleX || transform.scaleY);
332
326
  let savedContextForTransform = false;
333
327
  if (needsTransform) {
334
328
  ctx.save();
@@ -455,12 +449,11 @@ class BoxNode {
455
449
  /**
456
450
  * Renders the node's visual content including background fills, shadows, and borders.
457
451
  * This is an internal method used by the render() pipeline.
458
- *
459
- * @param ctx - The skia-canvas 2D rendering context to draw into
460
- * @param x - The absolute x-coordinate where drawing should begin
461
- * @param y - The absolute y-coordinate where drawing should begin
462
- * @param width - The width of the content area to render
463
- * @param height - The height of the content area to render
452
+ * @param ctx The skia-canvas 2D rendering context to draw into
453
+ * @param x The absolute x-coordinate where drawing should begin
454
+ * @param y The absolute y-coordinate where drawing should begin
455
+ * @param width The width of the content area to render
456
+ * @param height The height of the content area to render
464
457
  */
465
458
  _renderContent(ctx, x, y, width, height) {
466
459
  // Calculate border radius values for all corners
@@ -727,7 +720,7 @@ class BoxNode {
727
720
  }
728
721
  /**
729
722
  * Creates a new BoxNode instance.
730
- * @param {BoxProps} props - Box properties and configuration.
723
+ * @param {BoxProps} props Box properties and configuration.
731
724
  * @returns {BoxNode} New BoxNode instance.
732
725
  */
733
726
  const Box = (props) => new BoxNode(props);
@@ -748,7 +741,7 @@ class ColumnNode extends BoxNode {
748
741
  }
749
742
  /**
750
743
  * Creates a new ColumnNode instance.
751
- * @param {BoxProps} props - Column properties and configuration.
744
+ * @param {BoxProps} props Column properties and configuration.
752
745
  * @returns {ColumnNode} New ColumnNode instance.
753
746
  */
754
747
  const Column = (props) => new ColumnNode(props);
@@ -769,7 +762,7 @@ class RowNode extends BoxNode {
769
762
  }
770
763
  /**
771
764
  * Creates a new RowNode instance.
772
- * @param {BoxProps} props - Row properties and configuration.
765
+ * @param {BoxProps} props Row properties and configuration.
773
766
  * @returns {RowNode} New RowNode instance.
774
767
  */
775
768
  const Row = (props) => new RowNode(props);
@@ -13,11 +13,13 @@ export declare class RootNode extends ColumnNode {
13
13
  private ctx;
14
14
  /** Target width for the canvas in pixels */
15
15
  private readonly targetWidth;
16
+ /** Target height for the canvas in pixels */
17
+ private readonly targetHeight;
16
18
  /** Scale factor for rendering (e.g. 2 for 2x resolution) */
17
19
  private readonly scale;
18
20
  /**
19
21
  * Creates a new root node for canvas rendering
20
- * @param props - Configuration properties for the root node
22
+ * @param props Configuration properties for the root node
21
23
  * @throws Error if width property is not provided
22
24
  */
23
25
  constructor(props: RootProps & BaseProps);
@@ -35,7 +37,7 @@ export declare class RootNode extends ColumnNode {
35
37
  }
36
38
  /**
37
39
  * Creates and renders a new root node with the given properties
38
- * @param props - Configuration properties for the root node
40
+ * @param props Configuration properties for the root node
39
41
  * @returns Promise resolving to the rendered Canvas instance
40
42
  */
41
43
  export declare const Root: (props: RootProps) => Promise<Canvas>;
@@ -1 +1 @@
1
- {"version":3,"file":"root.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/root.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA8C,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,UAAU,EAAW,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAUnE,eAAO,MAAM,qBAAqB,YAEjC,CAAA;AAED;;;GAGG;AACH,qBAAa,QAAS,SAAQ,UAAU;IACtC,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAoB;IAClC,8CAA8C;IAC9C,OAAO,CAAC,GAAG,CAAwC;IACnD,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;;;OAIG;gBACS,KAAK,EAAE,SAAS,GAAG,SAAS;IAsCxC;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CAqChC;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,GAAU,OAAO,SAAS,oBAAuC,CAAA"}
1
+ {"version":3,"file":"root.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/root.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA8C,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,UAAU,EAAW,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAUnE,eAAO,MAAM,qBAAqB,YAEjC,CAAA;AAED;;;GAGG;AACH,qBAAa,QAAS,SAAQ,UAAU;IACtC,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAoB;IAClC,8CAA8C;IAC9C,OAAO,CAAC,GAAG,CAAwC;IACnD,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;;;OAIG;gBACS,KAAK,EAAE,SAAS,GAAG,SAAS;IAyCxC;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CAqChC;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,GAAU,OAAO,SAAS,oBAAuC,CAAA"}
@@ -18,16 +18,19 @@ class RootNode extends ColumnNode {
18
18
  ctx = null;
19
19
  /** Target width for the canvas in pixels */
20
20
  targetWidth;
21
+ /** Target height for the canvas in pixels */
22
+ targetHeight;
21
23
  /** Scale factor for rendering (e.g. 2 for 2x resolution) */
22
24
  scale;
23
25
  /**
24
26
  * Creates a new root node for canvas rendering
25
- * @param props - Configuration properties for the root node
27
+ * @param props Configuration properties for the root node
26
28
  * @throws Error if width property is not provided
27
29
  */
28
30
  constructor(props) {
29
31
  // Call the parent constructor with root name and props
30
32
  super({ name: 'Root', ...props });
33
+ this.props = props;
31
34
  // Validate the required width property
32
35
  if (!props.width) {
33
36
  throw new Error('Width and height are required for Root');
@@ -51,6 +54,7 @@ class RootNode extends ColumnNode {
51
54
  // Set up scale and width
52
55
  this.scale = props.scale || 1;
53
56
  this.targetWidth = props.width;
57
+ this.targetHeight = props.height;
54
58
  this.node.setWidth(this.targetWidth);
55
59
  // Initialize children nodes
56
60
  this.processInitialChildren();
@@ -93,7 +97,7 @@ class RootNode extends ColumnNode {
93
97
  // Step 4: Create a canvas with calculated dimensions
94
98
  const calculatedContentHeight = this.node.getComputedHeight();
95
99
  const finalCanvasWidth = Math.ceil(this.targetWidth * this.scale);
96
- const finalCanvasHeight = Math.max(1, Math.ceil(calculatedContentHeight * this.scale));
100
+ const finalCanvasHeight = this.targetHeight ? Math.ceil(this.targetHeight * this.scale) : Math.max(1, Math.ceil(calculatedContentHeight * this.scale));
97
101
  // Step 5: Set up canvas context
98
102
  this.canvas = new Canvas(finalCanvasWidth, finalCanvasHeight);
99
103
  this.ctx = this.canvas.getContext('2d');
@@ -108,7 +112,7 @@ class RootNode extends ColumnNode {
108
112
  }
109
113
  /**
110
114
  * Creates and renders a new root node with the given properties
111
- * @param props - Configuration properties for the root node
115
+ * @param props Configuration properties for the root node
112
116
  * @returns Promise resolving to the rendered Canvas instance
113
117
  */
114
118
  const Root = async (props) => await new RootNode(props).render();
@@ -33,8 +33,7 @@ export declare class TextNode extends BoxNode {
33
33
  * - \b - Backspace (removed)
34
34
  * - \f - Form feed (treated as newline)
35
35
  * - \v - Vertical tab (treated as newline)
36
- *
37
- * @param input - Raw text string potentially containing escape sequences
36
+ * @param input Raw text string potentially containing escape sequences
38
37
  * @returns Processed string with escape sequences converted
39
38
  */
40
39
  private processEscapeSequences;
@@ -52,9 +51,8 @@ export declare class TextNode extends BoxNode {
52
51
  * <color="red">, <color='red'>, <color=red>
53
52
  *
54
53
  * Tags can be nested and must be properly closed with </tag>
55
- *
56
- * @param input - Text string containing markup tags
57
- * @param baseStyle - Default style properties to apply to all segments
54
+ * @param input Text string containing markup tags
55
+ * @param baseStyle Default style properties to apply to all segments
58
56
  * @returns Array of styled text segments with consistent style properties
59
57
  */
60
58
  private parseRichText;
@@ -69,8 +67,7 @@ export declare class TextNode extends BoxNode {
69
67
  * - Style: segment <i> > base fontStyle
70
68
  * - Size: segment size > base fontSize
71
69
  * - Family: base fontFamily
72
- *
73
- * @param segmentStyle - Optional TextSegment styling to override base props
70
+ * @param segmentStyle Optional TextSegment styling to override base props
74
71
  * @returns Formatted CSS font string for canvas context
75
72
  */
76
73
  private getFontString;
@@ -87,33 +84,30 @@ export declare class TextNode extends BoxNode {
87
84
  * 2. Otherwise calculating dynamic height based on largest font size per line
88
85
  * 3. Adding leading space above/below text content
89
86
  * 4. Including specified line gaps between lines
90
- *
91
- * @param widthConstraint - Maximum allowed width in pixels for text layout
92
- * @param widthMode - YogaLayout mode determining how width constraint is applied
87
+ * @param widthConstraint Maximum allowed width in pixels for text layout
88
+ * @param widthMode YogaLayout mode determining how width constraint is applied
93
89
  * @returns Calculated minimum dimensions required to render text content
94
- * - width: Total width needed for text layout
95
- * - height: Total height including line heights and gaps
90
+ * - width: Total width needed for text layout
91
+ * - height: Total height including line heights and gaps
96
92
  */
97
93
  private measureText;
98
94
  /**
99
95
  * Wraps text segments into multiple lines while respecting width constraints and preserving styling.
100
96
  * Handles rich text attributes (color, weight, size, bold, italic) and proper word wrapping.
101
97
  * Also respects explicit newline characters (\n) for forced line breaks.
102
- *
103
- * @param ctx - Canvas rendering context used for text measurements
104
- * @param segments - Array of text segments with styling information
105
- * @param maxWidth - Maximum allowed width for each line in pixels
106
- * @param parsedWordSpacingPx - Additional spacing to add between words in pixels
98
+ * @param ctx Canvas rendering context used for text measurements
99
+ * @param segments Array of text segments with styling information
100
+ * @param maxWidth Maximum allowed width for each line in pixels
101
+ * @param parsedWordSpacingPx Additional spacing to add between words in pixels
107
102
  * @returns Array of lines, where each line contains styled text segments
108
103
  */
109
104
  private wrapTextRich;
110
105
  /**
111
106
  * Breaks a word segment into multiple segments that each fit within the specified width constraint.
112
107
  * Maintains all styling properties (color, weight, size, bold, italic) across broken segments.
113
- *
114
- * @param ctx - Canvas rendering context used for text measurements
115
- * @param segmentToBreak - Original text segment to split
116
- * @param maxWidth - Maximum width allowed for each resulting segment
108
+ * @param ctx Canvas rendering context used for text measurements
109
+ * @param segmentToBreak Original text segment to split
110
+ * @param maxWidth Maximum width allowed for each resulting segment
117
111
  * @returns Array of TextSegments, each fitting maxWidth, or original segment if no breaking needed
118
112
  */
119
113
  private breakWordRich;
@@ -132,12 +126,11 @@ export declare class TextNode extends BoxNode {
132
126
  * - Ellipsis truncation
133
127
  * - Rich text styling per segment (color, weight, size, etc)
134
128
  * - Performance optimizations (clipping, visibility checks)
135
- *
136
- * @param ctx - Canvas rendering context
137
- * @param x - Content box left position in pixels
138
- * @param y - Content box top position in pixels
139
- * @param width - Content box total width including padding
140
- * @param height - Content box total height including padding
129
+ * @param ctx Canvas rendering context
130
+ * @param x Content box left position in pixels
131
+ * @param y Content box top position in pixels
132
+ * @param width Content box total width including padding
133
+ * @param height Content box total height including padding
141
134
  */
142
135
  protected _renderContent(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number): void;
143
136
  }
@@ -1 +1 @@
1
- {"version":3,"file":"text.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/text.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,yBAAyB,CAAA;AACrE,OAAO,EAAU,KAAK,wBAAwB,EAA2B,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAGxD;;;GAGG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAW;IACzC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,kBAAkB,CAAe;IAEjC,KAAK,EAAE,SAAS,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;gBAElC,IAAI,GAAE,MAAM,GAAG,MAAW,EAAE,KAAK,GAAE,SAAc;cAuB1C,aAAa,IAAI,IAAI;IA+DxC;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,sBAAsB;IA8B9B;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,aAAa;IA+ErB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,gBAAgB;IAyBxB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,aAAa;IAiCrB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAQjC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,WAAW;IA+OnB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,YAAY;IAkLpB;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAmErB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;;;;;;;;;;;;;;OAiBG;cACgB,cAAc,CAC/B,GAAG,EAAE,wBAAwB,EAC7B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;CAiWjB;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,SAAS,aAA8B,CAAA"}
1
+ {"version":3,"file":"text.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/text.canvas.util.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,yBAAyB,CAAA;AACrE,OAAO,EAAU,KAAK,wBAAwB,EAA2B,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAGxD;;;GAGG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,kBAAkB,CAAe;IAEjC,KAAK,EAAE,SAAS,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;gBAElC,IAAI,GAAE,MAAM,GAAG,MAAW,EAAE,KAAK,GAAE,SAAc;cAuB1C,aAAa,IAAI,IAAI;IAoDxC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,sBAAsB;IA8B9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,aAAa;IA+ErB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,gBAAgB;IAyBxB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAiCrB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAQjC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,WAAW;IA8NnB;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY;IAuKpB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAmErB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;;;;;;;;;;;;;OAgBG;cACgB,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CA8UrH;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,SAAS,aAA8B,CAAA"}