apexify.js 5.1.1 → 5.2.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/CHANGELOG.md +240 -0
- package/README.md +248 -1105
- package/dist/cjs/Canvas/ApexPainter.d.ts +182 -204
- package/dist/cjs/Canvas/ApexPainter.d.ts.map +1 -1
- package/dist/cjs/Canvas/ApexPainter.js +482 -1286
- package/dist/cjs/Canvas/ApexPainter.js.map +1 -1
- package/dist/cjs/Canvas/extended/CanvasCreator.d.ts +33 -0
- package/dist/cjs/Canvas/extended/CanvasCreator.d.ts.map +1 -0
- package/dist/cjs/Canvas/extended/CanvasCreator.js +223 -0
- package/dist/cjs/Canvas/extended/CanvasCreator.js.map +1 -0
- package/dist/cjs/Canvas/extended/ChartCreator.d.ts +26 -0
- package/dist/cjs/Canvas/extended/ChartCreator.d.ts.map +1 -0
- package/dist/cjs/Canvas/extended/ChartCreator.js +50 -0
- package/dist/cjs/Canvas/extended/ChartCreator.js.map +1 -0
- package/dist/cjs/Canvas/extended/GIFCreator.d.ts +43 -0
- package/dist/cjs/Canvas/extended/GIFCreator.d.ts.map +1 -0
- package/dist/cjs/Canvas/extended/GIFCreator.js +157 -0
- package/dist/cjs/Canvas/extended/GIFCreator.js.map +1 -0
- package/dist/cjs/Canvas/extended/ImageCreator.d.ts +83 -0
- package/dist/cjs/Canvas/extended/ImageCreator.d.ts.map +1 -0
- package/dist/cjs/Canvas/extended/ImageCreator.js +479 -0
- package/dist/cjs/Canvas/extended/ImageCreator.js.map +1 -0
- package/dist/cjs/Canvas/extended/TextCreator.d.ts +35 -0
- package/dist/cjs/Canvas/extended/TextCreator.d.ts.map +1 -0
- package/dist/cjs/Canvas/extended/TextCreator.js +98 -0
- package/dist/cjs/Canvas/extended/TextCreator.js.map +1 -0
- package/dist/cjs/Canvas/extended/VideoCreator.d.ts +370 -0
- package/dist/cjs/Canvas/extended/VideoCreator.d.ts.map +1 -0
- package/dist/cjs/Canvas/extended/VideoCreator.js +478 -0
- package/dist/cjs/Canvas/extended/VideoCreator.js.map +1 -0
- package/dist/cjs/Canvas/utils/Background/bg.d.ts +1 -1
- package/dist/cjs/Canvas/utils/Background/bg.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/Background/bg.js +43 -7
- package/dist/cjs/Canvas/utils/Background/bg.js.map +1 -1
- package/dist/cjs/Canvas/utils/Charts/barchart.d.ts +230 -0
- package/dist/cjs/Canvas/utils/Charts/barchart.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/barchart.js +1891 -0
- package/dist/cjs/Canvas/utils/Charts/barchart.js.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/comparisonchart.d.ts +103 -0
- package/dist/cjs/Canvas/utils/Charts/comparisonchart.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/comparisonchart.js +368 -0
- package/dist/cjs/Canvas/utils/Charts/comparisonchart.js.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/horizontalbarchart.d.ts +178 -0
- package/dist/cjs/Canvas/utils/Charts/horizontalbarchart.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/horizontalbarchart.js +1389 -0
- package/dist/cjs/Canvas/utils/Charts/horizontalbarchart.js.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/index.d.ts +45 -0
- package/dist/cjs/Canvas/utils/Charts/index.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/index.js +17 -0
- package/dist/cjs/Canvas/utils/Charts/index.js.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/linechart.d.ts +216 -0
- package/dist/cjs/Canvas/utils/Charts/linechart.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/linechart.js +1761 -0
- package/dist/cjs/Canvas/utils/Charts/linechart.js.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/piechart.d.ts +167 -0
- package/dist/cjs/Canvas/utils/Charts/piechart.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Charts/piechart.js +794 -0
- package/dist/cjs/Canvas/utils/Charts/piechart.js.map +1 -0
- package/dist/cjs/Canvas/utils/General/batchOperations.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/General/batchOperations.js +3 -4
- package/dist/cjs/Canvas/utils/General/batchOperations.js.map +1 -1
- package/dist/cjs/Canvas/utils/General/general functions.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/General/general functions.js +62 -33
- package/dist/cjs/Canvas/utils/General/general functions.js.map +1 -1
- package/dist/cjs/Canvas/utils/General/imageStitching.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/General/imageStitching.js +3 -6
- package/dist/cjs/Canvas/utils/General/imageStitching.js.map +1 -1
- package/dist/cjs/Canvas/utils/Image/imageMasking.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/Image/imageMasking.js +5 -12
- package/dist/cjs/Canvas/utils/Image/imageMasking.js.map +1 -1
- package/dist/cjs/Canvas/utils/Image/imageProperties.d.ts +4 -4
- package/dist/cjs/Canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/Image/imageProperties.js +44 -9
- package/dist/cjs/Canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.d.ts +5 -0
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.js +48 -5
- package/dist/cjs/Canvas/utils/Texts/enhancedTextRenderer.js.map +1 -1
- package/dist/cjs/Canvas/utils/Texts/textProperties.d.ts +1 -1
- package/dist/cjs/Canvas/utils/Texts/textProperties.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/Texts/textProperties.js +48 -5
- package/dist/cjs/Canvas/utils/Texts/textProperties.js.map +1 -1
- package/dist/cjs/Canvas/utils/Video/videoHelpers.d.ts +489 -0
- package/dist/cjs/Canvas/utils/Video/videoHelpers.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/Video/videoHelpers.js +1835 -0
- package/dist/cjs/Canvas/utils/Video/videoHelpers.js.map +1 -0
- package/dist/cjs/Canvas/utils/errorUtils.d.ts +15 -0
- package/dist/cjs/Canvas/utils/errorUtils.d.ts.map +1 -0
- package/dist/cjs/Canvas/utils/errorUtils.js +26 -0
- package/dist/cjs/Canvas/utils/errorUtils.js.map +1 -0
- package/dist/cjs/Canvas/utils/types.d.ts +17 -178
- 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 +4 -3
- package/dist/cjs/Canvas/utils/utils.d.ts.map +1 -1
- package/dist/cjs/Canvas/utils/utils.js +40 -6
- package/dist/cjs/Canvas/utils/utils.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -8
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +14 -45
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/Canvas/ApexPainter.d.ts +182 -204
- package/dist/esm/Canvas/ApexPainter.d.ts.map +1 -1
- package/dist/esm/Canvas/ApexPainter.js +482 -1286
- package/dist/esm/Canvas/ApexPainter.js.map +1 -1
- package/dist/esm/Canvas/extended/CanvasCreator.d.ts +33 -0
- package/dist/esm/Canvas/extended/CanvasCreator.d.ts.map +1 -0
- package/dist/esm/Canvas/extended/CanvasCreator.js +223 -0
- package/dist/esm/Canvas/extended/CanvasCreator.js.map +1 -0
- package/dist/esm/Canvas/extended/ChartCreator.d.ts +26 -0
- package/dist/esm/Canvas/extended/ChartCreator.d.ts.map +1 -0
- package/dist/esm/Canvas/extended/ChartCreator.js +50 -0
- package/dist/esm/Canvas/extended/ChartCreator.js.map +1 -0
- package/dist/esm/Canvas/extended/GIFCreator.d.ts +43 -0
- package/dist/esm/Canvas/extended/GIFCreator.d.ts.map +1 -0
- package/dist/esm/Canvas/extended/GIFCreator.js +157 -0
- package/dist/esm/Canvas/extended/GIFCreator.js.map +1 -0
- package/dist/esm/Canvas/extended/ImageCreator.d.ts +83 -0
- package/dist/esm/Canvas/extended/ImageCreator.d.ts.map +1 -0
- package/dist/esm/Canvas/extended/ImageCreator.js +479 -0
- package/dist/esm/Canvas/extended/ImageCreator.js.map +1 -0
- package/dist/esm/Canvas/extended/TextCreator.d.ts +35 -0
- package/dist/esm/Canvas/extended/TextCreator.d.ts.map +1 -0
- package/dist/esm/Canvas/extended/TextCreator.js +98 -0
- package/dist/esm/Canvas/extended/TextCreator.js.map +1 -0
- package/dist/esm/Canvas/extended/VideoCreator.d.ts +370 -0
- package/dist/esm/Canvas/extended/VideoCreator.d.ts.map +1 -0
- package/dist/esm/Canvas/extended/VideoCreator.js +478 -0
- package/dist/esm/Canvas/extended/VideoCreator.js.map +1 -0
- package/dist/esm/Canvas/utils/Background/bg.d.ts +1 -1
- package/dist/esm/Canvas/utils/Background/bg.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/Background/bg.js +43 -7
- package/dist/esm/Canvas/utils/Background/bg.js.map +1 -1
- package/dist/esm/Canvas/utils/Charts/barchart.d.ts +230 -0
- package/dist/esm/Canvas/utils/Charts/barchart.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Charts/barchart.js +1891 -0
- package/dist/esm/Canvas/utils/Charts/barchart.js.map +1 -0
- package/dist/esm/Canvas/utils/Charts/comparisonchart.d.ts +103 -0
- package/dist/esm/Canvas/utils/Charts/comparisonchart.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Charts/comparisonchart.js +368 -0
- package/dist/esm/Canvas/utils/Charts/comparisonchart.js.map +1 -0
- package/dist/esm/Canvas/utils/Charts/horizontalbarchart.d.ts +178 -0
- package/dist/esm/Canvas/utils/Charts/horizontalbarchart.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Charts/horizontalbarchart.js +1389 -0
- package/dist/esm/Canvas/utils/Charts/horizontalbarchart.js.map +1 -0
- package/dist/esm/Canvas/utils/Charts/index.d.ts +45 -0
- package/dist/esm/Canvas/utils/Charts/index.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Charts/index.js +17 -0
- package/dist/esm/Canvas/utils/Charts/index.js.map +1 -0
- package/dist/esm/Canvas/utils/Charts/linechart.d.ts +216 -0
- package/dist/esm/Canvas/utils/Charts/linechart.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Charts/linechart.js +1761 -0
- package/dist/esm/Canvas/utils/Charts/linechart.js.map +1 -0
- package/dist/esm/Canvas/utils/Charts/piechart.d.ts +167 -0
- package/dist/esm/Canvas/utils/Charts/piechart.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Charts/piechart.js +794 -0
- package/dist/esm/Canvas/utils/Charts/piechart.js.map +1 -0
- package/dist/esm/Canvas/utils/General/batchOperations.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/General/batchOperations.js +3 -4
- package/dist/esm/Canvas/utils/General/batchOperations.js.map +1 -1
- package/dist/esm/Canvas/utils/General/general functions.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/General/general functions.js +62 -33
- package/dist/esm/Canvas/utils/General/general functions.js.map +1 -1
- package/dist/esm/Canvas/utils/General/imageStitching.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/General/imageStitching.js +3 -6
- package/dist/esm/Canvas/utils/General/imageStitching.js.map +1 -1
- package/dist/esm/Canvas/utils/Image/imageMasking.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/Image/imageMasking.js +5 -12
- package/dist/esm/Canvas/utils/Image/imageMasking.js.map +1 -1
- package/dist/esm/Canvas/utils/Image/imageProperties.d.ts +4 -4
- package/dist/esm/Canvas/utils/Image/imageProperties.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/Image/imageProperties.js +44 -9
- package/dist/esm/Canvas/utils/Image/imageProperties.js.map +1 -1
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.d.ts +5 -0
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.js +48 -5
- package/dist/esm/Canvas/utils/Texts/enhancedTextRenderer.js.map +1 -1
- package/dist/esm/Canvas/utils/Texts/textProperties.d.ts +1 -1
- package/dist/esm/Canvas/utils/Texts/textProperties.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/Texts/textProperties.js +48 -5
- package/dist/esm/Canvas/utils/Texts/textProperties.js.map +1 -1
- package/dist/esm/Canvas/utils/Video/videoHelpers.d.ts +489 -0
- package/dist/esm/Canvas/utils/Video/videoHelpers.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/Video/videoHelpers.js +1835 -0
- package/dist/esm/Canvas/utils/Video/videoHelpers.js.map +1 -0
- package/dist/esm/Canvas/utils/errorUtils.d.ts +15 -0
- package/dist/esm/Canvas/utils/errorUtils.d.ts.map +1 -0
- package/dist/esm/Canvas/utils/errorUtils.js +26 -0
- package/dist/esm/Canvas/utils/errorUtils.js.map +1 -0
- package/dist/esm/Canvas/utils/types.d.ts +17 -178
- 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 +4 -3
- package/dist/esm/Canvas/utils/utils.d.ts.map +1 -1
- package/dist/esm/Canvas/utils/utils.js +40 -6
- package/dist/esm/Canvas/utils/utils.js.map +1 -1
- package/dist/esm/index.d.ts +1 -8
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -45
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +234 -198
- package/dist/cjs/Canvas/utils/Charts/charts.d.ts +0 -13
- package/dist/cjs/Canvas/utils/Charts/charts.d.ts.map +0 -1
- package/dist/cjs/Canvas/utils/Charts/charts.js +0 -466
- package/dist/cjs/Canvas/utils/Charts/charts.js.map +0 -1
- package/dist/esm/Canvas/utils/Charts/charts.d.ts +0 -13
- package/dist/esm/Canvas/utils/Charts/charts.d.ts.map +0 -1
- package/dist/esm/Canvas/utils/Charts/charts.js +0 -466
- package/dist/esm/Canvas/utils/Charts/charts.js.map +0 -1
- package/lib/Canvas/ApexPainter.ts +0 -5414
- package/lib/Canvas/utils/Background/bg.ts +0 -285
- package/lib/Canvas/utils/Charts/charts.ts +0 -548
- package/lib/Canvas/utils/Custom/advancedLines.ts +0 -387
- package/lib/Canvas/utils/Custom/customLines.ts +0 -206
- package/lib/Canvas/utils/General/batchOperations.ts +0 -103
- package/lib/Canvas/utils/General/conversion.ts +0 -34
- package/lib/Canvas/utils/General/general functions.ts +0 -726
- package/lib/Canvas/utils/General/imageCompression.ts +0 -316
- package/lib/Canvas/utils/General/imageStitching.ts +0 -252
- package/lib/Canvas/utils/Image/imageEffects.ts +0 -175
- package/lib/Canvas/utils/Image/imageFilters.ts +0 -356
- package/lib/Canvas/utils/Image/imageMasking.ts +0 -335
- package/lib/Canvas/utils/Image/imageProperties.ts +0 -587
- package/lib/Canvas/utils/Image/professionalImageFilters.ts +0 -391
- package/lib/Canvas/utils/Image/simpleProfessionalFilters.ts +0 -229
- package/lib/Canvas/utils/Patterns/enhancedPatternRenderer.ts +0 -455
- package/lib/Canvas/utils/Shapes/shapes.ts +0 -528
- package/lib/Canvas/utils/Texts/enhancedTextRenderer.ts +0 -716
- package/lib/Canvas/utils/Texts/textPathRenderer.ts +0 -320
- package/lib/Canvas/utils/Texts/textProperties.ts +0 -231
- package/lib/Canvas/utils/types.ts +0 -983
- package/lib/Canvas/utils/utils.ts +0 -135
- package/lib/index.ts +0 -81
- package/lib/utils.ts +0 -5
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
import { SKRSContext2D } from '@napi-rs/canvas';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Renders text along a path
|
|
5
|
-
* @param ctx - Canvas 2D context
|
|
6
|
-
* @param text - Text to render
|
|
7
|
-
* @param pathConfig - Path configuration
|
|
8
|
-
* @param offset - Distance from path
|
|
9
|
-
*/
|
|
10
|
-
export function renderTextOnPath(
|
|
11
|
-
ctx: SKRSContext2D,
|
|
12
|
-
text: string,
|
|
13
|
-
pathConfig: {
|
|
14
|
-
type: 'line' | 'arc' | 'bezier' | 'quadratic';
|
|
15
|
-
points: Array<{ x: number; y: number }>;
|
|
16
|
-
offset?: number;
|
|
17
|
-
},
|
|
18
|
-
offset: number = 0
|
|
19
|
-
): void {
|
|
20
|
-
const path = createPath(ctx, pathConfig);
|
|
21
|
-
const pathLength = getPathLength(path, pathConfig);
|
|
22
|
-
|
|
23
|
-
ctx.save();
|
|
24
|
-
|
|
25
|
-
// Measure text to distribute along path
|
|
26
|
-
const metrics = ctx.measureText(text);
|
|
27
|
-
const textWidth = metrics.width;
|
|
28
|
-
const charWidth = textWidth / text.length;
|
|
29
|
-
|
|
30
|
-
let currentDistance = 0;
|
|
31
|
-
|
|
32
|
-
for (let i = 0; i < text.length; i++) {
|
|
33
|
-
const char = text[i];
|
|
34
|
-
const charDistance = currentDistance + charWidth / 2;
|
|
35
|
-
|
|
36
|
-
if (charDistance <= pathLength) {
|
|
37
|
-
const point = getPointOnPath(path, pathConfig, charDistance);
|
|
38
|
-
const angle = getAngleOnPath(path, pathConfig, charDistance);
|
|
39
|
-
|
|
40
|
-
ctx.save();
|
|
41
|
-
ctx.translate(point.x, point.y);
|
|
42
|
-
ctx.rotate(angle);
|
|
43
|
-
ctx.fillText(char, 0, offset);
|
|
44
|
-
ctx.restore();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
currentDistance += charWidth;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
ctx.restore();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Creates a path based on configuration
|
|
55
|
-
*/
|
|
56
|
-
function createPath(
|
|
57
|
-
ctx: SKRSContext2D,
|
|
58
|
-
pathConfig: {
|
|
59
|
-
type: 'line' | 'arc' | 'bezier' | 'quadratic';
|
|
60
|
-
points: Array<{ x: number; y: number }>;
|
|
61
|
-
}
|
|
62
|
-
): Path2D {
|
|
63
|
-
const path = new Path2D();
|
|
64
|
-
|
|
65
|
-
switch (pathConfig.type) {
|
|
66
|
-
case 'line':
|
|
67
|
-
if (pathConfig.points.length >= 2) {
|
|
68
|
-
path.moveTo(pathConfig.points[0].x, pathConfig.points[0].y);
|
|
69
|
-
for (let i = 1; i < pathConfig.points.length; i++) {
|
|
70
|
-
path.lineTo(pathConfig.points[i].x, pathConfig.points[i].y);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
break;
|
|
74
|
-
|
|
75
|
-
case 'arc':
|
|
76
|
-
if (pathConfig.points.length >= 3) {
|
|
77
|
-
const center = pathConfig.points[0];
|
|
78
|
-
const start = pathConfig.points[1];
|
|
79
|
-
const end = pathConfig.points[2];
|
|
80
|
-
const radius = Math.sqrt(
|
|
81
|
-
Math.pow(start.x - center.x, 2) + Math.pow(start.y - center.y, 2)
|
|
82
|
-
);
|
|
83
|
-
const startAngle = Math.atan2(start.y - center.y, start.x - center.x);
|
|
84
|
-
const endAngle = Math.atan2(end.y - center.y, end.x - center.x);
|
|
85
|
-
path.arc(center.x, center.y, radius, startAngle, endAngle);
|
|
86
|
-
}
|
|
87
|
-
break;
|
|
88
|
-
|
|
89
|
-
case 'bezier':
|
|
90
|
-
if (pathConfig.points.length >= 4) {
|
|
91
|
-
path.moveTo(pathConfig.points[0].x, pathConfig.points[0].y);
|
|
92
|
-
for (let i = 1; i < pathConfig.points.length - 2; i += 3) {
|
|
93
|
-
if (i + 2 < pathConfig.points.length) {
|
|
94
|
-
path.bezierCurveTo(
|
|
95
|
-
pathConfig.points[i].x, pathConfig.points[i].y,
|
|
96
|
-
pathConfig.points[i + 1].x, pathConfig.points[i + 1].y,
|
|
97
|
-
pathConfig.points[i + 2].x, pathConfig.points[i + 2].y
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
break;
|
|
103
|
-
|
|
104
|
-
case 'quadratic':
|
|
105
|
-
if (pathConfig.points.length >= 3) {
|
|
106
|
-
path.moveTo(pathConfig.points[0].x, pathConfig.points[0].y);
|
|
107
|
-
for (let i = 1; i < pathConfig.points.length - 1; i += 2) {
|
|
108
|
-
if (i + 1 < pathConfig.points.length) {
|
|
109
|
-
path.quadraticCurveTo(
|
|
110
|
-
pathConfig.points[i].x, pathConfig.points[i].y,
|
|
111
|
-
pathConfig.points[i + 1].x, pathConfig.points[i + 1].y
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return path;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Gets approximate path length
|
|
124
|
-
*/
|
|
125
|
-
function getPathLength(
|
|
126
|
-
path: Path2D,
|
|
127
|
-
pathConfig: {
|
|
128
|
-
type: 'line' | 'arc' | 'bezier' | 'quadratic';
|
|
129
|
-
points: Array<{ x: number; y: number }>;
|
|
130
|
-
}
|
|
131
|
-
): number {
|
|
132
|
-
let length = 0;
|
|
133
|
-
|
|
134
|
-
switch (pathConfig.type) {
|
|
135
|
-
case 'line':
|
|
136
|
-
for (let i = 0; i < pathConfig.points.length - 1; i++) {
|
|
137
|
-
const dx = pathConfig.points[i + 1].x - pathConfig.points[i].x;
|
|
138
|
-
const dy = pathConfig.points[i + 1].y - pathConfig.points[i].y;
|
|
139
|
-
length += Math.sqrt(dx * dx + dy * dy);
|
|
140
|
-
}
|
|
141
|
-
break;
|
|
142
|
-
|
|
143
|
-
case 'arc':
|
|
144
|
-
if (pathConfig.points.length >= 3) {
|
|
145
|
-
const center = pathConfig.points[0];
|
|
146
|
-
const start = pathConfig.points[1];
|
|
147
|
-
const end = pathConfig.points[2];
|
|
148
|
-
const radius = Math.sqrt(
|
|
149
|
-
Math.pow(start.x - center.x, 2) + Math.pow(start.y - center.y, 2)
|
|
150
|
-
);
|
|
151
|
-
const startAngle = Math.atan2(start.y - center.y, start.x - center.x);
|
|
152
|
-
const endAngle = Math.atan2(end.y - center.y, end.x - center.x);
|
|
153
|
-
let angle = endAngle - startAngle;
|
|
154
|
-
if (angle < 0) angle += Math.PI * 2;
|
|
155
|
-
length = radius * angle;
|
|
156
|
-
}
|
|
157
|
-
break;
|
|
158
|
-
|
|
159
|
-
case 'bezier':
|
|
160
|
-
case 'quadratic':
|
|
161
|
-
// Approximate by sampling points along the curve
|
|
162
|
-
const samples = 100;
|
|
163
|
-
let prevPoint = pathConfig.points[0];
|
|
164
|
-
for (let i = 1; i <= samples; i++) {
|
|
165
|
-
const t = i / samples;
|
|
166
|
-
const point = getPointOnPath(path, pathConfig, t * 1000); // Approximate
|
|
167
|
-
const dx = point.x - prevPoint.x;
|
|
168
|
-
const dy = point.y - prevPoint.y;
|
|
169
|
-
length += Math.sqrt(dx * dx + dy * dy);
|
|
170
|
-
prevPoint = point;
|
|
171
|
-
}
|
|
172
|
-
break;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return length;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Gets a point on the path at a given distance
|
|
180
|
-
*/
|
|
181
|
-
function getPointOnPath(
|
|
182
|
-
path: Path2D,
|
|
183
|
-
pathConfig: {
|
|
184
|
-
type: 'line' | 'arc' | 'bezier' | 'quadratic';
|
|
185
|
-
points: Array<{ x: number; y: number }>;
|
|
186
|
-
},
|
|
187
|
-
distance: number
|
|
188
|
-
): { x: number; y: number } {
|
|
189
|
-
const pathLength = getPathLength(path, pathConfig);
|
|
190
|
-
const t = Math.min(1, distance / pathLength);
|
|
191
|
-
|
|
192
|
-
switch (pathConfig.type) {
|
|
193
|
-
case 'line':
|
|
194
|
-
return getPointOnLine(pathConfig.points, t);
|
|
195
|
-
|
|
196
|
-
case 'arc':
|
|
197
|
-
return getPointOnArc(pathConfig.points, t);
|
|
198
|
-
|
|
199
|
-
case 'bezier':
|
|
200
|
-
return getPointOnBezier(pathConfig.points, t);
|
|
201
|
-
|
|
202
|
-
case 'quadratic':
|
|
203
|
-
return getPointOnQuadratic(pathConfig.points, t);
|
|
204
|
-
|
|
205
|
-
default:
|
|
206
|
-
return { x: 0, y: 0 };
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Gets angle on path at a given distance
|
|
212
|
-
*/
|
|
213
|
-
function getAngleOnPath(
|
|
214
|
-
path: Path2D,
|
|
215
|
-
pathConfig: {
|
|
216
|
-
type: 'line' | 'arc' | 'bezier' | 'quadratic';
|
|
217
|
-
points: Array<{ x: number; y: number }>;
|
|
218
|
-
},
|
|
219
|
-
distance: number
|
|
220
|
-
): number {
|
|
221
|
-
const pathLength = getPathLength(path, pathConfig);
|
|
222
|
-
const t = Math.min(1, distance / pathLength);
|
|
223
|
-
const epsilon = 0.01;
|
|
224
|
-
const t2 = Math.min(1, (distance + epsilon) / pathLength);
|
|
225
|
-
|
|
226
|
-
const p1 = getPointOnPath(path, pathConfig, distance);
|
|
227
|
-
const p2 = getPointOnPath(path, pathConfig, distance + epsilon);
|
|
228
|
-
|
|
229
|
-
return Math.atan2(p2.y - p1.y, p2.x - p1.x);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function getPointOnLine(points: Array<{ x: number; y: number }>, t: number): { x: number; y: number } {
|
|
233
|
-
if (points.length < 2) return { x: 0, y: 0 };
|
|
234
|
-
|
|
235
|
-
const totalLength = points.reduce((sum, p, i) => {
|
|
236
|
-
if (i === 0) return 0;
|
|
237
|
-
const dx = p.x - points[i - 1].x;
|
|
238
|
-
const dy = p.y - points[i - 1].y;
|
|
239
|
-
return sum + Math.sqrt(dx * dx + dy * dy);
|
|
240
|
-
}, 0);
|
|
241
|
-
|
|
242
|
-
let currentLength = 0;
|
|
243
|
-
const targetLength = totalLength * t;
|
|
244
|
-
|
|
245
|
-
for (let i = 1; i < points.length; i++) {
|
|
246
|
-
const dx = points[i].x - points[i - 1].x;
|
|
247
|
-
const dy = points[i].y - points[i - 1].y;
|
|
248
|
-
const segmentLength = Math.sqrt(dx * dx + dy * dy);
|
|
249
|
-
|
|
250
|
-
if (currentLength + segmentLength >= targetLength) {
|
|
251
|
-
const segmentT = (targetLength - currentLength) / segmentLength;
|
|
252
|
-
return {
|
|
253
|
-
x: points[i - 1].x + dx * segmentT,
|
|
254
|
-
y: points[i - 1].y + dy * segmentT
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
currentLength += segmentLength;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return points[points.length - 1];
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function getPointOnArc(points: Array<{ x: number; y: number }>, t: number): { x: number; y: number } {
|
|
265
|
-
if (points.length < 3) return { x: 0, y: 0 };
|
|
266
|
-
|
|
267
|
-
const center = points[0];
|
|
268
|
-
const start = points[1];
|
|
269
|
-
const end = points[2];
|
|
270
|
-
const radius = Math.sqrt(
|
|
271
|
-
Math.pow(start.x - center.x, 2) + Math.pow(start.y - center.y, 2)
|
|
272
|
-
);
|
|
273
|
-
const startAngle = Math.atan2(start.y - center.y, start.x - center.x);
|
|
274
|
-
const endAngle = Math.atan2(end.y - center.y, end.x - center.x);
|
|
275
|
-
let angle = startAngle + (endAngle - startAngle) * t;
|
|
276
|
-
|
|
277
|
-
return {
|
|
278
|
-
x: center.x + Math.cos(angle) * radius,
|
|
279
|
-
y: center.y + Math.sin(angle) * radius
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function getPointOnBezier(points: Array<{ x: number; y: number }>, t: number): { x: number; y: number } {
|
|
284
|
-
if (points.length < 4) return { x: 0, y: 0 };
|
|
285
|
-
|
|
286
|
-
// Use first bezier curve
|
|
287
|
-
const p0 = points[0];
|
|
288
|
-
const p1 = points[1];
|
|
289
|
-
const p2 = points[2];
|
|
290
|
-
const p3 = points[3];
|
|
291
|
-
|
|
292
|
-
const mt = 1 - t;
|
|
293
|
-
const mt2 = mt * mt;
|
|
294
|
-
const mt3 = mt2 * mt;
|
|
295
|
-
const t2 = t * t;
|
|
296
|
-
const t3 = t2 * t;
|
|
297
|
-
|
|
298
|
-
return {
|
|
299
|
-
x: mt3 * p0.x + 3 * mt2 * t * p1.x + 3 * mt * t2 * p2.x + t3 * p3.x,
|
|
300
|
-
y: mt3 * p0.y + 3 * mt2 * t * p1.y + 3 * mt * t2 * p2.y + t3 * p3.y
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
function getPointOnQuadratic(points: Array<{ x: number; y: number }>, t: number): { x: number; y: number } {
|
|
305
|
-
if (points.length < 3) return { x: 0, y: 0 };
|
|
306
|
-
|
|
307
|
-
const p0 = points[0];
|
|
308
|
-
const p1 = points[1];
|
|
309
|
-
const p2 = points[2];
|
|
310
|
-
|
|
311
|
-
const mt = 1 - t;
|
|
312
|
-
const mt2 = mt * mt;
|
|
313
|
-
const t2 = t * t;
|
|
314
|
-
|
|
315
|
-
return {
|
|
316
|
-
x: mt2 * p0.x + 2 * mt * t * p1.x + t2 * p2.x,
|
|
317
|
-
y: mt2 * p0.y + 2 * mt * t * p1.y + t2 * p2.y
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import { SKRSContext2D } from '@napi-rs/canvas';
|
|
2
|
-
import { TextObject } from '../types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* The main function that draws text with optional wrapping.
|
|
6
|
-
* @param ctx CanvasRenderingContext2D
|
|
7
|
-
* @param textOptions TextObject
|
|
8
|
-
*/
|
|
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.');
|
|
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
|
-
}
|
|
63
|
-
|
|
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;
|
|
95
|
-
}
|
|
96
|
-
} else {
|
|
97
|
-
currentLine = testLine;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (currentLine && lines.length < maxLines) {
|
|
102
|
-
lines.push(currentLine);
|
|
103
|
-
}
|
|
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
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Draws a single line with correct alignment. Then uses `drawStrokeAndFill` to apply stroke, fill, etc.
|
|
118
|
-
*/
|
|
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
|
-
}
|
|
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) {
|
|
172
|
-
ctx.save();
|
|
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;
|
|
184
|
-
} else {
|
|
185
|
-
ctx.strokeStyle = options.stroke.color || options.color || 'darkgray';
|
|
186
|
-
}
|
|
187
|
-
ctx.strokeText(text, x, y);
|
|
188
|
-
ctx.restore();
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Then fill
|
|
192
|
-
ctx.fillText(text, x, y);
|
|
193
|
-
}
|
|
194
|
-
|
|
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;
|
|
231
|
-
}
|