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.
Files changed (129) hide show
  1. package/dist/cjs/ai/ApexModules.d.ts.map +1 -1
  2. package/dist/cjs/ai/ApexModules.js +56 -7
  3. package/dist/cjs/ai/ApexModules.js.map +1 -1
  4. package/dist/cjs/ai/functions/readFiles.js +1 -1
  5. package/dist/cjs/ai/functions/readFiles.js.map +1 -1
  6. package/dist/cjs/ai/modals-chat/electronHub/chatmodels.d.ts.map +1 -1
  7. package/dist/cjs/ai/modals-chat/electronHub/chatmodels.js +2 -1
  8. package/dist/cjs/ai/modals-chat/electronHub/chatmodels.js.map +1 -1
  9. package/dist/cjs/ai/modals-chat/electronHub/speechModels.d.ts.map +1 -1
  10. package/dist/cjs/ai/modals-chat/electronHub/speechModels.js +1 -1
  11. package/dist/cjs/ai/modals-chat/electronHub/speechModels.js.map +1 -1
  12. package/dist/cjs/canvas/ApexPainter.d.ts.map +1 -1
  13. package/dist/cjs/canvas/ApexPainter.js +27 -28
  14. package/dist/cjs/canvas/ApexPainter.js.map +1 -1
  15. package/dist/cjs/canvas/Themes/Level-Up/levelup.d.ts +11 -0
  16. package/dist/cjs/canvas/Themes/Level-Up/levelup.d.ts.map +1 -0
  17. package/dist/cjs/canvas/Themes/Level-Up/levelup.js +163 -0
  18. package/dist/cjs/canvas/Themes/Level-Up/levelup.js.map +1 -0
  19. package/dist/cjs/canvas/utils/Background/bg.d.ts +17 -10
  20. package/dist/cjs/canvas/utils/Background/bg.d.ts.map +1 -1
  21. package/dist/cjs/canvas/utils/Background/bg.js +102 -27
  22. package/dist/cjs/canvas/utils/Background/bg.js.map +1 -1
  23. package/dist/cjs/canvas/utils/Custom/customLines.d.ts.map +1 -1
  24. package/dist/cjs/canvas/utils/Custom/customLines.js +43 -19
  25. package/dist/cjs/canvas/utils/Custom/customLines.js.map +1 -1
  26. package/dist/cjs/canvas/utils/General/general functions.d.ts +6 -1
  27. package/dist/cjs/canvas/utils/General/general functions.d.ts.map +1 -1
  28. package/dist/cjs/canvas/utils/General/general functions.js +19 -20
  29. package/dist/cjs/canvas/utils/General/general functions.js.map +1 -1
  30. package/dist/cjs/canvas/utils/Image/imageProperties.d.ts +3 -9
  31. package/dist/cjs/canvas/utils/Image/imageProperties.d.ts.map +1 -1
  32. package/dist/cjs/canvas/utils/Image/imageProperties.js +220 -214
  33. package/dist/cjs/canvas/utils/Image/imageProperties.js.map +1 -1
  34. package/dist/cjs/canvas/utils/Texts/textProperties.d.ts +12 -14
  35. package/dist/cjs/canvas/utils/Texts/textProperties.d.ts.map +1 -1
  36. package/dist/cjs/canvas/utils/Texts/textProperties.js +100 -91
  37. package/dist/cjs/canvas/utils/Texts/textProperties.js.map +1 -1
  38. package/dist/cjs/canvas/utils/types.d.ts +89 -109
  39. package/dist/cjs/canvas/utils/types.d.ts.map +1 -1
  40. package/dist/cjs/canvas/utils/types.js.map +1 -1
  41. package/dist/cjs/canvas/utils/utils.d.ts +2 -4
  42. package/dist/cjs/canvas/utils/utils.d.ts.map +1 -1
  43. package/dist/cjs/canvas/utils/utils.js +2 -5
  44. package/dist/cjs/canvas/utils/utils.js.map +1 -1
  45. package/dist/cjs/index.d.ts.map +1 -1
  46. package/dist/cjs/index.js +31 -3
  47. package/dist/cjs/index.js.map +1 -1
  48. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  49. package/dist/esm/ai/ApexModules.d.ts.map +1 -1
  50. package/dist/esm/ai/ApexModules.js +56 -7
  51. package/dist/esm/ai/ApexModules.js.map +1 -1
  52. package/dist/esm/ai/functions/readFiles.js +1 -1
  53. package/dist/esm/ai/functions/readFiles.js.map +1 -1
  54. package/dist/esm/ai/modals-chat/electronHub/chatmodels.d.ts.map +1 -1
  55. package/dist/esm/ai/modals-chat/electronHub/chatmodels.js +2 -1
  56. package/dist/esm/ai/modals-chat/electronHub/chatmodels.js.map +1 -1
  57. package/dist/esm/ai/modals-chat/electronHub/speechModels.d.ts.map +1 -1
  58. package/dist/esm/ai/modals-chat/electronHub/speechModels.js +1 -1
  59. package/dist/esm/ai/modals-chat/electronHub/speechModels.js.map +1 -1
  60. package/dist/esm/canvas/ApexPainter.d.ts.map +1 -1
  61. package/dist/esm/canvas/ApexPainter.js +27 -28
  62. package/dist/esm/canvas/ApexPainter.js.map +1 -1
  63. package/dist/esm/canvas/Themes/Level-Up/levelup.d.ts +11 -0
  64. package/dist/esm/canvas/Themes/Level-Up/levelup.d.ts.map +1 -0
  65. package/dist/esm/canvas/Themes/Level-Up/levelup.js +163 -0
  66. package/dist/esm/canvas/Themes/Level-Up/levelup.js.map +1 -0
  67. package/dist/esm/canvas/utils/Background/bg.d.ts +17 -10
  68. package/dist/esm/canvas/utils/Background/bg.d.ts.map +1 -1
  69. package/dist/esm/canvas/utils/Background/bg.js +102 -27
  70. package/dist/esm/canvas/utils/Background/bg.js.map +1 -1
  71. package/dist/esm/canvas/utils/Custom/customLines.d.ts.map +1 -1
  72. package/dist/esm/canvas/utils/Custom/customLines.js +43 -19
  73. package/dist/esm/canvas/utils/Custom/customLines.js.map +1 -1
  74. package/dist/esm/canvas/utils/General/general functions.d.ts +6 -1
  75. package/dist/esm/canvas/utils/General/general functions.d.ts.map +1 -1
  76. package/dist/esm/canvas/utils/General/general functions.js +19 -20
  77. package/dist/esm/canvas/utils/General/general functions.js.map +1 -1
  78. package/dist/esm/canvas/utils/Image/imageProperties.d.ts +3 -9
  79. package/dist/esm/canvas/utils/Image/imageProperties.d.ts.map +1 -1
  80. package/dist/esm/canvas/utils/Image/imageProperties.js +220 -214
  81. package/dist/esm/canvas/utils/Image/imageProperties.js.map +1 -1
  82. package/dist/esm/canvas/utils/Texts/textProperties.d.ts +12 -14
  83. package/dist/esm/canvas/utils/Texts/textProperties.d.ts.map +1 -1
  84. package/dist/esm/canvas/utils/Texts/textProperties.js +100 -91
  85. package/dist/esm/canvas/utils/Texts/textProperties.js.map +1 -1
  86. package/dist/esm/canvas/utils/types.d.ts +89 -109
  87. package/dist/esm/canvas/utils/types.d.ts.map +1 -1
  88. package/dist/esm/canvas/utils/types.js.map +1 -1
  89. package/dist/esm/canvas/utils/utils.d.ts +2 -4
  90. package/dist/esm/canvas/utils/utils.d.ts.map +1 -1
  91. package/dist/esm/canvas/utils/utils.js +2 -5
  92. package/dist/esm/canvas/utils/utils.js.map +1 -1
  93. package/dist/esm/index.d.ts.map +1 -1
  94. package/dist/esm/index.js +31 -3
  95. package/dist/esm/index.js.map +1 -1
  96. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  97. package/lib/ai/ApexModules.ts +83 -11
  98. package/lib/ai/functions/readFiles.ts +1 -1
  99. package/lib/ai/modals-chat/electronHub/chatmodels.ts +4 -2
  100. package/lib/ai/modals-chat/electronHub/speechModels.ts +2 -1
  101. package/lib/canvas/ApexPainter.ts +52 -61
  102. package/lib/canvas/Themes/Level-Up/levelup.ts +183 -0
  103. package/lib/canvas/utils/Background/bg.ts +179 -65
  104. package/lib/canvas/utils/Custom/customLines.ts +53 -20
  105. package/lib/canvas/utils/General/general functions.ts +21 -29
  106. package/lib/canvas/utils/Image/imageProperties.ts +399 -318
  107. package/lib/canvas/utils/Texts/textProperties.ts +213 -162
  108. package/lib/canvas/utils/types.ts +74 -107
  109. package/lib/canvas/utils/utils.ts +2 -5
  110. package/lib/index.ts +38 -10
  111. package/package.json +3 -2
  112. package/dist/cjs/canvas/utils/Background/circular.d.ts +0 -3
  113. package/dist/cjs/canvas/utils/Background/circular.d.ts.map +0 -1
  114. package/dist/cjs/canvas/utils/Background/circular.js +0 -13
  115. package/dist/cjs/canvas/utils/Background/circular.js.map +0 -1
  116. package/dist/cjs/canvas/utils/Background/radius.d.ts +0 -18
  117. package/dist/cjs/canvas/utils/Background/radius.d.ts.map +0 -1
  118. package/dist/cjs/canvas/utils/Background/radius.js +0 -104
  119. package/dist/cjs/canvas/utils/Background/radius.js.map +0 -1
  120. package/dist/esm/canvas/utils/Background/circular.d.ts +0 -3
  121. package/dist/esm/canvas/utils/Background/circular.d.ts.map +0 -1
  122. package/dist/esm/canvas/utils/Background/circular.js +0 -13
  123. package/dist/esm/canvas/utils/Background/circular.js.map +0 -1
  124. package/dist/esm/canvas/utils/Background/radius.d.ts +0 -18
  125. package/dist/esm/canvas/utils/Background/radius.d.ts.map +0 -1
  126. package/dist/esm/canvas/utils/Background/radius.js +0 -104
  127. package/dist/esm/canvas/utils/Background/radius.js.map +0 -1
  128. package/lib/canvas/utils/Background/circular.ts +0 -17
  129. package/lib/canvas/utils/Background/radius.ts +0 -102
@@ -1,180 +1,231 @@
1
- import { TextObject } from "../types";
1
+ import { SKRSContext2D } from '@napi-rs/canvas';
2
+ import { TextObject } from '../types';
2
3
 
3
4
  /**
4
- * Draws text on the canvas context.
5
- * @param ctx The canvas rendering context.
6
- * @param textOptions The options for the text.
5
+ * The main function that draws text with optional wrapping.
6
+ * @param ctx CanvasRenderingContext2D
7
+ * @param textOptions TextObject
7
8
  */
8
- export function drawText(ctx: any, textOptions: TextObject, size: any) {
9
- ctx.save();
10
-
11
- // Apply rotation if specified
12
- if (textOptions.rotation && textOptions.rotation !== 0) {
13
- ctx.translate(textOptions.x || 0, textOptions.y || 0);
14
- ctx.rotate(textOptions.rotation * Math.PI / 180);
15
- }
16
-
17
- ctx.font = `${textOptions.isBold ? 'bold ' : ''}${textOptions.fontSize || 16}px "${textOptions.fontName || 'Arial'}"`;
18
- ctx.textAlign = textOptions.textAlign || 'left';
19
- ctx.textBaseline = textOptions.textBaseline || 'alphabetic';
20
-
21
- // Apply shadow
22
- if (textOptions.shadow) {
23
- const { color, offsetX, offsetY, blur, opacity } = textOptions.shadow;
24
- ctx.shadowColor = color || "transparent";
25
- ctx.shadowOffsetX = offsetX || 0;
26
- ctx.shadowOffsetY = offsetY || 0;
27
- ctx.shadowBlur = blur || 0;
28
- ctx.globalAlpha = opacity || 1;
29
- }
30
-
31
- // Apply opacity
32
- if (textOptions.opacity !== undefined) {
33
- if (textOptions.opacity > 1 || textOptions.opacity < 0)
34
- throw new Error("Text opacity Error: the value can't be smaller than 0 or bigger than 1.");
35
- ctx.globalAlpha = textOptions.opacity;
36
- }
37
-
38
- const textWidth = ctx.measureText(textOptions.text).width;
39
- const textHeight = textOptions.fontSize || 16; // Rough estimate for height
40
-
41
- // Apply gradient fill
42
- if (textOptions.gradient) {
43
- const gradientFill = createGradient(
44
- ctx,
45
- textOptions.gradient,
46
- textOptions.x || 0,
47
- textOptions.y || 0 - textHeight,
48
- (textOptions.x || 0) + textWidth,
49
- (textOptions.y || 0)
50
- );
51
- console.log("Gradient Fill Created:", gradientFill);
52
- ctx.fillStyle = gradientFill;
53
- } else {
54
- ctx.fillStyle = textOptions.color || 'darkgray';
9
+ export function drawText(ctx: SKRSContext2D, textOptions: TextObject) {
10
+ ctx.save();
11
+
12
+ // 1) Apply rotation if any
13
+ if (textOptions.rotation && textOptions.rotation !== 0) {
14
+ ctx.translate(textOptions.x || 0, textOptions.y || 0);
15
+ ctx.rotate((textOptions.rotation * Math.PI) / 180);
16
+ }
17
+
18
+ // 2) Setup font (for measuring and for final draw)
19
+ const fontSize = textOptions.fontSize || 16;
20
+ const isBold = textOptions.isBold ? 'bold ' : '';
21
+ const fontFamily = textOptions.fontName || (textOptions.fontPath ? 'customFont' : 'Arial');
22
+ ctx.font = `${isBold}${fontSize}px "${fontFamily}"`;
23
+
24
+ // 3) Alignment, baseline
25
+ ctx.textAlign = textOptions.textAlign || 'left';
26
+ ctx.textBaseline = textOptions.textBaseline || 'alphabetic';
27
+
28
+ // 4) Shadow
29
+ if (textOptions.shadow) {
30
+ const { color, offsetX, offsetY, blur, opacity } = textOptions.shadow;
31
+ ctx.shadowColor = color || 'transparent';
32
+ ctx.shadowOffsetX = offsetX || 0;
33
+ ctx.shadowOffsetY = offsetY || 0;
34
+ ctx.shadowBlur = blur || 0;
35
+ ctx.globalAlpha = opacity !== undefined ? opacity : 1;
36
+ }
37
+
38
+ // 5) Opacity
39
+ if (textOptions.opacity !== undefined) {
40
+ if (textOptions.opacity < 0 || textOptions.opacity > 1) {
41
+ throw new Error('Text opacity must be between 0 and 1.');
55
42
  }
43
+ ctx.globalAlpha = textOptions.opacity;
44
+ }
45
+
46
+ // 6) If maxWidth is provided, we do word wrapping
47
+ if (textOptions.maxWidth) {
48
+ WrappedText(
49
+ ctx,
50
+ textOptions.text as string,
51
+ textOptions.x || 0,
52
+ textOptions.y || 0,
53
+ textOptions.maxWidth,
54
+ textOptions
55
+ );
56
+ } else {
57
+ // No wrapping needed → just draw stroke + fill
58
+ drawStrokeAndFill(ctx, textOptions.text as string, textOptions.x || 0, textOptions.y || 0, textOptions);
59
+ }
60
+
61
+ ctx.restore();
62
+ }
56
63
 
57
- // Apply stroke with gradient
58
- if (textOptions.outlined || textOptions.stroke) {
59
- if (textOptions.stroke?.gradient) {
60
- const gradientStroke = createGradient(
61
- ctx,
62
- textOptions.stroke.gradient,
63
- textOptions.x || 0,
64
- textOptions.y || 0 - textHeight,
65
- (textOptions.x || 0) + textWidth,
66
- (textOptions.y || 0)
67
- );
68
- console.log("Gradient Stroke Created:", gradientStroke);
69
- ctx.strokeStyle = gradientStroke;
70
- } else {
71
- ctx.strokeStyle = textOptions.stroke?.color || textOptions.color;
64
+ /**
65
+ * Handles word-based wrapping. Then draws each line with stroke, fill, gradient, etc.
66
+ */
67
+ export function WrappedText(
68
+ ctx: SKRSContext2D,
69
+ text: string,
70
+ startX: number,
71
+ startY: number,
72
+ maxWidth: number,
73
+ options: TextObject
74
+ ) {
75
+ const fontSize = options.fontSize || 16;
76
+ const lineHeight = options.lineHeight || fontSize * 1.4;
77
+ const maxHeight = options.maxHeight;
78
+ const maxLines = maxHeight ? Math.floor(maxHeight / lineHeight) : Infinity;
79
+
80
+ let currentLine = "";
81
+ const words = text.split(" ");
82
+ const lines: string[] = [];
83
+
84
+ for (let i = 0; i < words.length; i++) {
85
+ const testLine = currentLine ? currentLine + " " + words[i] : words[i];
86
+ const testWidth = ctx.measureText(testLine).width;
87
+
88
+ if (testWidth > maxWidth && currentLine) {
89
+ lines.push(currentLine);
90
+ currentLine = words[i];
91
+
92
+ if (lines.length >= maxLines) {
93
+ currentLine = "...";
94
+ break;
72
95
  }
73
- ctx.lineWidth = textOptions.stroke?.width || 1;
74
- ctx.strokeText(textOptions.text, textOptions.x || 0, textOptions.y || 0);
96
+ } else {
97
+ currentLine = testLine;
98
+ }
75
99
  }
76
-
77
- // Draw the text
78
- if (textOptions.maxWidth) {
79
- WrappedText(ctx, textOptions.text || 'Hello World', textOptions.x || 0, textOptions.y || 0, textOptions.maxWidth, textOptions);
80
- } else {
81
- if (!textOptions.rotation) {
82
- ctx.fillText(textOptions.text, textOptions.x || 0, textOptions.y || 0);
83
- } else {
84
- ctx.fillText(textOptions.text, 0, 0);
85
- }
100
+
101
+ if (currentLine && lines.length < maxLines) {
102
+ lines.push(currentLine);
86
103
  }
87
-
88
- ctx.restore();
89
- }
104
+
105
+ // 🔥 Ensure correct text alignment for Arabic & English
106
+ ctx.textAlign = options.textAlign || "left";
107
+
108
+ // 🎯 Draw each line with stroke & fill together
109
+ let offsetY = 0;
110
+ for (const line of lines) {
111
+ drawStrokeAndFill(ctx, line, startX, startY + offsetY, options);
112
+ offsetY += lineHeight;
113
+ }
114
+ }
115
+
90
116
  /**
91
- * Draws wrapped text on the canvas context.
92
- * @param ctx The canvas rendering context.
93
- * @param text The text to be drawn.
94
- * @param x The x-coordinate of the starting point of the text.
95
- * @param y The y-coordinate of the starting point of the text.
96
- * @param maxWidth The maximum width for wrapping the text.
97
- * @param textOptions The options for the text.
117
+ * Draws a single line with correct alignment. Then uses `drawStrokeAndFill` to apply stroke, fill, etc.
98
118
  */
99
- export function WrappedText(ctx: any, text: string, x: number, y: number, maxWidth: number, textOptions: TextObject) {
100
- const words = text.split(' ');
101
- let currentLine = '';
102
- const fontSize = textOptions.fontSize || 16;
103
- const lineHeight = textOptions.lineHeight || fontSize;
119
+ function drawLine(
120
+ ctx: SKRSContext2D,
121
+ lineText: string,
122
+ startX: number,
123
+ startY: number,
124
+ maxWidth: number,
125
+ options: TextObject
126
+ ) {
127
+ let xOffset = startX;
128
+
129
+ // If user wants 'center' or 'right', we offset by measured width
130
+ const measuredWidth = ctx.measureText(lineText).width;
131
+ if (options.textAlign === 'center') {
132
+ xOffset = startX + (maxWidth / 2) - (measuredWidth / 2);
133
+ } else if (options.textAlign === 'right') {
134
+ xOffset = startX + maxWidth - measuredWidth;
135
+ }
136
+
137
+ // Finally, draw stroke+fill for this line
138
+ drawStrokeAndFill(ctx, lineText, xOffset, startY, options);
139
+ }
104
140
 
141
+ /**
142
+ * Actually draws stroke (if any) and fill for the given text & position.
143
+ */
144
+ function drawStrokeAndFill(
145
+ ctx: SKRSContext2D,
146
+ text: string,
147
+ x: number,
148
+ y: number,
149
+ options: TextObject
150
+ ) {
151
+ const fontSize = options.fontSize || 16;
152
+ const textWidth = ctx.measureText(text).width;
153
+ const textHeight = fontSize;
154
+
155
+ // Apply gradient fill if needed
156
+ if (options.gradient) {
157
+ const gradientFill = createGradient(
158
+ ctx,
159
+ options.gradient,
160
+ x,
161
+ y - textHeight,
162
+ x + textWidth,
163
+ y
164
+ );
165
+ ctx.fillStyle = gradientFill;
166
+ } else {
167
+ ctx.fillStyle = options.color || 'darkgray';
168
+ }
169
+
170
+ // Draw stroke first (if exists)
171
+ if (options.stroke) {
105
172
  ctx.save();
106
-
107
- ctx.fillStyle = textOptions.color || 'darkgray';
108
- if (textOptions.outlined || textOptions.stroke) {
109
- ctx.strokeStyle = textOptions.stroke?.color || textOptions.color;
110
- ctx.lineWidth = textOptions.stroke?.width || 1;
111
- }
112
-
113
- if (textOptions.rotation && textOptions.rotation !== 0) {
114
- ctx.translate(x, y);
115
- ctx.rotate(textOptions.rotation * Math.PI / 180);
116
- x = 0;
117
- y = 0;
118
- }
119
-
120
- for (let n = 0; n < words.length; n++) {
121
- const testLine = currentLine + words[n] + ' ';
122
- const metrics = ctx.measureText(testLine);
123
- const testWidth = metrics.width;
124
-
125
- if (testWidth > maxWidth && n > 0) {
126
- const adjustedY = y + lineHeight;
127
- if (textOptions.outlined || textOptions.stroke) {
128
- ctx.strokeText(currentLine.trim(), x, adjustedY);
129
- } else {
130
- ctx.fillText(currentLine.trim(), x, adjustedY);
131
- }
132
- currentLine = words[n] + ' ';
133
- y += lineHeight;
134
- } else {
135
- currentLine = testLine;
136
- }
137
- }
138
-
139
- const adjustedY = y + lineHeight;
140
- if (textOptions.outlined || textOptions.stroke) {
141
- ctx.strokeText(currentLine.trim(), x, adjustedY);
173
+ ctx.lineWidth = options.stroke.width || 1;
174
+ if (options.stroke.gradient) {
175
+ const gradientStroke = createGradient(
176
+ ctx,
177
+ options.stroke.gradient,
178
+ x,
179
+ y - textHeight,
180
+ x + textWidth,
181
+ y
182
+ );
183
+ ctx.strokeStyle = gradientStroke;
142
184
  } else {
143
- ctx.fillText(currentLine.trim(), x, adjustedY);
185
+ ctx.strokeStyle = options.stroke.color || options.color || 'darkgray';
144
186
  }
145
-
187
+ ctx.strokeText(text, x, y);
146
188
  ctx.restore();
147
- }
189
+ }
148
190
 
149
- export function createGradient(ctx: any, gradientOptions: any, startX: number, startY: number, endX: number, endY: number) {
150
- if (!gradientOptions || !gradientOptions.type || !gradientOptions.colors) {
151
- throw new Error("Invalid gradient options. Provide a valid object with type and colors properties.");
152
- }
153
-
154
- if (!Array.isArray(gradientOptions.colors)) {
155
- throw new Error("Invalid gradient options. The colors property should be an array of color stops.");
156
- }
157
-
158
- let gradient;
159
- if (gradientOptions.type === "linear") {
160
- gradient = ctx.createLinearGradient(startX, startY, endX, endY);
161
- } else if (gradientOptions.type === "radial") {
162
- gradient = ctx.createRadialGradient(
163
- gradientOptions.startX || startX,
164
- gradientOptions.startY || startY,
165
- gradientOptions.startRadius || 0,
166
- gradientOptions.endX || endX,
167
- gradientOptions.endY || endY,
168
- gradientOptions.endRadius || 0
169
- );
170
- } else {
171
- throw new Error('Unsupported gradient type. Use "linear" or "radial".');
172
- }
173
-
174
- for (const colorStop of gradientOptions.colors) {
175
- console.log(`Adding color stop: ${colorStop.stop} ${colorStop.color}`);
176
- gradient.addColorStop(colorStop.stop, colorStop.color);
177
- }
191
+ // Then fill
192
+ ctx.fillText(text, x, y);
193
+ }
178
194
 
179
- return gradient;
195
+ /**
196
+ * Creates a linear or radial gradient for fill/stroke.
197
+ */
198
+ export function createGradient(
199
+ ctx: SKRSContext2D,
200
+ gradientOptions: any,
201
+ startX: number,
202
+ startY: number,
203
+ endX: number,
204
+ endY: number
205
+ ) {
206
+ if (!gradientOptions || !gradientOptions.type || !gradientOptions.colors) {
207
+ throw new Error("Invalid gradient options. Provide a valid object with type and colors properties.");
208
+ }
209
+
210
+ let gradient: CanvasGradient;
211
+ if (gradientOptions.type === "linear") {
212
+ gradient = ctx.createLinearGradient(startX, startY, endX, endY);
213
+ } else if (gradientOptions.type === "radial") {
214
+ gradient = ctx.createRadialGradient(
215
+ gradientOptions.startX || startX,
216
+ gradientOptions.startY || startY,
217
+ gradientOptions.startRadius || 0,
218
+ gradientOptions.endX || endX,
219
+ gradientOptions.endY || endY,
220
+ gradientOptions.endRadius || 0
221
+ );
222
+ } else {
223
+ throw new Error('Unsupported gradient type. Use "linear" or "radial".');
224
+ }
225
+
226
+ for (const colorStop of gradientOptions.colors) {
227
+ gradient.addColorStop(colorStop.stop, colorStop.color);
228
+ }
229
+
230
+ return gradient;
180
231
  }