apexify.js 4.9.26 → 4.9.27
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/README.md +358 -47
- package/dist/cjs/Canvas/ApexPainter.d.ts +122 -78
- package/dist/cjs/Canvas/ApexPainter.d.ts.map +1 -1
- package/dist/cjs/Canvas/ApexPainter.js +461 -352
- package/dist/cjs/Canvas/ApexPainter.js.map +1 -1
- package/dist/cjs/Canvas/utils/Background/bg.d.ts +23 -11
- package/dist/cjs/Canvas/utils/Background/bg.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/Background/bg.js +174 -107
- package/dist/cjs/Canvas/utils/Background/bg.js.map +1 -1
- package/dist/cjs/Canvas/utils/Custom/customLines.js +2 -2
- package/dist/cjs/Canvas/utils/Custom/customLines.js.map +1 -1
- package/dist/cjs/Canvas/utils/Image/imageFilters.d.ts +11 -0
- package/dist/cjs/Canvas/utils/Image/imageFilters.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Image/imageFilters.js +307 -0
- package/dist/cjs/Canvas/utils/Image/imageFilters.js.map +1 -0
- package/dist/cjs/Canvas/utils/Image/imageProperties.d.ts +47 -112
- package/dist/cjs/Canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/Image/imageProperties.js +229 -560
- package/dist/cjs/Canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/cjs/Canvas/utils/Image/professionalImageFilters.d.ts +11 -0
- package/dist/cjs/Canvas/utils/Image/professionalImageFilters.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Image/professionalImageFilters.js +351 -0
- package/dist/cjs/Canvas/utils/Image/professionalImageFilters.js.map +1 -0
- package/dist/cjs/Canvas/utils/Image/simpleProfessionalFilters.d.ts +11 -0
- package/dist/cjs/Canvas/utils/Image/simpleProfessionalFilters.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Image/simpleProfessionalFilters.js +215 -0
- package/dist/cjs/Canvas/utils/Image/simpleProfessionalFilters.js.map +1 -0
- package/dist/cjs/Canvas/utils/Patterns/enhancedPatternRenderer.d.ts +71 -0
- package/dist/cjs/Canvas/utils/Patterns/enhancedPatternRenderer.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Patterns/enhancedPatternRenderer.js +392 -0
- package/dist/cjs/Canvas/utils/Patterns/enhancedPatternRenderer.js.map +1 -0
- package/dist/cjs/Canvas/utils/Shapes/shapes.d.ts +29 -0
- package/dist/cjs/Canvas/utils/Shapes/shapes.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Shapes/shapes.js +334 -0
- package/dist/cjs/Canvas/utils/Shapes/shapes.js.map +1 -0
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.d.ts +127 -0
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.js +365 -0
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.js.map +1 -0
- package/dist/cjs/Canvas/utils/types.d.ts +227 -131
- package/dist/cjs/Canvas/utils/types.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/types.js +0 -1
- package/dist/cjs/Canvas/utils/types.js.map +1 -1
- package/dist/cjs/Canvas/utils/utils.d.ts +7 -4
- package/dist/cjs/Canvas/utils/utils.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/utils.js +17 -7
- package/dist/cjs/Canvas/utils/utils.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/Canvas/ApexPainter.d.ts +122 -78
- package/dist/esm/Canvas/ApexPainter.d.ts.map +1 -1
- package/dist/esm/Canvas/ApexPainter.js +461 -352
- package/dist/esm/Canvas/ApexPainter.js.map +1 -1
- package/dist/esm/Canvas/utils/Background/bg.d.ts +23 -11
- package/dist/esm/Canvas/utils/Background/bg.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/Background/bg.js +174 -107
- package/dist/esm/Canvas/utils/Background/bg.js.map +1 -1
- package/dist/esm/Canvas/utils/Custom/customLines.js +2 -2
- package/dist/esm/Canvas/utils/Custom/customLines.js.map +1 -1
- package/dist/esm/Canvas/utils/Image/imageFilters.d.ts +11 -0
- package/dist/esm/Canvas/utils/Image/imageFilters.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Image/imageFilters.js +307 -0
- package/dist/esm/Canvas/utils/Image/imageFilters.js.map +1 -0
- package/dist/esm/Canvas/utils/Image/imageProperties.d.ts +47 -112
- package/dist/esm/Canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/Image/imageProperties.js +229 -560
- package/dist/esm/Canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/esm/Canvas/utils/Image/professionalImageFilters.d.ts +11 -0
- package/dist/esm/Canvas/utils/Image/professionalImageFilters.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Image/professionalImageFilters.js +351 -0
- package/dist/esm/Canvas/utils/Image/professionalImageFilters.js.map +1 -0
- package/dist/esm/Canvas/utils/Image/simpleProfessionalFilters.d.ts +11 -0
- package/dist/esm/Canvas/utils/Image/simpleProfessionalFilters.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Image/simpleProfessionalFilters.js +215 -0
- package/dist/esm/Canvas/utils/Image/simpleProfessionalFilters.js.map +1 -0
- package/dist/esm/Canvas/utils/Patterns/enhancedPatternRenderer.d.ts +71 -0
- package/dist/esm/Canvas/utils/Patterns/enhancedPatternRenderer.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Patterns/enhancedPatternRenderer.js +392 -0
- package/dist/esm/Canvas/utils/Patterns/enhancedPatternRenderer.js.map +1 -0
- package/dist/esm/Canvas/utils/Shapes/shapes.d.ts +29 -0
- package/dist/esm/Canvas/utils/Shapes/shapes.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Shapes/shapes.js +334 -0
- package/dist/esm/Canvas/utils/Shapes/shapes.js.map +1 -0
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.d.ts +127 -0
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.js +365 -0
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.js.map +1 -0
- package/dist/esm/Canvas/utils/types.d.ts +227 -131
- package/dist/esm/Canvas/utils/types.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/types.js +0 -1
- package/dist/esm/Canvas/utils/types.js.map +1 -1
- package/dist/esm/Canvas/utils/utils.d.ts +7 -4
- package/dist/esm/Canvas/utils/utils.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/utils.js +17 -7
- package/dist/esm/Canvas/utils/utils.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/Canvas/ApexPainter.ts +1325 -1218
- package/lib/Canvas/utils/Background/bg.ts +247 -173
- package/lib/Canvas/utils/Custom/customLines.ts +3 -3
- package/lib/Canvas/utils/Image/imageFilters.ts +356 -0
- package/lib/Canvas/utils/Image/imageProperties.ts +322 -775
- package/lib/Canvas/utils/Image/professionalImageFilters.ts +391 -0
- package/lib/Canvas/utils/Image/simpleProfessionalFilters.ts +229 -0
- package/lib/Canvas/utils/Patterns/enhancedPatternRenderer.ts +444 -0
- package/lib/Canvas/utils/Shapes/shapes.ts +528 -0
- package/lib/Canvas/utils/Texts/enhancedTextRenderer.ts +478 -0
- package/lib/Canvas/utils/types.ts +301 -117
- package/lib/Canvas/utils/utils.ts +85 -72
- package/package.json +106 -188
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
import { SKRSContext2D } from '@napi-rs/canvas';
|
|
2
|
+
import { ShapeType, ShapeProperties, gradient } from '../types';
|
|
3
|
+
import { createGradientFill } from '../Image/imageProperties';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Draws a shape on the canvas context
|
|
7
|
+
* @param ctx Canvas 2D context
|
|
8
|
+
* @param shapeType Type of shape to draw
|
|
9
|
+
* @param x X position
|
|
10
|
+
* @param y Y position
|
|
11
|
+
* @param width Width of the shape
|
|
12
|
+
* @param height Height of the shape
|
|
13
|
+
* @param shapeProps Shape properties including fill, color, gradient
|
|
14
|
+
*/
|
|
15
|
+
export function drawShape(
|
|
16
|
+
ctx: SKRSContext2D,
|
|
17
|
+
shapeType: ShapeType,
|
|
18
|
+
x: number,
|
|
19
|
+
y: number,
|
|
20
|
+
width: number,
|
|
21
|
+
height: number,
|
|
22
|
+
shapeProps: ShapeProperties
|
|
23
|
+
): void {
|
|
24
|
+
ctx.save();
|
|
25
|
+
|
|
26
|
+
// Set up fill style
|
|
27
|
+
if (shapeProps.gradient) {
|
|
28
|
+
const gradient = createGradientFill(ctx, shapeProps.gradient, { x, y, w: width, h: height });
|
|
29
|
+
ctx.fillStyle = gradient as any;
|
|
30
|
+
} else {
|
|
31
|
+
ctx.fillStyle = shapeProps.color || '#000000';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Draw the shape based on type
|
|
35
|
+
switch (shapeType) {
|
|
36
|
+
case 'rectangle':
|
|
37
|
+
drawRectangle(ctx, x, y, width, height, shapeProps);
|
|
38
|
+
break;
|
|
39
|
+
case 'square':
|
|
40
|
+
const size = Math.min(width, height);
|
|
41
|
+
drawRectangle(ctx, x, y, size, size, shapeProps);
|
|
42
|
+
break;
|
|
43
|
+
case 'circle':
|
|
44
|
+
drawCircle(ctx, x, y, width, height, shapeProps);
|
|
45
|
+
break;
|
|
46
|
+
case 'triangle':
|
|
47
|
+
drawTriangle(ctx, x, y, width, height, shapeProps);
|
|
48
|
+
break;
|
|
49
|
+
case 'trapezium':
|
|
50
|
+
drawTrapezium(ctx, x, y, width, height, shapeProps);
|
|
51
|
+
break;
|
|
52
|
+
case 'star':
|
|
53
|
+
drawStar(ctx, x, y, width, height, shapeProps);
|
|
54
|
+
break;
|
|
55
|
+
case 'heart':
|
|
56
|
+
drawHeart(ctx, x, y, width, height, shapeProps);
|
|
57
|
+
break;
|
|
58
|
+
case 'polygon':
|
|
59
|
+
drawPolygon(ctx, x, y, width, height, shapeProps);
|
|
60
|
+
break;
|
|
61
|
+
default:
|
|
62
|
+
throw new Error(`Unknown shape type: ${shapeType}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
ctx.restore();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates a path for a shape (used for shadows and strokes)
|
|
70
|
+
* @param ctx Canvas 2D context
|
|
71
|
+
* @param shapeType Type of shape
|
|
72
|
+
* @param x X position
|
|
73
|
+
* @param y Y position
|
|
74
|
+
* @param width Width of the shape
|
|
75
|
+
* @param height Height of the shape
|
|
76
|
+
* @param shapeProps Shape properties
|
|
77
|
+
*/
|
|
78
|
+
export function createShapePath(
|
|
79
|
+
ctx: SKRSContext2D,
|
|
80
|
+
shapeType: ShapeType,
|
|
81
|
+
x: number,
|
|
82
|
+
y: number,
|
|
83
|
+
width: number,
|
|
84
|
+
height: number,
|
|
85
|
+
shapeProps: ShapeProperties
|
|
86
|
+
): void {
|
|
87
|
+
switch (shapeType) {
|
|
88
|
+
case 'rectangle':
|
|
89
|
+
createRectanglePath(ctx, x, y, width, height);
|
|
90
|
+
break;
|
|
91
|
+
case 'square':
|
|
92
|
+
const size = Math.min(width, height);
|
|
93
|
+
createRectanglePath(ctx, x, y, size, size);
|
|
94
|
+
break;
|
|
95
|
+
case 'circle':
|
|
96
|
+
createCirclePath(ctx, x, y, width, height, shapeProps);
|
|
97
|
+
break;
|
|
98
|
+
case 'triangle':
|
|
99
|
+
createTrianglePath(ctx, x, y, width, height);
|
|
100
|
+
break;
|
|
101
|
+
case 'trapezium':
|
|
102
|
+
createTrapeziumPath(ctx, x, y, width, height);
|
|
103
|
+
break;
|
|
104
|
+
case 'star':
|
|
105
|
+
createStarPath(ctx, x, y, width, height, shapeProps);
|
|
106
|
+
break;
|
|
107
|
+
case 'heart':
|
|
108
|
+
createHeartPath(ctx, x, y, width, height);
|
|
109
|
+
break;
|
|
110
|
+
case 'polygon':
|
|
111
|
+
createPolygonPath(ctx, x, y, width, height, shapeProps);
|
|
112
|
+
break;
|
|
113
|
+
default:
|
|
114
|
+
throw new Error(`Unknown shape type: ${shapeType}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Draws a rectangle
|
|
120
|
+
*/
|
|
121
|
+
function drawRectangle(
|
|
122
|
+
ctx: SKRSContext2D,
|
|
123
|
+
x: number,
|
|
124
|
+
y: number,
|
|
125
|
+
width: number,
|
|
126
|
+
height: number,
|
|
127
|
+
shapeProps: ShapeProperties
|
|
128
|
+
): void {
|
|
129
|
+
ctx.beginPath();
|
|
130
|
+
ctx.rect(x, y, width, height);
|
|
131
|
+
|
|
132
|
+
if (shapeProps.fill !== false) {
|
|
133
|
+
ctx.fill();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Creates rectangle path
|
|
139
|
+
*/
|
|
140
|
+
function createRectanglePath(
|
|
141
|
+
ctx: SKRSContext2D,
|
|
142
|
+
x: number,
|
|
143
|
+
y: number,
|
|
144
|
+
width: number,
|
|
145
|
+
height: number
|
|
146
|
+
): void {
|
|
147
|
+
ctx.beginPath();
|
|
148
|
+
ctx.rect(x, y, width, height);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Draws a circle
|
|
153
|
+
*/
|
|
154
|
+
function drawCircle(
|
|
155
|
+
ctx: SKRSContext2D,
|
|
156
|
+
x: number,
|
|
157
|
+
y: number,
|
|
158
|
+
width: number,
|
|
159
|
+
height: number,
|
|
160
|
+
shapeProps: ShapeProperties
|
|
161
|
+
): void {
|
|
162
|
+
const centerX = x + width / 2;
|
|
163
|
+
const centerY = y + height / 2;
|
|
164
|
+
const radius = shapeProps.radius || Math.min(width, height) / 2;
|
|
165
|
+
|
|
166
|
+
ctx.beginPath();
|
|
167
|
+
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
|
|
168
|
+
|
|
169
|
+
if (shapeProps.fill !== false) {
|
|
170
|
+
ctx.fill();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Creates circle path
|
|
176
|
+
*/
|
|
177
|
+
function createCirclePath(
|
|
178
|
+
ctx: SKRSContext2D,
|
|
179
|
+
x: number,
|
|
180
|
+
y: number,
|
|
181
|
+
width: number,
|
|
182
|
+
height: number,
|
|
183
|
+
shapeProps: ShapeProperties
|
|
184
|
+
): void {
|
|
185
|
+
const centerX = x + width / 2;
|
|
186
|
+
const centerY = y + height / 2;
|
|
187
|
+
const radius = shapeProps.radius || Math.min(width, height) / 2;
|
|
188
|
+
|
|
189
|
+
ctx.beginPath();
|
|
190
|
+
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Draws a triangle (pointing up)
|
|
195
|
+
*/
|
|
196
|
+
function drawTriangle(
|
|
197
|
+
ctx: SKRSContext2D,
|
|
198
|
+
x: number,
|
|
199
|
+
y: number,
|
|
200
|
+
width: number,
|
|
201
|
+
height: number,
|
|
202
|
+
shapeProps: ShapeProperties
|
|
203
|
+
): void {
|
|
204
|
+
const centerX = x + width / 2;
|
|
205
|
+
const topY = y;
|
|
206
|
+
const bottomY = y + height;
|
|
207
|
+
const leftX = x;
|
|
208
|
+
const rightX = x + width;
|
|
209
|
+
|
|
210
|
+
ctx.beginPath();
|
|
211
|
+
ctx.moveTo(centerX, topY); // Top point
|
|
212
|
+
ctx.lineTo(rightX, bottomY); // Bottom right
|
|
213
|
+
ctx.lineTo(leftX, bottomY); // Bottom left
|
|
214
|
+
ctx.closePath();
|
|
215
|
+
|
|
216
|
+
if (shapeProps.fill !== false) {
|
|
217
|
+
ctx.fill();
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Creates triangle path
|
|
223
|
+
*/
|
|
224
|
+
function createTrianglePath(
|
|
225
|
+
ctx: SKRSContext2D,
|
|
226
|
+
x: number,
|
|
227
|
+
y: number,
|
|
228
|
+
width: number,
|
|
229
|
+
height: number
|
|
230
|
+
): void {
|
|
231
|
+
const centerX = x + width / 2;
|
|
232
|
+
const topY = y;
|
|
233
|
+
const bottomY = y + height;
|
|
234
|
+
const leftX = x;
|
|
235
|
+
const rightX = x + width;
|
|
236
|
+
|
|
237
|
+
ctx.beginPath();
|
|
238
|
+
ctx.moveTo(centerX, topY); // Top point
|
|
239
|
+
ctx.lineTo(rightX, bottomY); // Bottom right
|
|
240
|
+
ctx.lineTo(leftX, bottomY); // Bottom left
|
|
241
|
+
ctx.closePath();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Draws a trapezium (isosceles trapezoid)
|
|
246
|
+
*/
|
|
247
|
+
function drawTrapezium(
|
|
248
|
+
ctx: SKRSContext2D,
|
|
249
|
+
x: number,
|
|
250
|
+
y: number,
|
|
251
|
+
width: number,
|
|
252
|
+
height: number,
|
|
253
|
+
shapeProps: ShapeProperties
|
|
254
|
+
): void {
|
|
255
|
+
const topWidth = width * 0.6; // Top is 60% of bottom width
|
|
256
|
+
const topOffset = (width - topWidth) / 2;
|
|
257
|
+
|
|
258
|
+
ctx.beginPath();
|
|
259
|
+
ctx.moveTo(x + topOffset, y); // Top left
|
|
260
|
+
ctx.lineTo(x + topOffset + topWidth, y); // Top right
|
|
261
|
+
ctx.lineTo(x + width, y + height); // Bottom right
|
|
262
|
+
ctx.lineTo(x, y + height); // Bottom left
|
|
263
|
+
ctx.closePath();
|
|
264
|
+
|
|
265
|
+
if (shapeProps.fill !== false) {
|
|
266
|
+
ctx.fill();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Creates trapezium path
|
|
272
|
+
*/
|
|
273
|
+
function createTrapeziumPath(
|
|
274
|
+
ctx: SKRSContext2D,
|
|
275
|
+
x: number,
|
|
276
|
+
y: number,
|
|
277
|
+
width: number,
|
|
278
|
+
height: number
|
|
279
|
+
): void {
|
|
280
|
+
const topWidth = width * 0.6; // Top is 60% of bottom width
|
|
281
|
+
const topOffset = (width - topWidth) / 2;
|
|
282
|
+
|
|
283
|
+
ctx.beginPath();
|
|
284
|
+
ctx.moveTo(x + topOffset, y); // Top left
|
|
285
|
+
ctx.lineTo(x + topOffset + topWidth, y); // Top right
|
|
286
|
+
ctx.lineTo(x + width, y + height); // Bottom right
|
|
287
|
+
ctx.lineTo(x, y + height); // Bottom left
|
|
288
|
+
ctx.closePath();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Draws a star
|
|
293
|
+
*/
|
|
294
|
+
function drawStar(
|
|
295
|
+
ctx: SKRSContext2D,
|
|
296
|
+
x: number,
|
|
297
|
+
y: number,
|
|
298
|
+
width: number,
|
|
299
|
+
height: number,
|
|
300
|
+
shapeProps: ShapeProperties
|
|
301
|
+
): void {
|
|
302
|
+
const centerX = x + width / 2;
|
|
303
|
+
const centerY = y + height / 2;
|
|
304
|
+
const outerRadius = shapeProps.outerRadius || Math.min(width, height) / 2;
|
|
305
|
+
const innerRadius = shapeProps.innerRadius || outerRadius * 0.4;
|
|
306
|
+
const points = 5; // 5-pointed star
|
|
307
|
+
|
|
308
|
+
ctx.beginPath();
|
|
309
|
+
|
|
310
|
+
for (let i = 0; i < points * 2; i++) {
|
|
311
|
+
const angle = (i * Math.PI) / points;
|
|
312
|
+
const radius = i % 2 === 0 ? outerRadius : innerRadius;
|
|
313
|
+
const pointX = centerX + Math.cos(angle - Math.PI / 2) * radius;
|
|
314
|
+
const pointY = centerY + Math.sin(angle - Math.PI / 2) * radius;
|
|
315
|
+
|
|
316
|
+
if (i === 0) {
|
|
317
|
+
ctx.moveTo(pointX, pointY);
|
|
318
|
+
} else {
|
|
319
|
+
ctx.lineTo(pointX, pointY);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
ctx.closePath();
|
|
324
|
+
|
|
325
|
+
if (shapeProps.fill !== false) {
|
|
326
|
+
ctx.fill();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Creates star path
|
|
332
|
+
*/
|
|
333
|
+
function createStarPath(
|
|
334
|
+
ctx: SKRSContext2D,
|
|
335
|
+
x: number,
|
|
336
|
+
y: number,
|
|
337
|
+
width: number,
|
|
338
|
+
height: number,
|
|
339
|
+
shapeProps: ShapeProperties
|
|
340
|
+
): void {
|
|
341
|
+
const centerX = x + width / 2;
|
|
342
|
+
const centerY = y + height / 2;
|
|
343
|
+
const outerRadius = shapeProps.outerRadius || Math.min(width, height) / 2;
|
|
344
|
+
const innerRadius = shapeProps.innerRadius || outerRadius * 0.4;
|
|
345
|
+
const points = 5; // 5-pointed star
|
|
346
|
+
|
|
347
|
+
ctx.beginPath();
|
|
348
|
+
|
|
349
|
+
for (let i = 0; i < points * 2; i++) {
|
|
350
|
+
const angle = (i * Math.PI) / points;
|
|
351
|
+
const radius = i % 2 === 0 ? outerRadius : innerRadius;
|
|
352
|
+
const pointX = centerX + Math.cos(angle - Math.PI / 2) * radius;
|
|
353
|
+
const pointY = centerY + Math.sin(angle - Math.PI / 2) * radius;
|
|
354
|
+
|
|
355
|
+
if (i === 0) {
|
|
356
|
+
ctx.moveTo(pointX, pointY);
|
|
357
|
+
} else {
|
|
358
|
+
ctx.lineTo(pointX, pointY);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
ctx.closePath();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Draws a heart shape with improved bezier curves
|
|
367
|
+
*/
|
|
368
|
+
function drawHeart(
|
|
369
|
+
ctx: SKRSContext2D,
|
|
370
|
+
x: number,
|
|
371
|
+
y: number,
|
|
372
|
+
width: number,
|
|
373
|
+
height: number,
|
|
374
|
+
shapeProps: ShapeProperties
|
|
375
|
+
): void {
|
|
376
|
+
ctx.beginPath();
|
|
377
|
+
|
|
378
|
+
ctx.moveTo(x + width / 2, y + height * 0.9);
|
|
379
|
+
|
|
380
|
+
ctx.bezierCurveTo(
|
|
381
|
+
x + (width * 35) / 100, y + (height * 60) / 100,
|
|
382
|
+
x + (width * 10) / 100, y + (height * 55) / 100,
|
|
383
|
+
x + (width * 10) / 100, y + (height * 33.33) / 100
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
ctx.bezierCurveTo(
|
|
387
|
+
x + (width * 10) / 100, y + (height * 10) / 100,
|
|
388
|
+
x + (width * 50) / 100, y + (height * 5) / 100,
|
|
389
|
+
x + (width * 50) / 100, y + (height * 33.33) / 100
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
ctx.bezierCurveTo(
|
|
393
|
+
x + (width * 50) / 100, y + (height * 5) / 100,
|
|
394
|
+
x + (width * 90) / 100, y + (height * 10) / 100,
|
|
395
|
+
x + (width * 90) / 100, y + (height * 33.33) / 100
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
ctx.bezierCurveTo(
|
|
399
|
+
x + (width * 90) / 100, y + (height * 55) / 100,
|
|
400
|
+
x + (width * 65) / 100, y + (height * 60) / 100,
|
|
401
|
+
x + width / 2, y + height * 0.9
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
ctx.closePath();
|
|
405
|
+
|
|
406
|
+
if (shapeProps.fill !== false) {
|
|
407
|
+
ctx.fill();
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Creates heart path with improved bezier curves
|
|
413
|
+
*/
|
|
414
|
+
function createHeartPath(
|
|
415
|
+
ctx: SKRSContext2D,
|
|
416
|
+
x: number,
|
|
417
|
+
y: number,
|
|
418
|
+
width: number,
|
|
419
|
+
height: number
|
|
420
|
+
): void {
|
|
421
|
+
ctx.beginPath();
|
|
422
|
+
|
|
423
|
+
ctx.moveTo(x + width / 2, y + height * 0.9);
|
|
424
|
+
|
|
425
|
+
ctx.bezierCurveTo(
|
|
426
|
+
x + (width * 35) / 100, y + (height * 60) / 100,
|
|
427
|
+
x + (width * 10) / 100, y + (height * 55) / 100,
|
|
428
|
+
x + (width * 10) / 100, y + (height * 33.33) / 100
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
ctx.bezierCurveTo(
|
|
432
|
+
x + (width * 10) / 100, y + (height * 10) / 100,
|
|
433
|
+
x + (width * 50) / 100, y + (height * 5) / 100,
|
|
434
|
+
x + (width * 50) / 100, y + (height * 33.33) / 100
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
ctx.bezierCurveTo(
|
|
438
|
+
x + (width * 50) / 100, y + (height * 5) / 100,
|
|
439
|
+
x + (width * 90) / 100, y + (height * 10) / 100,
|
|
440
|
+
x + (width * 90) / 100, y + (height * 33.33) / 100
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
ctx.bezierCurveTo(
|
|
444
|
+
x + (width * 90) / 100, y + (height * 55) / 100,
|
|
445
|
+
x + (width * 65) / 100, y + (height * 60) / 100,
|
|
446
|
+
x + width / 2, y + height * 0.9
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
ctx.closePath();
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Draws a polygon
|
|
454
|
+
*/
|
|
455
|
+
function drawPolygon(
|
|
456
|
+
ctx: SKRSContext2D,
|
|
457
|
+
x: number,
|
|
458
|
+
y: number,
|
|
459
|
+
width: number,
|
|
460
|
+
height: number,
|
|
461
|
+
shapeProps: ShapeProperties
|
|
462
|
+
): void {
|
|
463
|
+
const centerX = x + width / 2;
|
|
464
|
+
const centerY = y + height / 2;
|
|
465
|
+
const radius = Math.min(width, height) / 2;
|
|
466
|
+
const sides = shapeProps.sides || 6; // Default to hexagon
|
|
467
|
+
|
|
468
|
+
ctx.beginPath();
|
|
469
|
+
|
|
470
|
+
for (let i = 0; i < sides; i++) {
|
|
471
|
+
const angle = (i * 2 * Math.PI) / sides;
|
|
472
|
+
const pointX = centerX + Math.cos(angle - Math.PI / 2) * radius;
|
|
473
|
+
const pointY = centerY + Math.sin(angle - Math.PI / 2) * radius;
|
|
474
|
+
|
|
475
|
+
if (i === 0) {
|
|
476
|
+
ctx.moveTo(pointX, pointY);
|
|
477
|
+
} else {
|
|
478
|
+
ctx.lineTo(pointX, pointY);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
ctx.closePath();
|
|
483
|
+
|
|
484
|
+
if (shapeProps.fill !== false) {
|
|
485
|
+
ctx.fill();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Creates polygon path
|
|
491
|
+
*/
|
|
492
|
+
function createPolygonPath(
|
|
493
|
+
ctx: SKRSContext2D,
|
|
494
|
+
x: number,
|
|
495
|
+
y: number,
|
|
496
|
+
width: number,
|
|
497
|
+
height: number,
|
|
498
|
+
shapeProps: ShapeProperties
|
|
499
|
+
): void {
|
|
500
|
+
const centerX = x + width / 2;
|
|
501
|
+
const centerY = y + height / 2;
|
|
502
|
+
const radius = Math.min(width, height) / 2;
|
|
503
|
+
const sides = shapeProps.sides || 6; // Default to hexagon
|
|
504
|
+
|
|
505
|
+
ctx.beginPath();
|
|
506
|
+
|
|
507
|
+
for (let i = 0; i < sides; i++) {
|
|
508
|
+
const angle = (i * 2 * Math.PI) / sides;
|
|
509
|
+
const pointX = centerX + Math.cos(angle - Math.PI / 2) * radius;
|
|
510
|
+
const pointY = centerY + Math.sin(angle - Math.PI / 2) * radius;
|
|
511
|
+
|
|
512
|
+
if (i === 0) {
|
|
513
|
+
ctx.moveTo(pointX, pointY);
|
|
514
|
+
} else {
|
|
515
|
+
ctx.lineTo(pointX, pointY);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
ctx.closePath();
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Checks if a source is a shape type
|
|
524
|
+
*/
|
|
525
|
+
export function isShapeSource(source: string | Buffer | ShapeType): source is ShapeType {
|
|
526
|
+
const shapeTypes: ShapeType[] = ['rectangle', 'square', 'circle', 'triangle', 'trapezium', 'star', 'heart', 'polygon'];
|
|
527
|
+
return typeof source === 'string' && shapeTypes.includes(source as ShapeType);
|
|
528
|
+
}
|