@nmmty/lazycanvas 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { ScaleType, AnyCentring, AnyGlobalCompositeOperation, ColorType, Transform, AnyFilter, LayerType } from "../../types";
1
+ import { ScaleType, AnyCentring, AnyGlobalCompositeOperation, Transform, AnyFilter, LayerType } from "../../types";
2
2
  /**
3
3
  * Interface representing the base structure of a layer.
4
4
  */
@@ -48,14 +48,6 @@ export interface IBaseLayerProps {
48
48
  * The opacity of the layer, ranging from 0 to 1.
49
49
  */
50
50
  opacity: number;
51
- /**
52
- * Whether the layer is filled.
53
- */
54
- filled: boolean;
55
- /**
56
- * The fill style (color or pattern) of the layer.
57
- */
58
- fillStyle: ColorType;
59
51
  /**
60
52
  * The shadow properties of the layer.
61
53
  */
@@ -206,8 +206,6 @@ class BaseLayer {
206
206
  centring: data.centring || types_1.Centring.Center,
207
207
  filter: data.filter || '',
208
208
  opacity: data.opacity || 1,
209
- filled: data.filled || true,
210
- fillStyle: data.fillStyle || '#000000',
211
209
  transform: data.transform || {},
212
210
  globalComposite: data.globalComposite || 'source-over',
213
211
  };
@@ -27,6 +27,14 @@ export interface IBezierLayerProps extends IBaseLayerProps {
27
27
  * The end point of the Bézier curve.
28
28
  */
29
29
  endPoint: Point;
30
+ /**
31
+ * Whether the layer is filled.
32
+ */
33
+ filled: boolean;
34
+ /**
35
+ * The fill style (color or pattern) of the layer.
36
+ */
37
+ fillStyle: ColorType;
30
38
  /**
31
39
  * The stroke properties of the Bézier curve.
32
40
  */
@@ -179,6 +179,8 @@ class BezierLayer extends BaseLayer_1.BaseLayer {
179
179
  validateProps(data) {
180
180
  return {
181
181
  ...super.validateProps(data),
182
+ filled: data.filled || false,
183
+ fillStyle: data.fillStyle || '#000000',
182
184
  centring: data.centring || types_1.Centring.None,
183
185
  controlPoints: data.controlPoints || [{ x: 0, y: 0 }, { x: 0, y: 0 }],
184
186
  endPoint: data.endPoint || { x: 0, y: 0 },
@@ -1,5 +1,5 @@
1
1
  import { BaseLayer, IBaseLayer, IBaseLayerMisc, IBaseLayerProps } from "./BaseLayer";
2
- import { ScaleType, LayerType, radiusCorner } from "../../types";
2
+ import { ScaleType, LayerType, RadiusCorner } from "../../types";
3
3
  import { Canvas, SKRSContext2D, SvgCanvas } from "@napi-rs/canvas";
4
4
  import { LayersManager } from "../managers";
5
5
  /**
@@ -39,7 +39,7 @@ export interface IImageLayerProps extends IBaseLayerProps {
39
39
  * The radius of the image.
40
40
  */
41
41
  radius: {
42
- [corner in radiusCorner]?: ScaleType;
42
+ [corner in RadiusCorner]?: ScaleType;
43
43
  };
44
44
  };
45
45
  }
@@ -72,7 +72,7 @@ export declare class ImageLayer extends BaseLayer<IImageLayerProps> {
72
72
  * @returns {this} The current instance for chaining.
73
73
  */
74
74
  setSize(width: ScaleType, height: ScaleType, radius?: {
75
- [corner in radiusCorner]?: ScaleType;
75
+ [corner in RadiusCorner]?: ScaleType;
76
76
  }): this;
77
77
  /**
78
78
  * Draws the Image Layer on the canvas.
@@ -32,6 +32,14 @@ export interface ILineLayerProps extends IBaseLayerProps {
32
32
  */
33
33
  y: ScaleType;
34
34
  };
35
+ /**
36
+ * Whether the layer is filled.
37
+ */
38
+ filled: boolean;
39
+ /**
40
+ * The fill style (color or pattern) of the layer.
41
+ */
42
+ fillStyle: ColorType;
35
43
  /**
36
44
  * The stroke properties of the line.
37
45
  */
@@ -148,6 +148,8 @@ class LineLayer extends BaseLayer_1.BaseLayer {
148
148
  validateProps(data) {
149
149
  return {
150
150
  ...super.validateProps(data),
151
+ filled: data.filled || false,
152
+ fillStyle: data.fillStyle || '#000000',
151
153
  centring: data.centring || types_1.Centring.None,
152
154
  endPoint: {
153
155
  x: data.endPoint?.x || 0,
@@ -1,5 +1,5 @@
1
1
  import { BaseLayer, IBaseLayer, IBaseLayerMisc, IBaseLayerProps } from "./BaseLayer";
2
- import { ColorType, ScaleType, LayerType, radiusCorner } from "../../types";
2
+ import { ColorType, ScaleType, LayerType, RadiusCorner } from "../../types";
3
3
  import { Canvas, SKRSContext2D, SvgCanvas } from "@napi-rs/canvas";
4
4
  import { LayersManager } from "../managers";
5
5
  /**
@@ -35,9 +35,17 @@ export interface IMorphLayerProps extends IBaseLayerProps {
35
35
  * The radius of the Morph Layer.
36
36
  */
37
37
  radius: {
38
- [corner in radiusCorner]?: ScaleType;
38
+ [corner in RadiusCorner]?: ScaleType;
39
39
  };
40
40
  };
41
+ /**
42
+ * Whether the layer is filled.
43
+ */
44
+ filled: boolean;
45
+ /**
46
+ * The fill style (color or pattern) of the layer.
47
+ */
48
+ fillStyle: ColorType;
41
49
  /**
42
50
  * The stroke properties of the morph.
43
51
  */
@@ -90,7 +98,7 @@ export declare class MorphLayer extends BaseLayer<IMorphLayerProps> {
90
98
  * @returns {this} The current instance for chaining.
91
99
  */
92
100
  setSize(width: ScaleType, height: ScaleType, radius?: {
93
- [corner in radiusCorner]?: ScaleType;
101
+ [corner in RadiusCorner]?: ScaleType;
94
102
  }): this;
95
103
  /**
96
104
  * Sets the color of the Morph Layer.
@@ -156,6 +156,8 @@ class MorphLayer extends BaseLayer_1.BaseLayer {
156
156
  validateProps(data) {
157
157
  return {
158
158
  ...super.validateProps(data),
159
+ filled: data.filled || true,
160
+ fillStyle: data.fillStyle || '#000000',
159
161
  size: {
160
162
  width: data.size?.width || 100,
161
163
  height: data.size?.height || 100,
@@ -3,11 +3,28 @@ import { ColorType, LayerType } from "../../types";
3
3
  import { BaseLayer, IBaseLayer, IBaseLayerMisc, IBaseLayerProps } from "./BaseLayer";
4
4
  import { LayersManager } from "../managers";
5
5
  export interface IPath2DLayer extends IBaseLayer {
6
+ /**
7
+ * The type of the layer, which is `Path`.
8
+ */
6
9
  type: LayerType.Path;
10
+ /**
11
+ * The properties specific to the Path2D Layer.
12
+ */
7
13
  props: IPath2DLayerProps;
8
14
  }
9
15
  export interface IPath2DLayerProps extends IBaseLayerProps {
16
+ /**
17
+ * The Path2D object representing the shape of the layer.
18
+ */
10
19
  path2D: Path2D;
20
+ /**
21
+ * Whether the layer is filled.
22
+ */
23
+ filled: boolean;
24
+ /**
25
+ * The fill style (color or pattern) of the layer.
26
+ */
27
+ fillStyle: ColorType;
11
28
  /**
12
29
  * The stroke properties of the Path2D.
13
30
  */
@@ -141,7 +141,9 @@ class Path2DLayer extends BaseLayer_1.BaseLayer {
141
141
  ctx.save();
142
142
  let fillStyle = await (0, utils_1.parseFillStyle)(ctx, this.props.fillStyle, { debug, manager });
143
143
  (0, utils_1.transform)(ctx, this.props.transform, { width: 0, height: 0, x: 0, y: 0, type: this.type });
144
+ (0, utils_1.drawShadow)(ctx, this.props.shadow);
144
145
  (0, utils_1.opacity)(ctx, this.props.opacity);
146
+ (0, utils_1.filters)(ctx, this.props.filter);
145
147
  ctx.globalCompositeOperation = this.props.globalComposite;
146
148
  if (this.props.clipPath) {
147
149
  ctx.clip(this.props.path2D);
@@ -184,6 +186,8 @@ class Path2DLayer extends BaseLayer_1.BaseLayer {
184
186
  validateProps(data) {
185
187
  return {
186
188
  ...super.validateProps(data),
189
+ filled: data.filled || true,
190
+ fillStyle: data.fillStyle || '#000000',
187
191
  path2D: data.path2D || new canvas_1.Path2D(),
188
192
  stroke: {
189
193
  width: data.stroke?.width || 1,
@@ -27,6 +27,14 @@ export interface IQuadraticLayerProps extends IBaseLayerProps {
27
27
  * The end point of the quadratic curve, including x and y coordinates.
28
28
  */
29
29
  endPoint: Point;
30
+ /**
31
+ * Whether the layer is filled.
32
+ */
33
+ filled: boolean;
34
+ /**
35
+ * The fill style (color or pattern) of the layer.
36
+ */
37
+ fillStyle: ColorType;
30
38
  /**
31
39
  * The stroke properties of the quadratic curve.
32
40
  */
@@ -160,6 +160,8 @@ class QuadraticLayer extends BaseLayer_1.BaseLayer {
160
160
  validateProps(data) {
161
161
  return {
162
162
  ...super.validateProps(data),
163
+ filled: data.filled || false,
164
+ fillStyle: data.fillStyle || '#000000',
163
165
  centring: data.centring || types_1.Centring.None,
164
166
  controlPoints: data.controlPoints || [{ x: 0, y: 0 }],
165
167
  endPoint: data.endPoint || { x: 0, y: 0 },
@@ -1,5 +1,5 @@
1
1
  import { BaseLayer, IBaseLayer, IBaseLayerMisc, IBaseLayerProps } from "./BaseLayer";
2
- import { ScaleType, ColorType, AnyWeight, AnyTextAlign, AnyTextBaseline, AnyTextDirection, LineCap, LineJoin, LayerType } from "../../types";
2
+ import { ScaleType, ColorType, AnyWeight, AnyTextAlign, AnyTextBaseline, AnyTextDirection, LineCap, LineJoin, LayerType, SubStringColor } from "../../types";
3
3
  import { Canvas, SKRSContext2D, SvgCanvas } from "@napi-rs/canvas";
4
4
  import { LayersManager } from "../managers";
5
5
  /**
@@ -23,6 +23,18 @@ export interface ITextLayerProps extends IBaseLayerProps {
23
23
  * The text content of the layer.
24
24
  */
25
25
  text: string;
26
+ /**
27
+ * Whether the layer is filled.
28
+ */
29
+ filled: boolean;
30
+ /**
31
+ * The fill style (color or pattern) of the layer.
32
+ */
33
+ fillStyle: ColorType;
34
+ /**
35
+ * Array of substring color configurations for partial text coloring.
36
+ */
37
+ subStringColors?: SubStringColor[];
26
38
  /**
27
39
  * The font configuration for the text.
28
40
  */
@@ -151,20 +163,20 @@ export declare class TextLayer extends BaseLayer<ITextLayerProps> {
151
163
  }, size?: number, weight?: AnyWeight): this;
152
164
  /**
153
165
  * Configures the multiline properties of the text layer.
154
- * @param {boolean} [enabled] - Whether multiline is enabled.
155
166
  * @param {ScaleType} [width] - The width of the multiline text area.
156
167
  * @param {ScaleType} [height] - The height of the multiline text area.
157
168
  * @param {number} [spacing] - The spacing between lines (optional).
158
169
  * @returns {this} The current instance for chaining.
159
170
  */
160
- setMultiline(enabled: boolean, width: ScaleType, height: ScaleType, spacing?: number): this;
171
+ setMultiline(width: ScaleType, height: ScaleType, spacing?: number): this;
161
172
  /**
162
173
  * Sets the color of the text layer.
163
- * @param {ColorType} [color] - The color of the text.
174
+ * @param {ColorType} [color] - The base color of the text.
175
+ * @param {SubStringColor[]} [sub] - Optional substring colors for partial text coloring.
164
176
  * @returns {this} The current instance for chaining.
165
177
  * @throws {LazyError} If the color is not provided or invalid.
166
178
  */
167
- setColor(color: ColorType): this;
179
+ setColor(color: ColorType, ...sub: SubStringColor[]): this;
168
180
  /**
169
181
  * Sets the alignment of the text layer.
170
182
  * @param {AnyTextAlign} [align] - The alignment of the text.
@@ -233,6 +245,7 @@ export declare class TextLayer extends BaseLayer<ITextLayerProps> {
233
245
  * @param {number} [x] - The x-coordinate of the text.
234
246
  * @param {number} [y] - The y-coordinate of the text.
235
247
  * @param {number} [w] - The width of the text area.
248
+ * @param {number} [textOffset] - The offset of this text segment in the original full text (for multiline support).
236
249
  */
237
250
  private drawText;
238
251
  /**
@@ -242,8 +255,8 @@ export declare class TextLayer extends BaseLayer<ITextLayerProps> {
242
255
  toJSON(): ITextLayer;
243
256
  /**
244
257
  * Validates the properties of the Text Layer.
245
- * @param {ITextLayerProps} [props] - The properties to validate.
258
+ * @param {ITextLayerProps} [data] - The properties to validate.
246
259
  * @returns {ITextLayerProps} The validated properties.
247
260
  */
248
- protected validateProps(props: ITextLayerProps): ITextLayerProps;
261
+ protected validateProps(data: ITextLayerProps): ITextLayerProps;
249
262
  }
@@ -63,15 +63,14 @@ class TextLayer extends BaseLayer_1.BaseLayer {
63
63
  }
64
64
  /**
65
65
  * Configures the multiline properties of the text layer.
66
- * @param {boolean} [enabled] - Whether multiline is enabled.
67
66
  * @param {ScaleType} [width] - The width of the multiline text area.
68
67
  * @param {ScaleType} [height] - The height of the multiline text area.
69
68
  * @param {number} [spacing] - The spacing between lines (optional).
70
69
  * @returns {this} The current instance for chaining.
71
70
  */
72
- setMultiline(enabled, width, height, spacing) {
71
+ setMultiline(width, height, spacing) {
73
72
  this.props.multiline = {
74
- enabled: enabled,
73
+ enabled: true,
75
74
  spacing: spacing || 1.1,
76
75
  };
77
76
  this.props.size = {
@@ -82,16 +81,20 @@ class TextLayer extends BaseLayer_1.BaseLayer {
82
81
  }
83
82
  /**
84
83
  * Sets the color of the text layer.
85
- * @param {ColorType} [color] - The color of the text.
84
+ * @param {ColorType} [color] - The base color of the text.
85
+ * @param {SubStringColor[]} [sub] - Optional substring colors for partial text coloring.
86
86
  * @returns {this} The current instance for chaining.
87
87
  * @throws {LazyError} If the color is not provided or invalid.
88
88
  */
89
- setColor(color) {
89
+ setColor(color, ...sub) {
90
90
  if (!color)
91
91
  throw new LazyUtil_1.LazyError('The color of the layer must be provided');
92
92
  if (!(0, utils_1.isColor)(color))
93
93
  throw new LazyUtil_1.LazyError('The color of the layer must be a valid color');
94
94
  this.props.fillStyle = color;
95
+ if (sub && sub.length > 0) {
96
+ this.props.subStringColors = sub;
97
+ }
95
98
  return this;
96
99
  }
97
100
  /**
@@ -222,10 +225,12 @@ class TextLayer extends BaseLayer_1.BaseLayer {
222
225
  let ym = y;
223
226
  lines = [];
224
227
  let line = '';
228
+ let charOffset = 0; // Track position in original text
225
229
  for (let word of words) {
226
230
  let linePlus = line + word + ' ';
227
231
  if (ctx.measureText(linePlus).width > w) {
228
- lines.push({ text: line, x: xm, y: ym });
232
+ lines.push({ text: line, x: xm, y: ym, startOffset: charOffset });
233
+ charOffset += line.length;
229
234
  line = word + ' ';
230
235
  ym += lineHeight;
231
236
  }
@@ -233,17 +238,17 @@ class TextLayer extends BaseLayer_1.BaseLayer {
233
238
  line = linePlus;
234
239
  }
235
240
  }
236
- lines.push({ text: line, x: xm, y: ym });
241
+ lines.push({ text: line, x: xm, y: ym, startOffset: charOffset });
237
242
  if (ym > ym + h)
238
243
  break;
239
244
  }
240
245
  for (let line of lines) {
241
- this.drawText(this.props, ctx, fillStyle, line.text, line.x, line.y, w);
246
+ this.drawText(this.props, ctx, fillStyle, line.text, line.x, line.y, w, line.startOffset);
242
247
  }
243
248
  }
244
249
  else {
245
250
  ctx.font = `${this.props.font.weight} ${this.props.font.size}px ${this.props.font.family}`;
246
- this.drawText(this.props, ctx, fillStyle, this.props.text, x, y, w);
251
+ this.drawText(this.props, ctx, fillStyle, this.props.text, x, y, w, 0);
247
252
  }
248
253
  ctx.closePath();
249
254
  ctx.restore();
@@ -257,22 +262,113 @@ class TextLayer extends BaseLayer_1.BaseLayer {
257
262
  * @param {number} [x] - The x-coordinate of the text.
258
263
  * @param {number} [y] - The y-coordinate of the text.
259
264
  * @param {number} [w] - The width of the text area.
265
+ * @param {number} [textOffset] - The offset of this text segment in the original full text (for multiline support).
260
266
  */
261
- drawText(props, ctx, fillStyle, text, x, y, w) {
262
- if (props.filled) {
263
- ctx.fillStyle = fillStyle;
264
- ctx.fillText(text, x, y, w);
267
+ drawText(props, ctx, fillStyle, text, x, y, w, textOffset = 0) {
268
+ // If no substring colors are defined, draw normally
269
+ if (!props.subStringColors || props.subStringColors.length === 0) {
270
+ if (props.filled) {
271
+ ctx.fillStyle = fillStyle;
272
+ ctx.fillText(text, x, y, w);
273
+ }
274
+ else {
275
+ ctx.strokeStyle = fillStyle;
276
+ ctx.lineWidth = props.stroke?.width || 1;
277
+ ctx.lineCap = props.stroke?.cap || 'butt';
278
+ ctx.lineJoin = props.stroke?.join || 'miter';
279
+ ctx.miterLimit = props.stroke?.miterLimit || 10;
280
+ ctx.lineDashOffset = props.stroke?.dashOffset || 0;
281
+ ctx.setLineDash(props.stroke?.dash || []);
282
+ ctx.strokeText(text, x, y, w);
283
+ }
284
+ return;
265
285
  }
266
- else {
267
- ctx.strokeStyle = fillStyle;
268
- ctx.lineWidth = props.stroke?.width || 1;
269
- ctx.lineCap = props.stroke?.cap || 'butt';
270
- ctx.lineJoin = props.stroke?.join || 'miter';
271
- ctx.miterLimit = props.stroke?.miterLimit || 10;
272
- ctx.lineDashOffset = props.stroke?.dashOffset || 0;
273
- ctx.setLineDash(props.stroke?.dash || []);
274
- ctx.strokeText(text, x, y, w);
286
+ // Draw text with substring colors
287
+ const textLength = text.length;
288
+ let currentX = x;
289
+ // Save original text alignment and set to left for manual positioning
290
+ const originalAlign = ctx.textAlign;
291
+ ctx.textAlign = 'left';
292
+ // Adjust starting X based on text alignment
293
+ const alignValue = props.align;
294
+ if (alignValue === types_1.TextAlign.Center || alignValue === 'center') {
295
+ const totalWidth = ctx.measureText(text).width;
296
+ currentX = x - totalWidth / 2;
297
+ }
298
+ else if (alignValue === types_1.TextAlign.Right || alignValue === 'right' || alignValue === types_1.TextAlign.End || alignValue === 'end') {
299
+ const totalWidth = ctx.measureText(text).width;
300
+ currentX = x - totalWidth;
301
+ }
302
+ // Create segments based on substring colors
303
+ const segments = [];
304
+ // Sort substring colors by start position
305
+ const sortedColors = [...props.subStringColors].sort((a, b) => a.start - b.start);
306
+ let currentIndex = 0;
307
+ for (const subColor of sortedColors) {
308
+ // Adjust positions based on textOffset (for multiline support)
309
+ const globalStart = subColor.start;
310
+ const globalEnd = subColor.end;
311
+ const lineStart = textOffset;
312
+ const lineEnd = textOffset + textLength;
313
+ // Skip if this color segment doesn't overlap with current line
314
+ if (globalEnd <= lineStart || globalStart >= lineEnd) {
315
+ continue;
316
+ }
317
+ // Calculate local positions within this line
318
+ const localStart = Math.max(0, globalStart - lineStart);
319
+ const localEnd = Math.min(textLength, globalEnd - lineStart);
320
+ // Add base color segment before this substring color
321
+ if (currentIndex < localStart) {
322
+ segments.push({
323
+ text: text.substring(currentIndex, localStart),
324
+ color: fillStyle,
325
+ start: currentIndex,
326
+ end: localStart
327
+ });
328
+ }
329
+ // Add colored substring
330
+ if (localStart < localEnd) {
331
+ segments.push({
332
+ text: text.substring(localStart, localEnd),
333
+ color: subColor.color,
334
+ start: localStart,
335
+ end: localEnd
336
+ });
337
+ currentIndex = localEnd;
338
+ }
339
+ }
340
+ // Add remaining text with base color
341
+ if (currentIndex < textLength) {
342
+ segments.push({
343
+ text: text.substring(currentIndex),
344
+ color: fillStyle,
345
+ start: currentIndex,
346
+ end: textLength
347
+ });
348
+ }
349
+ // Draw each segment
350
+ for (const segment of segments) {
351
+ if (segment.text.length === 0)
352
+ continue;
353
+ const segmentWidth = ctx.measureText(segment.text).width;
354
+ if (props.filled) {
355
+ ctx.fillStyle = segment.color;
356
+ ctx.fillText(segment.text, currentX, y);
357
+ }
358
+ else {
359
+ ctx.strokeStyle = segment.color;
360
+ ctx.lineWidth = props.stroke?.width || 1;
361
+ ctx.lineCap = props.stroke?.cap || 'butt';
362
+ ctx.lineJoin = props.stroke?.join || 'miter';
363
+ ctx.miterLimit = props.stroke?.miterLimit || 10;
364
+ ctx.lineDashOffset = props.stroke?.dashOffset || 0;
365
+ ctx.setLineDash(props.stroke?.dash || []);
366
+ ctx.strokeText(segment.text, currentX, y);
367
+ }
368
+ currentX += segmentWidth;
275
369
  }
370
+ // Restore original text alignment
371
+ ctx.textAlign = originalAlign;
276
372
  }
277
373
  /**
278
374
  * Converts the Text Layer to a JSON representation.
@@ -290,29 +386,29 @@ class TextLayer extends BaseLayer_1.BaseLayer {
290
386
  }
291
387
  /**
292
388
  * Validates the properties of the Text Layer.
293
- * @param {ITextLayerProps} [props] - The properties to validate.
389
+ * @param {ITextLayerProps} [data] - The properties to validate.
294
390
  * @returns {ITextLayerProps} The validated properties.
295
391
  */
296
- validateProps(props) {
392
+ validateProps(data) {
297
393
  return {
298
- ...super.validateProps(props),
299
- text: props.text || "",
394
+ ...super.validateProps(data),
395
+ filled: data.filled || true,
396
+ fillStyle: data.fillStyle || '#000000',
397
+ text: data.text || "",
300
398
  font: {
301
- family: props.font?.family || "Arial",
302
- size: props.font?.size || 16,
303
- weight: props.font?.weight || types_1.FontWeight.Regular,
399
+ family: data.font?.family || "Arial",
400
+ size: data.font?.size || 16,
401
+ weight: data.font?.weight || types_1.FontWeight.Regular,
304
402
  },
305
403
  multiline: {
306
- enabled: props.multiline?.enabled || false,
307
- spacing: props.multiline?.spacing || 1.1,
404
+ enabled: data.multiline?.enabled || false,
405
+ spacing: data.multiline?.spacing || 1.1,
308
406
  },
309
407
  size: {
310
- width: props.size?.width || "vw",
311
- height: props.size?.height || 0,
408
+ width: data.size?.width || "vw",
409
+ height: data.size?.height || 0,
312
410
  },
313
- align: props.align || types_1.TextAlign.Left,
314
- fillStyle: props.fillStyle || "#000000",
315
- filled: props.filled !== undefined ? props.filled : true,
411
+ align: data.align || types_1.TextAlign.Left,
316
412
  };
317
413
  }
318
414
  }
@@ -96,4 +96,10 @@ export interface Transform {
96
96
  matrix: DOMMatrix2DInit;
97
97
  }
98
98
 
99
- export type radiusCorner = 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom' | 'all';
99
+ export type RadiusCorner = 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom' | 'all';
100
+
101
+ export type SubStringColor = {
102
+ color: StringColorType;
103
+ start: number;
104
+ end: number;
105
+ }
@@ -1,10 +1,10 @@
1
- import type { AnyCentring, AnyLayer, AnyTextAlign, ColorType, PointNumber, ScaleType, Transform } from "../types";
1
+ import type { AnyCentring, AnyLayer, AnyTextAlign, ColorType, PointNumber, ScaleType, SubStringColor, Transform } from "../types";
2
2
  import { LayerType } from "../types";
3
3
  import { Canvas, SKRSContext2D, SvgCanvas } from "@napi-rs/canvas";
4
4
  import { LayersManager } from "../structures/managers";
5
5
  import { Group } from "../structures/components";
6
6
  export declare function generateID(type: string): string;
7
- export declare function isColor(v: ColorType): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
7
+ export declare function isColor(v: ColorType | SubStringColor): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
8
8
  export declare function parseToNormal(v: ScaleType, ctx: SKRSContext2D, canvas: Canvas | SvgCanvas, layer?: {
9
9
  width: number;
10
10
  height: number;
@@ -35,7 +35,7 @@ export declare function parser(ctx: SKRSContext2D, canvas: Canvas | SvgCanvas, m
35
35
  export declare function drawShadow(ctx: SKRSContext2D, shadow: any): void;
36
36
  export declare function opacity(ctx: SKRSContext2D, opacity?: number): void;
37
37
  export declare function filters(ctx: SKRSContext2D, filters: string | null | undefined): void;
38
- export declare function parseFillStyle(ctx: SKRSContext2D, color: ColorType, opts: {
38
+ export declare function parseFillStyle(ctx: SKRSContext2D, color: ColorType | SubStringColor, opts: {
39
39
  debug?: boolean;
40
40
  layer?: {
41
41
  width: number;
@@ -45,7 +45,7 @@ export declare function parseFillStyle(ctx: SKRSContext2D, color: ColorType, opt
45
45
  align: AnyCentring;
46
46
  };
47
47
  manager?: LayersManager;
48
- }): string | Promise<CanvasPattern> | CanvasGradient;
48
+ }): string | CanvasGradient | Promise<CanvasPattern>;
49
49
  export declare function transform(ctx: SKRSContext2D, transform: Transform, layer?: {
50
50
  width: number;
51
51
  height: number;
@@ -33,7 +33,7 @@ let rgbaReg = /^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(0|0?\.\d+|1(\.0)?)\)$/;
33
33
  let hslReg = /^hsl\((\d+),\s*(\d+)%,\s*(\d+)%\)$/;
34
34
  let hslaReg = /^hsla\((\d+),\s*(\d+)%,\s*(\d+)%,\s*(0|0?\.\d+|1(\.0)?)\)$/;
35
35
  function isColor(v) {
36
- return typeof (v === 'string' && (hexReg.test(v) || rgbReg.test(v) || rgbaReg.test(v) || hslReg.test(v) || hslaReg.test(v))) || v instanceof helpers_1.Gradient || v instanceof helpers_1.Pattern;
36
+ return typeof (v === 'string' && (hexReg.test(v) || rgbReg.test(v) || rgbaReg.test(v) || hslReg.test(v) || hslaReg.test(v))) || v instanceof helpers_1.Gradient || v instanceof helpers_1.Pattern || (typeof v === 'object' && (v.start && v.end && v.color));
37
37
  }
38
38
  function parseToNormal(v, ctx, canvas, layer = { width: 0, height: 0 }, options = { vertical: false, layer: false }, manager) {
39
39
  if (typeof v === 'number')
@@ -149,7 +149,13 @@ function parseFillStyle(ctx, color, opts) {
149
149
  if (color instanceof helpers_1.Gradient || color instanceof helpers_1.Pattern) {
150
150
  return color.draw(ctx, opts);
151
151
  }
152
- return color;
152
+ if (typeof color === 'object' && color.start && color.end && color.color) {
153
+ return color.color;
154
+ }
155
+ else if (typeof color === 'string') {
156
+ return color;
157
+ }
158
+ return '#000000';
153
159
  }
154
160
  function transform(ctx, transform, layer = { width: 0, height: 0, x: 0, y: 0, type: types_1.LayerType.Morph }, extra = { text: '', textAlign: types_1.TextAlign.Left, fontSize: 0, multiline: false }) {
155
161
  if (transform) {
package/package.json CHANGED
@@ -1,59 +1,59 @@
1
- {
2
- "name": "@nmmty/lazycanvas",
3
- "version": "0.6.1",
4
- "description": "A simple way to interact with @napi-rs/canvas in an advanced way!",
5
- "main": "./dist/index.js",
6
- "types": "./dist/index.d.ts",
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/NMMTY/LazyCanvas.git"
10
- },
11
- "keywords": [
12
- "canvas",
13
- "@napi-rs/canvas",
14
- "node-canvas",
15
- "easy",
16
- "simple"
17
- ],
18
- "author": "NMMTY",
19
- "license": "MIT",
20
- "bugs": {
21
- "url": "https://github.com/NMMTY/LazyCanvas/issues"
22
- },
23
- "homepage": "https://github.com/NMMTY/LazyCanvas#readme",
24
- "dependencies": {
25
- "@napi-rs/canvas": "^0.1.72",
26
- "gifenc": "^1.0.3",
27
- "js-yaml": "^4.1.0",
28
- "path": "^0.12.7",
29
- "svgson": "^5.3.1"
30
- },
31
- "devDependencies": {
32
- "@hitomihiumi/colors.ts": "^1.0.3",
33
- "@types/js-yaml": "^4.0.9",
34
- "@types/node": "^22.10.2",
35
- "@typescript-eslint/utils": "^8.39.1",
36
- "ava": "^6.2.0",
37
- "eslint": "^9.23.0",
38
- "eslint-config-neon": "^0.2.7",
39
- "lodash.merge": "^4.6.2",
40
- "tslib": "^2.8.1",
41
- "tsx": "^4.19.2",
42
- "typescript": "^5.4.5",
43
- "@hitomihiumi/micro-docgen": "0.4.2"
44
- },
45
- "scripts": {
46
- "test": "tsc ./test/test.ts && node ./test/test.js",
47
- "centring": "tsc ./test/centring.ts && node ./test/centring.js",
48
- "logo": "tsc ./test/logo.ts && node ./test/logo.js",
49
- "text": "tsc ./test/text.ts && node ./test/text.js",
50
- "animation": "tsc ./test/animation.ts && node ./test/animation.js",
51
- "iotest": "tsc ./test/iotest.ts && node ./test/iotest.js",
52
- "gradient": "tsc ./test/gradient.ts && node ./test/gradient.js",
53
- "docgen": "tsx docgen.ts && tsx ./scripts/post-docgen.ts",
54
- "lint": "eslint ./src --ext .ts",
55
- "lint:fix": "eslint ./src --ext .ts --fix",
56
- "font": "tsx ./scripts/font-gen.ts",
57
- "build": "tsc && tsx ./scripts/post-build.ts"
58
- }
59
- }
1
+ {
2
+ "name": "@nmmty/lazycanvas",
3
+ "version": "0.6.3",
4
+ "description": "A simple way to interact with @napi-rs/canvas in an advanced way!",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "scripts": {
8
+ "test": "tsc ./test/test.ts && node ./test/test.js",
9
+ "centring": "tsc ./test/centring.ts && node ./test/centring.js",
10
+ "logo": "tsc ./test/logo.ts && node ./test/logo.js",
11
+ "text": "tsc ./test/text.ts && node ./test/text.js",
12
+ "animation": "tsc ./test/animation.ts && node ./test/animation.js",
13
+ "iotest": "tsc ./test/iotest.ts && node ./test/iotest.js",
14
+ "gradient": "tsc ./test/gradient.ts && node ./test/gradient.js",
15
+ "docgen": "tsx docgen.ts && tsx ./scripts/post-docgen.ts",
16
+ "lint": "eslint ./src --ext .ts",
17
+ "lint:fix": "eslint ./src --ext .ts --fix",
18
+ "font": "tsx ./scripts/font-gen.ts",
19
+ "build": "tsc && tsx ./scripts/post-build.ts"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/NMMTY/LazyCanvas.git"
24
+ },
25
+ "keywords": [
26
+ "canvas",
27
+ "@napi-rs/canvas",
28
+ "node-canvas",
29
+ "easy",
30
+ "simple"
31
+ ],
32
+ "author": "NMMTY",
33
+ "license": "MIT",
34
+ "bugs": {
35
+ "url": "https://github.com/NMMTY/LazyCanvas/issues"
36
+ },
37
+ "homepage": "https://github.com/NMMTY/LazyCanvas#readme",
38
+ "dependencies": {
39
+ "@napi-rs/canvas": "^0.1.72",
40
+ "gifenc": "^1.0.3",
41
+ "js-yaml": "^4.1.0",
42
+ "path": "^0.12.7",
43
+ "svgson": "^5.3.1"
44
+ },
45
+ "devDependencies": {
46
+ "@hitomihiumi/colors.ts": "^1.0.3",
47
+ "@hitomihiumi/micro-docgen": "workspace:*",
48
+ "@types/js-yaml": "^4.0.9",
49
+ "@types/node": "^22.10.2",
50
+ "@typescript-eslint/utils": "^8.39.1",
51
+ "ava": "^6.2.0",
52
+ "eslint": "^9.23.0",
53
+ "eslint-config-neon": "^0.2.7",
54
+ "lodash.merge": "^4.6.2",
55
+ "tslib": "^2.8.1",
56
+ "tsx": "^4.19.2",
57
+ "typescript": "^5.4.5"
58
+ }
59
+ }