apexify.js 4.6.2 → 4.7.0
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/cjs/ai/ApexModules.d.ts.map +1 -1
- package/dist/cjs/ai/ApexModules.js +56 -7
- package/dist/cjs/ai/ApexModules.js.map +1 -1
- package/dist/cjs/ai/functions/readFiles.js +1 -1
- package/dist/cjs/ai/functions/readFiles.js.map +1 -1
- package/dist/cjs/ai/modals-chat/electronHub/chatmodels.d.ts.map +1 -1
- package/dist/cjs/ai/modals-chat/electronHub/chatmodels.js +2 -1
- package/dist/cjs/ai/modals-chat/electronHub/chatmodels.js.map +1 -1
- package/dist/cjs/ai/modals-chat/electronHub/speechModels.d.ts.map +1 -1
- package/dist/cjs/ai/modals-chat/electronHub/speechModels.js +1 -1
- package/dist/cjs/ai/modals-chat/electronHub/speechModels.js.map +1 -1
- package/dist/cjs/canvas/ApexPainter.d.ts.map +1 -1
- package/dist/cjs/canvas/ApexPainter.js +27 -28
- package/dist/cjs/canvas/ApexPainter.js.map +1 -1
- package/dist/cjs/canvas/Themes/Level-Up/levelup.d.ts +11 -0
- package/dist/cjs/canvas/Themes/Level-Up/levelup.d.ts.map +1 -0
- package/dist/cjs/canvas/Themes/Level-Up/levelup.js +163 -0
- package/dist/cjs/canvas/Themes/Level-Up/levelup.js.map +1 -0
- package/dist/cjs/canvas/utils/Background/bg.d.ts +17 -10
- package/dist/cjs/canvas/utils/Background/bg.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/Background/bg.js +102 -27
- package/dist/cjs/canvas/utils/Background/bg.js.map +1 -1
- package/dist/cjs/canvas/utils/Custom/customLines.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/Custom/customLines.js +43 -19
- package/dist/cjs/canvas/utils/Custom/customLines.js.map +1 -1
- package/dist/cjs/canvas/utils/General/general functions.d.ts +6 -1
- package/dist/cjs/canvas/utils/General/general functions.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/General/general functions.js +19 -20
- package/dist/cjs/canvas/utils/General/general functions.js.map +1 -1
- package/dist/cjs/canvas/utils/Image/imageProperties.d.ts +3 -9
- package/dist/cjs/canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/Image/imageProperties.js +220 -214
- package/dist/cjs/canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/cjs/canvas/utils/Texts/textProperties.d.ts +12 -14
- package/dist/cjs/canvas/utils/Texts/textProperties.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/Texts/textProperties.js +100 -91
- package/dist/cjs/canvas/utils/Texts/textProperties.js.map +1 -1
- package/dist/cjs/canvas/utils/types.d.ts +89 -109
- package/dist/cjs/canvas/utils/types.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/types.js.map +1 -1
- package/dist/cjs/canvas/utils/utils.d.ts +2 -4
- package/dist/cjs/canvas/utils/utils.d.ts.map +1 -1
- package/dist/cjs/canvas/utils/utils.js +2 -5
- package/dist/cjs/canvas/utils/utils.js.map +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +31 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/ai/ApexModules.d.ts.map +1 -1
- package/dist/esm/ai/ApexModules.js +56 -7
- package/dist/esm/ai/ApexModules.js.map +1 -1
- package/dist/esm/ai/functions/readFiles.js +1 -1
- package/dist/esm/ai/functions/readFiles.js.map +1 -1
- package/dist/esm/ai/modals-chat/electronHub/chatmodels.d.ts.map +1 -1
- package/dist/esm/ai/modals-chat/electronHub/chatmodels.js +2 -1
- package/dist/esm/ai/modals-chat/electronHub/chatmodels.js.map +1 -1
- package/dist/esm/ai/modals-chat/electronHub/speechModels.d.ts.map +1 -1
- package/dist/esm/ai/modals-chat/electronHub/speechModels.js +1 -1
- package/dist/esm/ai/modals-chat/electronHub/speechModels.js.map +1 -1
- package/dist/esm/canvas/ApexPainter.d.ts.map +1 -1
- package/dist/esm/canvas/ApexPainter.js +27 -28
- package/dist/esm/canvas/ApexPainter.js.map +1 -1
- package/dist/esm/canvas/Themes/Level-Up/levelup.d.ts +11 -0
- package/dist/esm/canvas/Themes/Level-Up/levelup.d.ts.map +1 -0
- package/dist/esm/canvas/Themes/Level-Up/levelup.js +163 -0
- package/dist/esm/canvas/Themes/Level-Up/levelup.js.map +1 -0
- package/dist/esm/canvas/utils/Background/bg.d.ts +17 -10
- package/dist/esm/canvas/utils/Background/bg.d.ts.map +1 -1
- package/dist/esm/canvas/utils/Background/bg.js +102 -27
- package/dist/esm/canvas/utils/Background/bg.js.map +1 -1
- package/dist/esm/canvas/utils/Custom/customLines.d.ts.map +1 -1
- package/dist/esm/canvas/utils/Custom/customLines.js +43 -19
- package/dist/esm/canvas/utils/Custom/customLines.js.map +1 -1
- package/dist/esm/canvas/utils/General/general functions.d.ts +6 -1
- package/dist/esm/canvas/utils/General/general functions.d.ts.map +1 -1
- package/dist/esm/canvas/utils/General/general functions.js +19 -20
- package/dist/esm/canvas/utils/General/general functions.js.map +1 -1
- package/dist/esm/canvas/utils/Image/imageProperties.d.ts +3 -9
- package/dist/esm/canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/esm/canvas/utils/Image/imageProperties.js +220 -214
- package/dist/esm/canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/esm/canvas/utils/Texts/textProperties.d.ts +12 -14
- package/dist/esm/canvas/utils/Texts/textProperties.d.ts.map +1 -1
- package/dist/esm/canvas/utils/Texts/textProperties.js +100 -91
- package/dist/esm/canvas/utils/Texts/textProperties.js.map +1 -1
- package/dist/esm/canvas/utils/types.d.ts +89 -109
- package/dist/esm/canvas/utils/types.d.ts.map +1 -1
- package/dist/esm/canvas/utils/types.js.map +1 -1
- package/dist/esm/canvas/utils/utils.d.ts +2 -4
- package/dist/esm/canvas/utils/utils.d.ts.map +1 -1
- package/dist/esm/canvas/utils/utils.js +2 -5
- package/dist/esm/canvas/utils/utils.js.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +31 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/ai/ApexModules.ts +83 -11
- package/lib/ai/functions/readFiles.ts +1 -1
- package/lib/ai/modals-chat/electronHub/chatmodels.ts +4 -2
- package/lib/ai/modals-chat/electronHub/speechModels.ts +2 -1
- package/lib/canvas/ApexPainter.ts +52 -61
- package/lib/canvas/Themes/Level-Up/levelup.ts +183 -0
- package/lib/canvas/utils/Background/bg.ts +179 -65
- package/lib/canvas/utils/Custom/customLines.ts +53 -20
- package/lib/canvas/utils/General/general functions.ts +21 -29
- package/lib/canvas/utils/Image/imageProperties.ts +399 -318
- package/lib/canvas/utils/Texts/textProperties.ts +213 -162
- package/lib/canvas/utils/types.ts +74 -107
- package/lib/canvas/utils/utils.ts +2 -5
- package/lib/index.ts +38 -10
- package/package.json +3 -2
- package/dist/cjs/canvas/utils/Background/circular.d.ts +0 -3
- package/dist/cjs/canvas/utils/Background/circular.d.ts.map +0 -1
- package/dist/cjs/canvas/utils/Background/circular.js +0 -13
- package/dist/cjs/canvas/utils/Background/circular.js.map +0 -1
- package/dist/cjs/canvas/utils/Background/radius.d.ts +0 -18
- package/dist/cjs/canvas/utils/Background/radius.d.ts.map +0 -1
- package/dist/cjs/canvas/utils/Background/radius.js +0 -104
- package/dist/cjs/canvas/utils/Background/radius.js.map +0 -1
- package/dist/esm/canvas/utils/Background/circular.d.ts +0 -3
- package/dist/esm/canvas/utils/Background/circular.d.ts.map +0 -1
- package/dist/esm/canvas/utils/Background/circular.js +0 -13
- package/dist/esm/canvas/utils/Background/circular.js.map +0 -1
- package/dist/esm/canvas/utils/Background/radius.d.ts +0 -18
- package/dist/esm/canvas/utils/Background/radius.d.ts.map +0 -1
- package/dist/esm/canvas/utils/Background/radius.js +0 -104
- package/dist/esm/canvas/utils/Background/radius.js.map +0 -1
- package/lib/canvas/utils/Background/circular.ts +0 -17
- package/lib/canvas/utils/Background/radius.ts +0 -102
|
@@ -34,13 +34,15 @@ export function applyShadow(
|
|
|
34
34
|
width,
|
|
35
35
|
height,
|
|
36
36
|
shadow.borderRadius ?? 2,
|
|
37
|
-
shadow.borderPosition
|
|
38
37
|
);
|
|
39
38
|
|
|
40
39
|
ctx.fillStyle = shadow.gradient
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
? createGradient(
|
|
41
|
+
ctx, shadow.gradient,
|
|
42
|
+
shadowX, shadowY,
|
|
43
|
+
shadowX + width, shadowY + height
|
|
44
|
+
)
|
|
45
|
+
: shadow.color || "transparent";
|
|
44
46
|
ctx.fill();
|
|
45
47
|
}
|
|
46
48
|
|
|
@@ -68,62 +70,101 @@ export function applyZoom(
|
|
|
68
70
|
ctx.translate(-zoomX, -zoomY);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
* Applies stroke to the canvas context with support for selective side strokes.
|
|
73
|
-
* If stroke.borderPosition is "all", it uses the full rounded path.
|
|
74
|
-
* Otherwise, it constructs individual segments for the specified sides.
|
|
75
|
-
*
|
|
76
|
-
* @param ctx The canvas rendering context.
|
|
77
|
-
* @param stroke The stroke properties.
|
|
78
|
-
* @param x The x-coordinate of the shape.
|
|
79
|
-
* @param y The y-coordinate of the shape.
|
|
80
|
-
* @param width The width of the shape.
|
|
81
|
-
* @param height The height of the shape.
|
|
82
|
-
*/
|
|
83
|
-
export function applyStroke(
|
|
84
|
-
ctx: SKRSContext2D,
|
|
85
|
-
stroke: ImageProperties['stroke'],
|
|
86
|
-
x: number,
|
|
87
|
-
y: number,
|
|
88
|
-
width: number,
|
|
89
|
-
height: number
|
|
90
|
-
): void {
|
|
91
|
-
if (!stroke) return;
|
|
92
|
-
|
|
93
|
-
ctx.save();
|
|
94
|
-
ctx.beginPath();
|
|
95
|
-
|
|
96
|
-
ctx.strokeStyle = stroke.gradient
|
|
97
|
-
? createGradient(ctx, stroke.gradient, x, y, x + width, y + height)
|
|
98
|
-
: stroke.color || "transparent";
|
|
99
|
-
|
|
100
|
-
ctx.lineWidth = stroke.width && stroke.width > 0 ? stroke.width : 2;
|
|
101
|
-
|
|
102
|
-
const positionOffset = stroke.position ?? 0;
|
|
103
|
-
const halfStroke = ctx.lineWidth / 2;
|
|
104
|
-
const totalOffset = positionOffset > 0 ? positionOffset + halfStroke : 0;
|
|
105
|
-
|
|
106
|
-
const adjustedBorderRadius = stroke.borderRadius === "circular"
|
|
107
|
-
? "circular"
|
|
108
|
-
: (stroke.borderRadius ?? 2) + halfStroke;
|
|
109
|
-
|
|
110
|
-
const adjustedX = x - totalOffset;
|
|
111
|
-
const adjustedY = y - totalOffset;
|
|
112
|
-
const adjustedWidth = width + totalOffset * 2;
|
|
113
|
-
const adjustedHeight = height + totalOffset * 2;
|
|
114
|
-
|
|
115
|
-
objectRadius(ctx, adjustedX, adjustedY, adjustedWidth, adjustedHeight, adjustedBorderRadius, "all");
|
|
116
|
-
|
|
117
|
-
ctx.stroke();
|
|
118
|
-
ctx.restore();
|
|
119
|
-
}
|
|
120
|
-
|
|
73
|
+
|
|
121
74
|
/**
|
|
122
|
-
*
|
|
123
|
-
* Supports
|
|
124
|
-
*
|
|
125
|
-
* @param
|
|
75
|
+
* Applies stroke to the canvas context with support for selective side strokes.
|
|
76
|
+
* Supports optional blur effect on the stroke.
|
|
77
|
+
*
|
|
78
|
+
* @param ctx The canvas rendering context.
|
|
79
|
+
* @param stroke The stroke properties.
|
|
80
|
+
* @param x The x-coordinate of the shape.
|
|
81
|
+
* @param y The y-coordinate of the shape.
|
|
82
|
+
* @param width The width of the shape.
|
|
83
|
+
* @param height The height of the shape.
|
|
84
|
+
* @param blur Optional blur effect on the stroke.
|
|
126
85
|
*/
|
|
86
|
+
export function applyStroke(
|
|
87
|
+
ctx: SKRSContext2D,
|
|
88
|
+
stroke: ImageProperties["stroke"],
|
|
89
|
+
x: number,
|
|
90
|
+
y: number,
|
|
91
|
+
width: number,
|
|
92
|
+
height: number,
|
|
93
|
+
shapeName?: string,
|
|
94
|
+
isImage?: boolean
|
|
95
|
+
): void {
|
|
96
|
+
if (!stroke) return;
|
|
97
|
+
|
|
98
|
+
ctx.save();
|
|
99
|
+
|
|
100
|
+
if (stroke.blur && stroke.blur > 0) {
|
|
101
|
+
ctx.filter = `blur(${stroke.blur}px)`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
ctx.strokeStyle = stroke.gradient
|
|
105
|
+
? createGradient(ctx, stroke.gradient, x, y, x + width, y + height)
|
|
106
|
+
: stroke.color || "transparent";
|
|
107
|
+
|
|
108
|
+
ctx.lineWidth = stroke.width && stroke.width > 0 ? stroke.width : 2;
|
|
109
|
+
|
|
110
|
+
ctx.beginPath();
|
|
111
|
+
|
|
112
|
+
if (isImage) {
|
|
113
|
+
ctx.globalCompositeOperation = "source-atop";
|
|
114
|
+
ctx.rect(x, y, width, height);
|
|
115
|
+
} else if (["heart", "arrow", "circle", "star", "pentagon", "hexagon", "heptagon", "octagon", "diamond", "trapezoid", "kite"].includes(shapeName as string)) {
|
|
116
|
+
switch (shapeName) {
|
|
117
|
+
case "circle":
|
|
118
|
+
ctx.arc(x + width / 2, y + height / 2, width / 2, 0, Math.PI * 2);
|
|
119
|
+
break;
|
|
120
|
+
case "star":
|
|
121
|
+
drawStar(ctx, x, y, width, height);
|
|
122
|
+
break;
|
|
123
|
+
case "arrow":
|
|
124
|
+
drawArrow(ctx, x, y, width, height);
|
|
125
|
+
break;
|
|
126
|
+
case "pentagon": case "hexagon": case "heptagon": case "octagon":
|
|
127
|
+
const sides = parseInt(shapeName.replace(/\D/g, ""), 10);
|
|
128
|
+
drawPolygon(ctx, x, y, width, height, sides);
|
|
129
|
+
break;
|
|
130
|
+
case "diamond":
|
|
131
|
+
ctx.moveTo(x + width / 2, y);
|
|
132
|
+
ctx.lineTo(x + width, y + height / 2);
|
|
133
|
+
ctx.lineTo(x + width / 2, y + height);
|
|
134
|
+
ctx.lineTo(x, y + height / 2);
|
|
135
|
+
ctx.closePath();
|
|
136
|
+
break;
|
|
137
|
+
case "trapezoid":
|
|
138
|
+
const topWidth = width * 0.6;
|
|
139
|
+
const offset = (width - topWidth) / 2;
|
|
140
|
+
ctx.moveTo(x + offset, y);
|
|
141
|
+
ctx.lineTo(x + offset + topWidth, y);
|
|
142
|
+
ctx.lineTo(x + width, y + height);
|
|
143
|
+
ctx.lineTo(x, y + height);
|
|
144
|
+
ctx.closePath();
|
|
145
|
+
break;
|
|
146
|
+
case "heart":
|
|
147
|
+
drawHeart(ctx, x , y, width, height);
|
|
148
|
+
break;
|
|
149
|
+
case "kite":
|
|
150
|
+
ctx.moveTo(x + width / 2, y);
|
|
151
|
+
ctx.lineTo(x + width, y + height / 2);
|
|
152
|
+
ctx.lineTo(x + width / 2, y + height);
|
|
153
|
+
ctx.lineTo(x, y + height / 2);
|
|
154
|
+
ctx.closePath();
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
objectRadius(ctx, x, y, width, height, stroke.borderRadius || 2, "all");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
ctx.stroke();
|
|
162
|
+
ctx.filter = "none";
|
|
163
|
+
ctx.restore();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
127
168
|
export function drawShape(ctx: SKRSContext2D, shapeSettings: any): void {
|
|
128
169
|
const {
|
|
129
170
|
source,
|
|
@@ -139,10 +180,10 @@ export function drawShape(ctx: SKRSContext2D, shapeSettings: any): void {
|
|
|
139
180
|
isFilled = false,
|
|
140
181
|
color = "transparent",
|
|
141
182
|
gradient,
|
|
183
|
+
filling,
|
|
142
184
|
} = shapeSettings;
|
|
143
185
|
|
|
144
186
|
const shapeName = source.toLowerCase();
|
|
145
|
-
|
|
146
187
|
ctx.save();
|
|
147
188
|
|
|
148
189
|
applyRotation(ctx, rotation, x, y, width, height);
|
|
@@ -166,40 +207,13 @@ export function drawShape(ctx: SKRSContext2D, shapeSettings: any): void {
|
|
|
166
207
|
ctx.closePath();
|
|
167
208
|
break;
|
|
168
209
|
}
|
|
169
|
-
case 'pentagon': {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
case 'hexagon': {
|
|
174
|
-
drawPolygon(ctx, x, y, width, height, 6);
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
case 'heptagon': {
|
|
178
|
-
drawPolygon(ctx, x, y, width, height, 7);
|
|
179
|
-
break;
|
|
180
|
-
}
|
|
181
|
-
case 'octagon': {
|
|
182
|
-
drawPolygon(ctx, x, y, width, height, 8);
|
|
210
|
+
case 'pentagon': case 'hexagon': case 'heptagon': case 'octagon': {
|
|
211
|
+
const sides = parseInt(shapeName.replace(/\D/g, ""), 10);
|
|
212
|
+
drawPolygon(ctx, x, y, width, height, sides);
|
|
183
213
|
break;
|
|
184
214
|
}
|
|
185
215
|
case 'star': {
|
|
186
|
-
|
|
187
|
-
const cx = x + width / 2;
|
|
188
|
-
const cy = y + height / 2;
|
|
189
|
-
const outerRadius = Math.min(width, height) / 2;
|
|
190
|
-
const innerRadius = outerRadius / 2;
|
|
191
|
-
const step = Math.PI / 5;
|
|
192
|
-
for (let i = 0; i < 10; i++) {
|
|
193
|
-
const r = i % 2 === 0 ? outerRadius : innerRadius;
|
|
194
|
-
const angle = i * step - Math.PI / 2;
|
|
195
|
-
if (i === 0) {
|
|
196
|
-
ctx.moveTo(cx + r * Math.cos(angle), cy + r * Math.sin(angle));
|
|
197
|
-
} else {
|
|
198
|
-
ctx.lineTo(cx + r * Math.cos(angle), cy + r * Math.sin(angle));
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
ctx.closePath();
|
|
202
|
-
}
|
|
216
|
+
drawStar(ctx, x, y, width, height);
|
|
203
217
|
break;
|
|
204
218
|
}
|
|
205
219
|
case 'kite': {
|
|
@@ -214,31 +228,12 @@ export function drawShape(ctx: SKRSContext2D, shapeSettings: any): void {
|
|
|
214
228
|
ctx.ellipse(x + width / 2, y + height / 2, width / 2, height / 2, 0, 0, Math.PI * 2);
|
|
215
229
|
break;
|
|
216
230
|
}
|
|
217
|
-
case '
|
|
218
|
-
ctx
|
|
219
|
-
ctx.bezierCurveTo(
|
|
220
|
-
x + width * 0.1, y + height * 0.5,
|
|
221
|
-
x, y + height * 0.2,
|
|
222
|
-
x + width / 2, y + height * 0.3
|
|
223
|
-
);
|
|
224
|
-
ctx.bezierCurveTo(
|
|
225
|
-
x + width, y + height * 0.2,
|
|
226
|
-
x + width * 0.9, y + height * 0.5,
|
|
227
|
-
x + width / 2, y + height * 0.75
|
|
228
|
-
);
|
|
229
|
-
ctx.closePath();
|
|
231
|
+
case 'arrow': {
|
|
232
|
+
drawArrow(ctx, x, y, width, height);
|
|
230
233
|
break;
|
|
231
234
|
}
|
|
232
|
-
case '
|
|
233
|
-
|
|
234
|
-
ctx.moveTo(x, y + height / 2);
|
|
235
|
-
ctx.lineTo(x + width - arrowHeadWidth, y + height / 2);
|
|
236
|
-
ctx.lineTo(x + width - arrowHeadWidth, y);
|
|
237
|
-
ctx.lineTo(x + width, y + height / 2);
|
|
238
|
-
ctx.lineTo(x + width - arrowHeadWidth, y + height);
|
|
239
|
-
ctx.lineTo(x + width - arrowHeadWidth, y + height / 2);
|
|
240
|
-
ctx.lineTo(x, y + height / 2);
|
|
241
|
-
ctx.closePath();
|
|
235
|
+
case 'heart': {
|
|
236
|
+
drawHeart(ctx, x, y, width, height);
|
|
242
237
|
break;
|
|
243
238
|
}
|
|
244
239
|
case 'diamond': {
|
|
@@ -259,17 +254,6 @@ export function drawShape(ctx: SKRSContext2D, shapeSettings: any): void {
|
|
|
259
254
|
ctx.closePath();
|
|
260
255
|
break;
|
|
261
256
|
}
|
|
262
|
-
case 'cloud': {
|
|
263
|
-
const radius = width / 5;
|
|
264
|
-
ctx.moveTo(x + radius, y + height / 2);
|
|
265
|
-
ctx.arc(x + radius, y + height / 2, radius, Math.PI * 0.5, Math.PI * 1.5);
|
|
266
|
-
ctx.arc(x + width / 2, y + height / 2 - radius, radius, Math.PI, 0);
|
|
267
|
-
ctx.arc(x + width - radius, y + height / 2, radius, Math.PI * 1.5, Math.PI * 0.5);
|
|
268
|
-
ctx.lineTo(x + width, y + height);
|
|
269
|
-
ctx.lineTo(x, y + height);
|
|
270
|
-
ctx.closePath();
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
273
257
|
default: {
|
|
274
258
|
ctx.restore();
|
|
275
259
|
throw new Error(`Unsupported shape: ${shapeName}`);
|
|
@@ -280,108 +264,262 @@ export function drawShape(ctx: SKRSContext2D, shapeSettings: any): void {
|
|
|
280
264
|
if (borderRadius && shapeName !== 'circle' && shapeName !== 'oval') {
|
|
281
265
|
objectRadius(ctx, x, y, width, height, borderRadius, borderPosition);
|
|
282
266
|
}
|
|
267
|
+
|
|
268
|
+
let fillStyle: string | CanvasGradient = color;
|
|
269
|
+
|
|
283
270
|
if (gradient) {
|
|
284
|
-
|
|
285
|
-
|
|
271
|
+
fillStyle = createGradient(ctx, gradient, x, y, x + width, y + height);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (filling && filling.percentage <= 100) {
|
|
275
|
+
ctx.save();
|
|
276
|
+
|
|
277
|
+
const isCustomShape = ["heart", "arrow", "star", "pentagon", "hexagon", "heptagon", "octagon", "diamond", "trapezoid", "kite", "oval", "circle"].includes(shapeName);
|
|
278
|
+
|
|
279
|
+
if (isCustomShape) {
|
|
280
|
+
ctx.clip();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
let fillX = x;
|
|
284
|
+
let fillY = y;
|
|
285
|
+
let fillWidth = width;
|
|
286
|
+
let fillHeight = height;
|
|
287
|
+
|
|
288
|
+
switch (filling.rotation) {
|
|
289
|
+
case 0:
|
|
290
|
+
fillHeight = (filling.percentage / 100) * height;
|
|
291
|
+
fillY = y + height - fillHeight;
|
|
292
|
+
break;
|
|
293
|
+
|
|
294
|
+
case 180:
|
|
295
|
+
fillHeight = (filling.percentage / 100) * height;
|
|
296
|
+
break;
|
|
297
|
+
|
|
298
|
+
case 90:
|
|
299
|
+
fillWidth = (filling.percentage / 100) * width;
|
|
300
|
+
break;
|
|
301
|
+
|
|
302
|
+
case 270:
|
|
303
|
+
fillWidth = (filling.percentage / 100) * width;
|
|
304
|
+
fillX = x + width - fillWidth;
|
|
305
|
+
break;
|
|
306
|
+
|
|
307
|
+
default:
|
|
308
|
+
console.warn(`Unsupported filling rotation: ${filling.rotation}, defaulting to 0 (Bottom to Top).`);
|
|
309
|
+
fillHeight = (filling.percentage / 100) * height;
|
|
310
|
+
fillY = y + height - fillHeight;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
ctx.beginPath();
|
|
314
|
+
ctx.rect(fillX, fillY, fillWidth, fillHeight);
|
|
315
|
+
ctx.fillStyle = fillStyle;
|
|
316
|
+
ctx.fill();
|
|
317
|
+
|
|
318
|
+
ctx.restore();
|
|
286
319
|
} else {
|
|
287
|
-
ctx.fillStyle =
|
|
320
|
+
ctx.fillStyle = fillStyle;
|
|
321
|
+
ctx.fill();
|
|
288
322
|
}
|
|
289
|
-
ctx.fill();
|
|
290
323
|
}
|
|
324
|
+
|
|
291
325
|
|
|
292
326
|
if (stroke) {
|
|
293
|
-
applyStroke(ctx, stroke, x, y, width, height);
|
|
327
|
+
applyStroke(ctx, stroke, x, y, width, height, shapeName, false);
|
|
294
328
|
}
|
|
295
329
|
|
|
296
330
|
ctx.restore();
|
|
297
331
|
}
|
|
298
332
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
|
|
308
|
-
|
|
333
|
+
function drawHeart(ctx: SKRSContext2D, x: number, y: number, width: number, height: number): void {
|
|
334
|
+
ctx.beginPath();
|
|
335
|
+
|
|
336
|
+
ctx.moveTo(x + width / 2, y + height * 0.9);
|
|
337
|
+
|
|
338
|
+
ctx.bezierCurveTo(
|
|
339
|
+
x + (width * 35) / 100, y + (height * 60) / 100,
|
|
340
|
+
x + (width * 10) / 100, y + (height * 55) / 100,
|
|
341
|
+
x + (width * 10) / 100, y + (height * 33.33) / 100
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
ctx.bezierCurveTo(
|
|
345
|
+
x + (width * 10) / 100, y + (height * 10) / 100,
|
|
346
|
+
x + (width * 50) / 100, y + (height * 5) / 100,
|
|
347
|
+
x + (width * 50) / 100, y + (height * 33.33) / 100
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
ctx.bezierCurveTo(
|
|
351
|
+
x + (width * 50) / 100, y + (height * 5) / 100,
|
|
352
|
+
x + (width * 90) / 100, y + (height * 10) / 100,
|
|
353
|
+
x + (width * 90) / 100, y + (height * 33.33) / 100
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
ctx.bezierCurveTo(
|
|
357
|
+
x + (width * 90) / 100, y + (height * 55) / 100,
|
|
358
|
+
x + (width * 65) / 100, y + (height * 60) / 100,
|
|
359
|
+
x + width / 2, y + height * 0.9
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
ctx.closePath();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
/** Draws a polygon with a given number of sides */
|
|
309
367
|
function drawPolygon(ctx: SKRSContext2D, x: number, y: number, width: number, height: number, sides: number): void {
|
|
310
368
|
const cx = x + width / 2;
|
|
311
369
|
const cy = y + height / 2;
|
|
312
370
|
const radius = Math.min(width, height) / 2;
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
371
|
+
ctx.moveTo(cx + radius, cy);
|
|
372
|
+
for (let i = 1; i <= sides; i++) {
|
|
373
|
+
const angle = (Math.PI * 2 * i) / sides;
|
|
374
|
+
ctx.lineTo(cx + radius * Math.cos(angle), cy + radius * Math.sin(angle));
|
|
375
|
+
}
|
|
376
|
+
ctx.closePath();
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function drawArrow(ctx: SKRSContext2D, x: number, y: number, width: number, height: number) {
|
|
380
|
+
const shaftWidth = width * 0.25;
|
|
381
|
+
const headWidth = width * 0.5;
|
|
382
|
+
const headHeight = height * 0.6;
|
|
383
|
+
|
|
384
|
+
ctx.beginPath();
|
|
385
|
+
|
|
386
|
+
ctx.moveTo(x, y + height / 2 - shaftWidth / 2);
|
|
387
|
+
ctx.lineTo(x + width - headWidth, y + height / 2 - shaftWidth / 2);
|
|
388
|
+
ctx.lineTo(x + width - headWidth, y);
|
|
389
|
+
|
|
390
|
+
ctx.lineTo(x + width, y + height / 2);
|
|
391
|
+
|
|
392
|
+
ctx.lineTo(x + width - headWidth, y + height);
|
|
393
|
+
ctx.lineTo(x + width - headWidth, y + height / 2 + shaftWidth / 2);
|
|
394
|
+
|
|
395
|
+
ctx.lineTo(x, y + height / 2 + shaftWidth / 2);
|
|
396
|
+
ctx.closePath();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
function drawStar(ctx: SKRSContext2D, x: number, y: number, width: number, height: number): void {
|
|
401
|
+
const cx = x + width / 2;
|
|
402
|
+
const cy = y + height / 2;
|
|
403
|
+
|
|
404
|
+
const size = Math.min(width, height);
|
|
405
|
+
|
|
406
|
+
const outerRadius = size / 2;
|
|
407
|
+
const innerRadius = outerRadius * 0.5;
|
|
408
|
+
const rotationOffset = -Math.PI / 2;
|
|
409
|
+
|
|
410
|
+
ctx.beginPath();
|
|
411
|
+
|
|
412
|
+
for (let i = 0; i < 5; i++) {
|
|
413
|
+
let angle = (i * (Math.PI * 2)) / 5 + rotationOffset;
|
|
414
|
+
ctx.lineTo(cx + outerRadius * Math.cos(angle), cy + outerRadius * Math.sin(angle));
|
|
415
|
+
|
|
416
|
+
angle += Math.PI / 5;
|
|
417
|
+
ctx.lineTo(cx + innerRadius * Math.cos(angle), cy + innerRadius * Math.sin(angle));
|
|
320
418
|
}
|
|
419
|
+
|
|
321
420
|
ctx.closePath();
|
|
322
421
|
}
|
|
323
422
|
|
|
324
|
-
export function createGradient(
|
|
325
|
-
|
|
326
|
-
|
|
423
|
+
export function createGradient(
|
|
424
|
+
ctx: any,
|
|
425
|
+
gradientOptions: any,
|
|
426
|
+
startX: number,
|
|
427
|
+
startY: number,
|
|
428
|
+
endX: number,
|
|
429
|
+
endY: number
|
|
430
|
+
) {
|
|
431
|
+
if (!gradientOptions || !gradientOptions.type || !gradientOptions.colors) {
|
|
432
|
+
throw new Error(
|
|
433
|
+
"Invalid gradient options. Provide a valid object with type and colors properties."
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (!Array.isArray(gradientOptions.colors)) {
|
|
438
|
+
throw new Error(
|
|
439
|
+
"Invalid gradient options. The colors property should be an array of color stops."
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (gradientOptions.type === "linear") {
|
|
444
|
+
if (
|
|
445
|
+
typeof startX !== "number" ||
|
|
446
|
+
typeof startY !== "number" ||
|
|
447
|
+
typeof endX !== "number" ||
|
|
448
|
+
typeof endY !== "number"
|
|
449
|
+
) {
|
|
450
|
+
throw new Error(
|
|
451
|
+
"Invalid gradient options for linear gradient. Numeric values are required for startX, startY, endX, and endY."
|
|
452
|
+
);
|
|
327
453
|
}
|
|
328
454
|
|
|
329
|
-
if (
|
|
330
|
-
|
|
455
|
+
if (typeof gradientOptions.rotate === "number") {
|
|
456
|
+
const centerX = (startX + endX) / 2;
|
|
457
|
+
const centerY = (startY + endY) / 2;
|
|
458
|
+
const dx = endX - startX;
|
|
459
|
+
const dy = endY - startY;
|
|
460
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
461
|
+
const angleRad = (gradientOptions.rotate * Math.PI) / 180;
|
|
462
|
+
|
|
463
|
+
startX = centerX - (length / 2) * Math.cos(angleRad);
|
|
464
|
+
startY = centerY - (length / 2) * Math.sin(angleRad);
|
|
465
|
+
endX = centerX + (length / 2) * Math.cos(angleRad);
|
|
466
|
+
endY = centerY + (length / 2) * Math.sin(angleRad);
|
|
331
467
|
}
|
|
332
468
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const gradient = ctx.createLinearGradient(startX, startY, endX, endY);
|
|
343
|
-
|
|
344
|
-
for (const colorStop of gradientOptions.colors) {
|
|
345
|
-
if (typeof colorStop.stop !== "number" || typeof colorStop.color !== "string") {
|
|
346
|
-
throw new Error("Invalid color stop. Each color stop should have a numeric stop value and a color string.");
|
|
347
|
-
}
|
|
348
|
-
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return gradient;
|
|
352
|
-
|
|
353
|
-
} else if (gradientOptions.type === "radial") {
|
|
354
|
-
if (
|
|
355
|
-
typeof gradientOptions.startX !== "number" ||
|
|
356
|
-
typeof gradientOptions.startY !== "number" ||
|
|
357
|
-
typeof gradientOptions.startRadius !== "number" ||
|
|
358
|
-
typeof gradientOptions.endX !== "number" ||
|
|
359
|
-
typeof gradientOptions.endY !== "number" ||
|
|
360
|
-
typeof gradientOptions.endRadius !== "number"
|
|
361
|
-
) {
|
|
362
|
-
throw new Error("Invalid gradient options for radial gradient. Numeric values are required for startX, startY, startRadius, endX, endY, and endRadius.");
|
|
363
|
-
}
|
|
364
|
-
const gradient = ctx.createRadialGradient(
|
|
365
|
-
gradientOptions.startX,
|
|
366
|
-
gradientOptions.startY,
|
|
367
|
-
gradientOptions.startRadius,
|
|
368
|
-
gradientOptions.endX,
|
|
369
|
-
gradientOptions.endY,
|
|
370
|
-
gradientOptions.endRadius
|
|
469
|
+
const gradient = ctx.createLinearGradient(startX, startY, endX, endY);
|
|
470
|
+
|
|
471
|
+
for (const colorStop of gradientOptions.colors) {
|
|
472
|
+
if (
|
|
473
|
+
typeof colorStop.stop !== "number" ||
|
|
474
|
+
typeof colorStop.color !== "string"
|
|
475
|
+
) {
|
|
476
|
+
throw new Error(
|
|
477
|
+
"Invalid color stop. Each color stop should have a numeric stop value and a color string."
|
|
371
478
|
);
|
|
479
|
+
}
|
|
480
|
+
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
481
|
+
}
|
|
372
482
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
483
|
+
return gradient;
|
|
484
|
+
} else if (gradientOptions.type === "radial") {
|
|
485
|
+
if (
|
|
486
|
+
typeof gradientOptions.startX !== "number" ||
|
|
487
|
+
typeof gradientOptions.startY !== "number" ||
|
|
488
|
+
typeof gradientOptions.startRadius !== "number" ||
|
|
489
|
+
typeof gradientOptions.endX !== "number" ||
|
|
490
|
+
typeof gradientOptions.endY !== "number" ||
|
|
491
|
+
typeof gradientOptions.endRadius !== "number"
|
|
492
|
+
) {
|
|
493
|
+
throw new Error(
|
|
494
|
+
"Invalid gradient options for radial gradient. Numeric values are required for startX, startY, startRadius, endX, endY, and endRadius."
|
|
495
|
+
);
|
|
496
|
+
}
|
|
379
497
|
|
|
380
|
-
|
|
498
|
+
const gradient = ctx.createRadialGradient(
|
|
499
|
+
gradientOptions.startX,
|
|
500
|
+
gradientOptions.startY,
|
|
501
|
+
gradientOptions.startRadius,
|
|
502
|
+
gradientOptions.endX,
|
|
503
|
+
gradientOptions.endY,
|
|
504
|
+
gradientOptions.endRadius
|
|
505
|
+
);
|
|
381
506
|
|
|
382
|
-
|
|
383
|
-
|
|
507
|
+
for (const colorStop of gradientOptions.colors) {
|
|
508
|
+
if (
|
|
509
|
+
typeof colorStop.stop !== "number" ||
|
|
510
|
+
typeof colorStop.color !== "string"
|
|
511
|
+
) {
|
|
512
|
+
throw new Error(
|
|
513
|
+
"Invalid color stop. Each color stop should have a numeric stop value and a color string."
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
384
517
|
}
|
|
518
|
+
|
|
519
|
+
return gradient;
|
|
520
|
+
} else {
|
|
521
|
+
throw new Error('Unsupported gradient type. Use "linear" or "radial".');
|
|
522
|
+
}
|
|
385
523
|
}
|
|
386
524
|
|
|
387
525
|
|
|
@@ -442,17 +580,15 @@ export function applyRotation(
|
|
|
442
580
|
if (borderRadius === "circular") {
|
|
443
581
|
const circleRadius = Math.min(width, height) / 2;
|
|
444
582
|
ctx.arc(x + width / 2, y + height / 2, circleRadius, 0, 2 * Math.PI);
|
|
445
|
-
ctx.
|
|
446
|
-
} else {
|
|
447
|
-
const br: number =
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
const selectedCorners = new Set(bp.split(",").map((s) => s.trim()));
|
|
583
|
+
ctx.clip();
|
|
584
|
+
} else if (typeof borderRadius === "number" && borderRadius > 0) {
|
|
585
|
+
const br: number = Math.min(borderRadius, width / 2, height / 2);
|
|
586
|
+
const selectedPositions = new Set(borderPosition.toLowerCase().split(",").map((s) => s.trim()));
|
|
451
587
|
|
|
452
|
-
const roundTopLeft =
|
|
453
|
-
const roundTopRight =
|
|
454
|
-
const roundBottomRight =
|
|
455
|
-
const roundBottomLeft =
|
|
588
|
+
const roundTopLeft = selectedPositions.has("all") || selectedPositions.has("top-left") || (selectedPositions.has("top") && selectedPositions.has("left"));
|
|
589
|
+
const roundTopRight = selectedPositions.has("all") || selectedPositions.has("top-right") || (selectedPositions.has("top") && selectedPositions.has("right"));
|
|
590
|
+
const roundBottomRight = selectedPositions.has("all") || selectedPositions.has("bottom-right") || (selectedPositions.has("bottom") && selectedPositions.has("right"));
|
|
591
|
+
const roundBottomLeft = selectedPositions.has("all") || selectedPositions.has("bottom-left") || (selectedPositions.has("bottom") && selectedPositions.has("left"));
|
|
456
592
|
|
|
457
593
|
const tl = roundTopLeft ? br : 0;
|
|
458
594
|
const tr = roundTopRight ? br : 0;
|
|
@@ -460,43 +596,28 @@ export function applyRotation(
|
|
|
460
596
|
const bl = roundBottomLeft ? br : 0;
|
|
461
597
|
|
|
462
598
|
ctx.moveTo(x + tl, y);
|
|
463
|
-
|
|
464
|
-
if (
|
|
465
|
-
ctx.arcTo(x, y, x + width, y, tl);
|
|
466
|
-
} else if (roundTopLeft) {
|
|
467
|
-
ctx.arcTo(x, y, x + width, y, tl);
|
|
468
|
-
} else {
|
|
469
|
-
ctx.lineTo(x, y);
|
|
470
|
-
ctx.lineTo(x + width, y);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
if (tr > 0) {
|
|
474
|
-
ctx.arcTo(x + width, y, x + width, y + height, tr);
|
|
475
|
-
}
|
|
476
|
-
|
|
599
|
+
ctx.lineTo(x + width - tr, y);
|
|
600
|
+
if (tr > 0) ctx.arc(x + width - tr, y + tr, tr, -Math.PI / 2, 0, false);
|
|
477
601
|
ctx.lineTo(x + width, y + height - brR);
|
|
478
|
-
if (brR > 0)
|
|
479
|
-
ctx.arcTo(x + width, y + height, x, y + height, brR);
|
|
480
|
-
}
|
|
481
|
-
|
|
602
|
+
if (brR > 0) ctx.arc(x + width - brR, y + height - brR, brR, 0, Math.PI / 2, false);
|
|
482
603
|
ctx.lineTo(x + bl, y + height);
|
|
483
|
-
if (bl > 0)
|
|
484
|
-
ctx.arcTo(x, y + height, x, y, bl);
|
|
485
|
-
}
|
|
486
|
-
|
|
604
|
+
if (bl > 0) ctx.arc(x + bl, y + height - bl, bl, Math.PI / 2, Math.PI, false);
|
|
487
605
|
ctx.lineTo(x, y + tl);
|
|
488
|
-
if (tl > 0)
|
|
489
|
-
ctx.arcTo(x, y, x + tl, y, tl);
|
|
490
|
-
}
|
|
606
|
+
if (tl > 0) ctx.arc(x + tl, y + tl, tl, Math.PI, -Math.PI / 2, false);
|
|
491
607
|
|
|
492
608
|
ctx.closePath();
|
|
609
|
+
ctx.clip();
|
|
610
|
+
} else {
|
|
611
|
+
ctx.rect(x, y, width, height);
|
|
612
|
+
ctx.clip();
|
|
493
613
|
}
|
|
494
614
|
|
|
495
|
-
ctx.clip();
|
|
496
615
|
ctx.drawImage(image, x, y, width, height);
|
|
616
|
+
|
|
497
617
|
ctx.restore();
|
|
498
618
|
}
|
|
499
619
|
|
|
620
|
+
|
|
500
621
|
|
|
501
622
|
/**
|
|
502
623
|
* Creates a rounded rectangle (or circular) path on the canvas context.
|
|
@@ -514,91 +635,51 @@ export function applyRotation(
|
|
|
514
635
|
* - Or a comma-separated list, e.g. "top-left, bottom-right" or "top, left, bottom"
|
|
515
636
|
*/
|
|
516
637
|
export function objectRadius(
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const positions = bp.split(',').map(s => s.trim());
|
|
558
|
-
roundTopLeft = positions.includes('top-left') || (positions.includes('top') && positions.includes('left'));
|
|
559
|
-
roundTopRight = positions.includes('top-right') || (positions.includes('top') && positions.includes('right'));
|
|
560
|
-
roundBottomRight = positions.includes('bottom-right') || (positions.includes('bottom') && positions.includes('right'));
|
|
561
|
-
roundBottomLeft = positions.includes('bottom-left') || (positions.includes('bottom') && positions.includes('left'));
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
const tl = roundTopLeft ? +borderRadius : 0;
|
|
565
|
-
const tr = roundTopRight ? +borderRadius : 0;
|
|
566
|
-
const br = roundBottomRight ? +borderRadius : 0;
|
|
567
|
-
const bl = roundBottomLeft ? +borderRadius : 0;
|
|
568
|
-
|
|
569
|
-
ctx.beginPath();
|
|
570
|
-
ctx.moveTo(x + tl, y);
|
|
571
|
-
ctx.lineTo(x + width - tr, y);
|
|
572
|
-
if (tr > 0) {
|
|
573
|
-
ctx.quadraticCurveTo(x + width, y, x + width, y + tr);
|
|
574
|
-
} else {
|
|
575
|
-
ctx.lineTo(x + width, y);
|
|
576
|
-
}
|
|
577
|
-
ctx.lineTo(x + width, y + height - br);
|
|
578
|
-
if (br > 0) {
|
|
579
|
-
ctx.quadraticCurveTo(x + width, y + height, x + width - br, y + height);
|
|
580
|
-
} else {
|
|
581
|
-
ctx.lineTo(x + width, y + height);
|
|
582
|
-
}
|
|
583
|
-
ctx.lineTo(x + bl, y + height);
|
|
584
|
-
if (bl > 0) {
|
|
585
|
-
ctx.quadraticCurveTo(x, y + height, x, y + height - bl);
|
|
586
|
-
} else {
|
|
587
|
-
ctx.lineTo(x, y + height);
|
|
588
|
-
}
|
|
589
|
-
ctx.lineTo(x, y + tl);
|
|
590
|
-
if (tl > 0) {
|
|
591
|
-
ctx.quadraticCurveTo(x, y, x + tl, y);
|
|
592
|
-
} else {
|
|
593
|
-
ctx.lineTo(x, y);
|
|
594
|
-
}
|
|
595
|
-
ctx.closePath();
|
|
596
|
-
} else {
|
|
597
|
-
ctx.beginPath();
|
|
598
|
-
ctx.rect(x, y, width, height);
|
|
599
|
-
ctx.closePath();
|
|
600
|
-
}
|
|
638
|
+
ctx: SKRSContext2D,
|
|
639
|
+
x: number,
|
|
640
|
+
y: number,
|
|
641
|
+
width: number,
|
|
642
|
+
height: number,
|
|
643
|
+
borderRadius: number | "circular" = 0.1,
|
|
644
|
+
borderPosition: string = "all"
|
|
645
|
+
): void {
|
|
646
|
+
ctx.beginPath();
|
|
647
|
+
|
|
648
|
+
if (borderRadius === "circular") {
|
|
649
|
+
const circleRadius = Math.min(width, height) / 2;
|
|
650
|
+
ctx.arc(x + width / 2, y + height / 2, circleRadius, 0, 2 * Math.PI);
|
|
651
|
+
} else if (borderRadius > 0) {
|
|
652
|
+
const br: number = Math.min(borderRadius, width / 2, height / 2);
|
|
653
|
+
const selectedPositions = new Set(
|
|
654
|
+
borderPosition.toLowerCase().split(",").map((s) => s.trim())
|
|
655
|
+
);
|
|
656
|
+
|
|
657
|
+
const roundTopLeft = selectedPositions.has("all") || selectedPositions.has("top-left") || (selectedPositions.has("top") && selectedPositions.has("left"));
|
|
658
|
+
const roundTopRight = selectedPositions.has("all") || selectedPositions.has("top-right") || (selectedPositions.has("top") && selectedPositions.has("right"));
|
|
659
|
+
const roundBottomRight = selectedPositions.has("all") || selectedPositions.has("bottom-right") || (selectedPositions.has("bottom") && selectedPositions.has("right"));
|
|
660
|
+
const roundBottomLeft = selectedPositions.has("all") || selectedPositions.has("bottom-left") || (selectedPositions.has("bottom") && selectedPositions.has("left"));
|
|
661
|
+
|
|
662
|
+
const tl = roundTopLeft ? br : 0;
|
|
663
|
+
const tr = roundTopRight ? br : 0;
|
|
664
|
+
const brR = roundBottomRight ? br : 0;
|
|
665
|
+
const bl = roundBottomLeft ? br : 0;
|
|
666
|
+
|
|
667
|
+
ctx.moveTo(x + tl, y);
|
|
668
|
+
ctx.lineTo(x + width - tr, y);
|
|
669
|
+
if (tr > 0) ctx.arc(x + width - tr, y + tr, tr, -Math.PI / 2, 0, false);
|
|
670
|
+
ctx.lineTo(x + width, y + height - brR);
|
|
671
|
+
if (brR > 0) ctx.arc(x + width - brR, y + height - brR, brR, 0, Math.PI / 2, false);
|
|
672
|
+
ctx.lineTo(x + bl, y + height);
|
|
673
|
+
if (bl > 0) ctx.arc(x + bl, y + height - bl, bl, Math.PI / 2, Math.PI, false);
|
|
674
|
+
ctx.lineTo(x, y + tl);
|
|
675
|
+
if (tl > 0) ctx.arc(x + tl, y + tl, tl, Math.PI, -Math.PI / 2, false);
|
|
676
|
+
} else {
|
|
677
|
+
ctx.rect(x, y, width, height);
|
|
601
678
|
}
|
|
679
|
+
|
|
680
|
+
ctx.closePath();
|
|
681
|
+
}
|
|
682
|
+
|
|
602
683
|
|
|
603
684
|
|
|
604
685
|
/**
|