apexify.js 4.2.6 → 4.2.9

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 (45) hide show
  1. package/dist/ai/ApexAI.d.ts.map +1 -1
  2. package/dist/ai/ApexAI.js +1 -1
  3. package/dist/ai/ApexAI.js.map +1 -1
  4. package/dist/ai/ApexModules.d.ts +1 -1
  5. package/dist/ai/ApexModules.d.ts.map +1 -1
  6. package/dist/ai/ApexModules.js +1 -2
  7. package/dist/ai/ApexModules.js.map +1 -1
  8. package/dist/ai/functions/draw.d.ts.map +1 -1
  9. package/dist/ai/functions/draw.js +3 -1
  10. package/dist/ai/functions/draw.js.map +1 -1
  11. package/dist/canvas/ApexPainter.d.ts +0 -1
  12. package/dist/canvas/ApexPainter.d.ts.map +1 -1
  13. package/dist/canvas/ApexPainter.js +2 -26
  14. package/dist/canvas/ApexPainter.js.map +1 -1
  15. package/dist/canvas/utils/bg.d.ts.map +1 -1
  16. package/dist/canvas/utils/bg.js +17 -4
  17. package/dist/canvas/utils/bg.js.map +1 -1
  18. package/dist/canvas/utils/general functions.d.ts.map +1 -1
  19. package/dist/canvas/utils/general functions.js +2 -1
  20. package/dist/canvas/utils/general functions.js.map +1 -1
  21. package/dist/canvas/utils/imageProperties.d.ts.map +1 -1
  22. package/dist/canvas/utils/imageProperties.js +1 -5
  23. package/dist/canvas/utils/imageProperties.js.map +1 -1
  24. package/dist/canvas/utils/textProperties.d.ts +1 -1
  25. package/dist/canvas/utils/textProperties.d.ts.map +1 -1
  26. package/dist/canvas/utils/textProperties.js +80 -14
  27. package/dist/canvas/utils/textProperties.js.map +1 -1
  28. package/dist/canvas/utils/types.d.ts +34 -13
  29. package/dist/canvas/utils/types.d.ts.map +1 -1
  30. package/dist/canvas/utils/types.js.map +1 -1
  31. package/lib/ai/ApexAI.ts +2 -4
  32. package/lib/ai/ApexModules.ts +2 -3
  33. package/lib/ai/functions/draw.ts +3 -1
  34. package/lib/canvas/ApexPainter.ts +3 -31
  35. package/lib/canvas/utils/bg.ts +19 -4
  36. package/lib/canvas/utils/general functions.ts +3 -1
  37. package/lib/canvas/utils/imageProperties.ts +4 -5
  38. package/lib/canvas/utils/textProperties.ts +98 -15
  39. package/lib/canvas/utils/types.ts +34 -13
  40. package/package.json +181 -182
  41. package/dist/ai/ApexVoice.d.ts +0 -1
  42. package/dist/ai/ApexVoice.d.ts.map +0 -1
  43. package/dist/ai/ApexVoice.js +0 -2
  44. package/dist/ai/ApexVoice.js.map +0 -1
  45. package/lib/ai/ApexVoice.ts +0 -0
@@ -26,31 +26,6 @@ export class ApexPainter {
26
26
  let canvasHeight: number = canvas.height || 500;
27
27
  let borderRadius: number | string = canvas.borderRadius || 0;
28
28
 
29
- if (canvas.customBg) {
30
-
31
- try {
32
-
33
- if (canvas.customBg.startsWith('https' || 'http')) {
34
- const response = await fetch(canvas.customBg);
35
- if (!response.ok) {
36
- throw new Error("Failed to fetch background image.");
37
- }
38
- const buffer = await response.arrayBuffer();
39
- const image = await loadImage(Buffer.from(buffer));
40
- canvasWidth = image.width;
41
- canvasHeight = image.height;
42
- } else {
43
- const bgPath = path.join(process.cwd(), canvas.customBg);
44
- const image = await loadImage(bgPath);
45
- canvasWidth = image.width;
46
- canvasHeight = image.height;
47
- }
48
-
49
- } catch (error) {
50
- console.error('Error loading custom background image:', error);
51
- }
52
- }
53
-
54
29
  const canvasInstance = createCanvas(canvasWidth, canvasHeight);
55
30
  const ctx: any = canvasInstance.getContext('2d');
56
31
 
@@ -130,7 +105,8 @@ export class ApexPainter {
130
105
  );
131
106
  }
132
107
 
133
- drawText(ctx, mergedTextOptions);
108
+ const size = { width: existingImage.width, height: existingImage.height };
109
+ drawText(ctx, mergedTextOptions, size);
134
110
  }
135
111
 
136
112
  return canvas.toBuffer("image/png");
@@ -161,10 +137,6 @@ export class ApexPainter {
161
137
  }
162
138
  }
163
139
 
164
- async crop(data: cropOptions): Promise<any> {
165
-
166
- }
167
-
168
140
  async createGIF(images: ImageObject[], options: GIFOptions): Promise<GIFResults | any> {
169
141
  async function resizeImage(image: any, targetWidth: number, targetHeight: number) {
170
142
  const canvas = createCanvas(targetWidth, targetHeight);
@@ -575,8 +547,8 @@ export class ApexPainter {
575
547
  } catch (error: any) {
576
548
  throw new Error(error.message);
577
549
  }
578
-
579
550
  }
551
+
580
552
  public validHex(hexColor: string): any {
581
553
  const hexPattern = /^#[0-9a-fA-F]{6}$/;
582
554
  if (!hexPattern.test(hexColor)) {
@@ -73,14 +73,29 @@ export async function customBackground(ctx: any, canvas: CanvasConfig): Promise<
73
73
  }
74
74
 
75
75
  const image = await loadImage(imageBuffer);
76
+ const zoomScale = canvas.zoom?.scale || 1;
76
77
 
77
- canvas.width = image.width;
78
- canvas.height = image.height;
78
+ if (zoomScale < 0) throw new Error("Invalid scale. Scale can't be a -ve integer.");
79
79
 
80
- ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
80
+ const zoomX = canvas.zoom?.x || 0;
81
+ const zoomY = canvas.zoom?.y || 0;
82
+ const moveX = canvas.x || 0;
83
+ const moveY = canvas.y || 0;
84
+
85
+ if (!canvas.height || !canvas.width) {
86
+ canvas.height = image.height;
87
+ canvas.width = image.width;
88
+ }
89
+
90
+ const newWidth = image.width * zoomScale;
91
+ const newHeight = image.height * zoomScale;
92
+ const drawX = moveX + (canvas.width - newWidth) / 2 - zoomX;
93
+ const drawY = moveY + (canvas.height - newHeight) / 2 - zoomY;
94
+
95
+ ctx.drawImage(image, drawX, drawY, newWidth, newHeight);
81
96
 
82
97
  } catch (error: any) {
83
- console.error('Error loading custom background image:', error);
98
+ console.error('Error loading custom background image:', error.message);
84
99
  }
85
100
  }
86
101
  }
@@ -254,9 +254,11 @@ export async function cropInner(options: cropOptions): Promise<any> {
254
254
  ctx.quadraticCurveTo(0, 0, options.radius, 0);
255
255
  ctx.closePath();
256
256
  ctx.clip();
257
- } else if (options.radius !== null && options.radius !== 'circular' && typeof options.radius !== 'number' ) {
257
+ // @ts-ignore
258
+ } else if (options.radius !== null && options.radius !== 'circular' && (typeof options.radius !== 'number' || options.radius < 0)) {
258
259
  throw new Error('The "radius" option can only be "circular" or a non-negative number.');
259
260
  }
261
+
260
262
 
261
263
  ctx.drawImage(image, options.coordinates[0].from.x, options.coordinates[0].from.y, width, height, 0, 0, width, height);
262
264
 
@@ -231,14 +231,13 @@ export function drawShape(ctx: any, shapeSettings: any) {
231
231
  }
232
232
  } else {
233
233
  if (gradient) {
234
- // Call createGradient with correct coordinates
235
234
  const gradientFill = createGradient(
236
235
  ctx,
237
236
  gradient,
238
- x, // startX
239
- y, // startY
240
- x + width, // endX
241
- y + height, // endY
237
+ x,
238
+ y,
239
+ x + width,
240
+ y + height,
242
241
  );
243
242
  ctx.fillStyle = gradientFill;
244
243
  }
@@ -5,33 +5,88 @@ import { TextObject } from "./types";
5
5
  * @param ctx The canvas rendering context.
6
6
  * @param textOptions The options for the text.
7
7
  */
8
- export function drawText(ctx: any, textOptions: TextObject) {
8
+ export function drawText(ctx: any, textOptions: TextObject, size: any) {
9
9
  ctx.save();
10
+
11
+ if (textOptions.rotation && textOptions.rotation !== 0) {
12
+ ctx.translate(textOptions.x || 0, textOptions?.y || 0);
13
+ ctx.rotate(textOptions.rotation * Math.PI / 180);
14
+ }
15
+
10
16
  ctx.font = `${textOptions.isBold ? 'bold ' : ''}${textOptions.fontSize || 16}px ${textOptions.fontName || "Arial"}`;
11
17
  ctx.textAlign = textOptions.textAlign || 'left';
12
18
  ctx.textBaseline = textOptions.textBaseline || 'alphabetic';
13
19
 
14
20
  if (textOptions.shadow) {
15
- const { color, offsetX, offsetY, blur } = textOptions.shadow;
21
+ const { color, offsetX, offsetY, blur, opacity } = textOptions.shadow;
16
22
  ctx.shadowColor = color || "transparent";
17
23
  ctx.shadowOffsetX = offsetX || 0;
18
24
  ctx.shadowOffsetY = offsetY || 0;
19
25
  ctx.shadowBlur = blur || 0;
26
+ ctx.globalAlpha = opacity || null;
27
+ }
28
+
29
+ if (textOptions.opacity) {
30
+ if (textOptions.opacity > 1 || textOptions.opacity < 0) throw new Error("Text opacity Error: the value can't be smaller than 0 or bigger than 1.")
31
+ ctx.globalAlpha = textOptions.opacity;
20
32
  }
21
33
 
22
- ctx.fillStyle = textOptions.color || 'darkgray';
34
+
35
+ if (textOptions.outlined) {
36
+ ctx.strokeStyle = textOptions.stroke && textOptions.stroke.color ? textOptions.stroke.color : textOptions.color;
37
+ ctx.lineWidth = textOptions.stroke && textOptions.stroke.width ? textOptions.stroke.width : 1;
38
+ } else {
39
+
40
+ if (textOptions.gradient) {
41
+ if (textOptions.gradient.type === 'linear') {
42
+ const gradient = ctx.createLinearGradient(
43
+ textOptions.gradient?.startX || 0,
44
+ textOptions.gradient?.startY || 10,
45
+ textOptions.gradient?.endX || 20,
46
+ textOptions.gradient?.endY || 30
47
+ );
48
+
49
+ textOptions.gradient.colors.forEach(({ stop, color }) => {
50
+ gradient.addColorStop(stop, color);
51
+ });
52
+
53
+ ctx.fillStyle = gradient;
54
+ } else if (textOptions.gradient.type === 'radial') {
55
+ const gradient = ctx.createRadialGradient(
56
+ textOptions.gradient?.startX || 0,
57
+ textOptions.gradient?.startY || 10,
58
+ textOptions.gradient?.startRadius || 0,
59
+ textOptions.gradient?.endX || 20,
60
+ textOptions.gradient?.endY || 30,
61
+ textOptions.gradient?.endRadius || 30
62
+ );
63
+
64
+ textOptions.gradient.colors.forEach(({ stop, color }) => {
65
+ gradient.addColorStop(stop, color);
66
+ });
67
+
68
+ ctx.fillStyle = gradient;
69
+ } else {
70
+ throw new Error("Error Gradient: Invalid gradient type. Valid types: `radial` or `linear`.")
71
+ }
72
+ } else {
73
+ ctx.fillStyle = textOptions.color || 'darkgray';
74
+ }
75
+
76
+ }
23
77
 
24
78
  if (textOptions.maxWidth) {
25
79
  WrappedText(ctx, textOptions.text || 'Hello World', textOptions.x || 0, textOptions.y || 0, textOptions.maxWidth, textOptions);
26
80
  } else {
27
- ctx.fillText(textOptions.text, textOptions.x, textOptions.y);
28
- }
81
+ if (textOptions.outlined) {
82
+ ctx.strokeText(textOptions.text, textOptions.x, textOptions.y);
83
+ } else {
84
+ if (!textOptions.rotation) ctx.fillText(textOptions.text, textOptions.x, textOptions.y);
85
+ if (textOptions.rotation) ctx.fillText(textOptions.text, 0, 0);
29
86
 
30
- if (textOptions.stroke && textOptions.stroke.color && textOptions.stroke.width) {
31
- ctx.strokeStyle = textOptions.stroke.color;
32
- ctx.lineWidth = textOptions.stroke.width;
33
- ctx.strokeText(textOptions.text, textOptions.x, textOptions.y);
87
+ }
34
88
  }
89
+
35
90
  ctx.restore();
36
91
  }
37
92
 
@@ -48,21 +103,49 @@ export function WrappedText(ctx: any, text: string, x: number, y: number, maxWid
48
103
  const words = text.split(' ');
49
104
  let currentLine = '';
50
105
  const fontSize = textOptions.fontSize || 16;
106
+ const lineHeight = textOptions.lineHeight || fontSize;
107
+
108
+ ctx.save();
109
+
110
+ if (textOptions.outlined) {
111
+ ctx.strokeStyle = textOptions.stroke && textOptions.stroke.color ? textOptions.stroke.color : textOptions.color;
112
+ ctx.lineWidth = textOptions.stroke && textOptions.stroke.width ? textOptions.stroke.width : 1;
113
+ } else {
114
+ ctx.fillStyle = textOptions.color || 'darkgray';
115
+ }
116
+
117
+ if (textOptions.rotation && textOptions.rotation !== 0) {
118
+ ctx.translate(x, y);
119
+ ctx.rotate(textOptions.rotation * Math.PI / 180);
120
+ x = 0;
121
+ y = 0;
122
+ }
123
+
51
124
  for (let n = 0; n < words.length; n++) {
52
125
  const testLine = currentLine + words[n] + ' ';
53
126
  const metrics = ctx.measureText(testLine);
54
127
  const testWidth = metrics.width;
55
128
 
56
129
  if (testWidth > maxWidth && n > 0) {
57
- const adjustedY = y + (textOptions.lineHeight || fontSize) / 2;
58
- ctx.fillText(currentLine.trim(), x, adjustedY);
130
+ const adjustedY = y + lineHeight;
131
+ if (textOptions.outlined) {
132
+ ctx.strokeText(currentLine.trim(), x, adjustedY);
133
+ } else {
134
+ ctx.fillText(currentLine.trim(), x, adjustedY);
135
+ }
59
136
  currentLine = words[n] + ' ';
60
- y += textOptions.lineHeight || fontSize;
137
+ y += lineHeight;
61
138
  } else {
62
139
  currentLine = testLine;
63
140
  }
64
141
  }
65
142
 
66
- const adjustedY = y + (textOptions.lineHeight || fontSize) / 2;
67
- ctx.fillText(currentLine.trim(), x, adjustedY);
68
- }
143
+ const adjustedY = y + lineHeight;
144
+ if (textOptions.outlined) {
145
+ ctx.strokeText(currentLine.trim(), x, adjustedY);
146
+ } else {
147
+ ctx.fillText(currentLine.trim(), x, adjustedY);
148
+ }
149
+
150
+ ctx.restore();
151
+ }
@@ -22,9 +22,14 @@ export interface CanvasConfig {
22
22
  x?: number;
23
23
  y?: number;
24
24
  customBg?: string;
25
- colorBg?: string | 'transparent';
25
+ colorBg?: string;
26
+ zoom?: {
27
+ scale?: number;
28
+ x?: number;
29
+ y?: number;
30
+ };
26
31
  gradientBg?: {
27
- type?: string | 'linear' | 'radial' | undefined;
32
+ type?: 'linear' | 'radial';
28
33
  startX?: number;
29
34
  startY?: number;
30
35
  startRadius?: number;
@@ -37,7 +42,7 @@ export interface CanvasConfig {
37
42
  color?: string;
38
43
  width?: number;
39
44
  position?: number;
40
- borderRadius?: number | string | "circular";
45
+ borderRadius?: number | "circular";
41
46
  };
42
47
  shadow?: {
43
48
  color?: string;
@@ -47,7 +52,7 @@ export interface CanvasConfig {
47
52
  opacity?: number;
48
53
  };
49
54
  rotation?: number;
50
- borderRadius?: number | string | "circular";
55
+ borderRadius?: number | "circular";
51
56
  };
52
57
 
53
58
  /**
@@ -84,7 +89,7 @@ export interface ImageProperties {
84
89
  isFilled?: boolean;
85
90
  color?: string;
86
91
  gradient?: {
87
- type?: string | 'linear' | 'radial' | undefined;
92
+ type?: 'linear' | 'radial';
88
93
  startX?: number;
89
94
  startY?: number;
90
95
  startRadius?: number;
@@ -94,12 +99,12 @@ export interface ImageProperties {
94
99
  colors?: { stop?: number; color?: string }[];
95
100
  };
96
101
  rotation?: number;
97
- borderRadius?: number | string | "circular" ;
102
+ borderRadius?: number | "circular"
98
103
  stroke?: {
99
104
  color?: string;
100
105
  width?: number;
101
106
  position?: number;
102
- borderRadius?: number | string | "circular";
107
+ borderRadius?: number | "circular"
103
108
  };
104
109
  shadow?: {
105
110
  color?: string;
@@ -107,7 +112,7 @@ export interface ImageProperties {
107
112
  offsetY?: number;
108
113
  blur?: number;
109
114
  opacity?: number;
110
- borderRadius?: number | string | "circular";
115
+ borderRadius?: number | "circular"
111
116
  };
112
117
  };
113
118
 
@@ -122,8 +127,22 @@ export interface TextObject {
122
127
  color?: string;
123
128
  maxWidth?: number;
124
129
  lineHeight?: number;
125
- textAlign?: string | "end" | "center" | "left" | "right" | "start";
126
- textBaseline?: string | "alphabetic" | "bottom" | "hanging" | "ideographic" | "middle" | "top";
130
+ textAlign?: "end" | "center" | "left" | "right" | "start" | "justify";
131
+ textBaseline?: "alphabetic" | "bottom" | "hanging" | "ideographic" | "middle" | "top";
132
+ outlined?: boolean;
133
+ gradient?: {
134
+ type?: 'linear' | 'radial';
135
+ startX?: number;
136
+ startY?: number;
137
+ endX?: number;
138
+ endY?: number;
139
+ startRadius?: number;
140
+ endRadius?: number;
141
+ colors: {
142
+ stop: number;
143
+ color: string;
144
+ }[];
145
+ };
127
146
  shadow?: {
128
147
  color?: string;
129
148
  offsetX?: number;
@@ -135,6 +154,8 @@ export interface TextObject {
135
154
  color?: string;
136
155
  width?: number;
137
156
  };
157
+ rotation?: number;
158
+ opacity?: number;
138
159
  }
139
160
 
140
161
  /**
@@ -395,7 +416,7 @@ export interface LineChartConfig {
395
416
  };
396
417
  lineTension?: number[];
397
418
  grid?: {
398
- type: 'vertical' | 'horizontal' | 'both' | string;
419
+ type: 'vertical' | 'horizontal' | 'both';
399
420
  color: string;
400
421
  width: number;
401
422
  };
@@ -428,6 +449,6 @@ export interface cropCoordinate {
428
449
  export interface cropOptions {
429
450
  coordinates: cropCoordinate[];
430
451
  imageSource: string;
431
- crop: 'inner' | 'outer' | string;
432
- radius: 'circular' | number | string;
452
+ crop: 'inner' | 'outer';
453
+ radius: number | "circular"
433
454
  }