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.
- package/dist/ai/ApexAI.d.ts.map +1 -1
- package/dist/ai/ApexAI.js +1 -1
- package/dist/ai/ApexAI.js.map +1 -1
- package/dist/ai/ApexModules.d.ts +1 -1
- package/dist/ai/ApexModules.d.ts.map +1 -1
- package/dist/ai/ApexModules.js +1 -2
- package/dist/ai/ApexModules.js.map +1 -1
- package/dist/ai/functions/draw.d.ts.map +1 -1
- package/dist/ai/functions/draw.js +3 -1
- package/dist/ai/functions/draw.js.map +1 -1
- package/dist/canvas/ApexPainter.d.ts +0 -1
- package/dist/canvas/ApexPainter.d.ts.map +1 -1
- package/dist/canvas/ApexPainter.js +2 -26
- package/dist/canvas/ApexPainter.js.map +1 -1
- package/dist/canvas/utils/bg.d.ts.map +1 -1
- package/dist/canvas/utils/bg.js +17 -4
- package/dist/canvas/utils/bg.js.map +1 -1
- package/dist/canvas/utils/general functions.d.ts.map +1 -1
- package/dist/canvas/utils/general functions.js +2 -1
- package/dist/canvas/utils/general functions.js.map +1 -1
- package/dist/canvas/utils/imageProperties.d.ts.map +1 -1
- package/dist/canvas/utils/imageProperties.js +1 -5
- package/dist/canvas/utils/imageProperties.js.map +1 -1
- package/dist/canvas/utils/textProperties.d.ts +1 -1
- package/dist/canvas/utils/textProperties.d.ts.map +1 -1
- package/dist/canvas/utils/textProperties.js +80 -14
- package/dist/canvas/utils/textProperties.js.map +1 -1
- package/dist/canvas/utils/types.d.ts +34 -13
- package/dist/canvas/utils/types.d.ts.map +1 -1
- package/dist/canvas/utils/types.js.map +1 -1
- package/lib/ai/ApexAI.ts +2 -4
- package/lib/ai/ApexModules.ts +2 -3
- package/lib/ai/functions/draw.ts +3 -1
- package/lib/canvas/ApexPainter.ts +3 -31
- package/lib/canvas/utils/bg.ts +19 -4
- package/lib/canvas/utils/general functions.ts +3 -1
- package/lib/canvas/utils/imageProperties.ts +4 -5
- package/lib/canvas/utils/textProperties.ts +98 -15
- package/lib/canvas/utils/types.ts +34 -13
- package/package.json +181 -182
- package/dist/ai/ApexVoice.d.ts +0 -1
- package/dist/ai/ApexVoice.d.ts.map +0 -1
- package/dist/ai/ApexVoice.js +0 -2
- package/dist/ai/ApexVoice.js.map +0 -1
- 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
|
-
|
|
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)) {
|
package/lib/canvas/utils/bg.ts
CHANGED
|
@@ -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
|
-
|
|
78
|
-
canvas.height = image.height;
|
|
78
|
+
if (zoomScale < 0) throw new Error("Invalid scale. Scale can't be a -ve integer.");
|
|
79
79
|
|
|
80
|
-
|
|
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
|
-
|
|
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,
|
|
239
|
-
y,
|
|
240
|
-
x + width,
|
|
241
|
-
y + height,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 +
|
|
58
|
-
|
|
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 +=
|
|
137
|
+
y += lineHeight;
|
|
61
138
|
} else {
|
|
62
139
|
currentLine = testLine;
|
|
63
140
|
}
|
|
64
141
|
}
|
|
65
142
|
|
|
66
|
-
const adjustedY = y +
|
|
67
|
-
|
|
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
|
|
25
|
+
colorBg?: string;
|
|
26
|
+
zoom?: {
|
|
27
|
+
scale?: number;
|
|
28
|
+
x?: number;
|
|
29
|
+
y?: number;
|
|
30
|
+
};
|
|
26
31
|
gradientBg?: {
|
|
27
|
-
type?:
|
|
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 |
|
|
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 |
|
|
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?:
|
|
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 |
|
|
102
|
+
borderRadius?: number | "circular"
|
|
98
103
|
stroke?: {
|
|
99
104
|
color?: string;
|
|
100
105
|
width?: number;
|
|
101
106
|
position?: number;
|
|
102
|
-
borderRadius?:
|
|
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 |
|
|
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?:
|
|
126
|
-
textBaseline?:
|
|
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'
|
|
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'
|
|
432
|
-
radius:
|
|
452
|
+
crop: 'inner' | 'outer';
|
|
453
|
+
radius: number | "circular"
|
|
433
454
|
}
|