apexify.js 5.0.3 → 5.1.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 (35) hide show
  1. package/CHANGELOG.md +352 -137
  2. package/README.md +440 -19
  3. package/dist/cjs/Canvas/ApexPainter.d.ts +272 -0
  4. package/dist/cjs/Canvas/ApexPainter.d.ts.map +1 -1
  5. package/dist/cjs/Canvas/ApexPainter.js +2275 -125
  6. package/dist/cjs/Canvas/ApexPainter.js.map +1 -1
  7. package/dist/cjs/Canvas/utils/Custom/advancedLines.d.ts +4 -4
  8. package/dist/cjs/Canvas/utils/Custom/advancedLines.d.ts.map +1 -1
  9. package/dist/cjs/Canvas/utils/Custom/advancedLines.js +63 -21
  10. package/dist/cjs/Canvas/utils/Custom/advancedLines.js.map +1 -1
  11. package/dist/cjs/Canvas/utils/Custom/customLines.d.ts.map +1 -1
  12. package/dist/cjs/Canvas/utils/Custom/customLines.js +3 -0
  13. package/dist/cjs/Canvas/utils/Custom/customLines.js.map +1 -1
  14. package/dist/cjs/Canvas/utils/types.d.ts +5 -1
  15. package/dist/cjs/Canvas/utils/types.d.ts.map +1 -1
  16. package/dist/cjs/Canvas/utils/types.js.map +1 -1
  17. package/dist/esm/Canvas/ApexPainter.d.ts +272 -0
  18. package/dist/esm/Canvas/ApexPainter.d.ts.map +1 -1
  19. package/dist/esm/Canvas/ApexPainter.js +2275 -125
  20. package/dist/esm/Canvas/ApexPainter.js.map +1 -1
  21. package/dist/esm/Canvas/utils/Custom/advancedLines.d.ts +4 -4
  22. package/dist/esm/Canvas/utils/Custom/advancedLines.d.ts.map +1 -1
  23. package/dist/esm/Canvas/utils/Custom/advancedLines.js +63 -21
  24. package/dist/esm/Canvas/utils/Custom/advancedLines.js.map +1 -1
  25. package/dist/esm/Canvas/utils/Custom/customLines.d.ts.map +1 -1
  26. package/dist/esm/Canvas/utils/Custom/customLines.js +3 -0
  27. package/dist/esm/Canvas/utils/Custom/customLines.js.map +1 -1
  28. package/dist/esm/Canvas/utils/types.d.ts +5 -1
  29. package/dist/esm/Canvas/utils/types.d.ts.map +1 -1
  30. package/dist/esm/Canvas/utils/types.js.map +1 -1
  31. package/lib/Canvas/ApexPainter.ts +2973 -136
  32. package/lib/Canvas/utils/Custom/advancedLines.ts +77 -25
  33. package/lib/Canvas/utils/Custom/customLines.ts +4 -0
  34. package/lib/Canvas/utils/types.ts +6 -2
  35. package/package.json +1 -3
@@ -103,10 +103,10 @@ export function drawMarker(
103
103
  }
104
104
 
105
105
  /**
106
- * Creates a smooth path from points
106
+ * Creates a smooth path from points using Cardinal Spline (graph-like smoothness)
107
107
  * @param ctx - Canvas 2D context
108
108
  * @param points - Array of points
109
- * @param tension - Smoothness (0-1)
109
+ * @param tension - Smoothness (0-1, default 0.5, lower = smoother)
110
110
  * @param closed - Whether path is closed
111
111
  */
112
112
  export function createSmoothPath(
@@ -117,6 +117,10 @@ export function createSmoothPath(
117
117
  ): void {
118
118
  if (points.length < 2) return;
119
119
 
120
+ // Enable anti-aliasing for smoother rendering
121
+ ctx.imageSmoothingEnabled = true;
122
+ ctx.imageSmoothingQuality = 'high';
123
+
120
124
  ctx.beginPath();
121
125
  ctx.moveTo(points[0].x, points[0].y);
122
126
 
@@ -125,18 +129,35 @@ export function createSmoothPath(
125
129
  return;
126
130
  }
127
131
 
132
+ // Cardinal spline - produces graph-like smooth curves
133
+ // Ultra-high resolution for maximum smoothness (like professional graphing libraries)
134
+ const segmentsPerCurve = 50; // Increased to 50 for ultra-smooth curves
135
+
128
136
  for (let i = 0; i < points.length - 1; i++) {
129
137
  const p0 = i > 0 ? points[i - 1] : (closed ? points[points.length - 1] : points[i]);
130
138
  const p1 = points[i];
131
139
  const p2 = points[i + 1];
132
140
  const p3 = i < points.length - 2 ? points[i + 2] : (closed ? points[0] : p2);
133
141
 
134
- const cp1x = p1.x + (p2.x - p0.x) / 6 * tension;
135
- const cp1y = p1.y + (p2.y - p0.y) / 6 * tension;
136
- const cp2x = p2.x - (p3.x - p1.x) / 6 * tension;
137
- const cp2y = p2.y - (p3.y - p1.y) / 6 * tension;
142
+ // Cardinal spline control points (optimized for maximum smoothness)
143
+ const t = (1 - tension) * 0.5; // Convert tension to cardinal spline parameter
144
+
145
+ const cp1x = p1.x + t * (p2.x - p0.x);
146
+ const cp1y = p1.y + t * (p2.y - p0.y);
147
+ const cp2x = p2.x - t * (p3.x - p1.x);
148
+ const cp2y = p2.y - t * (p3.y - p1.y);
138
149
 
139
- ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, p2.x, p2.y);
150
+ // Draw ultra-smooth curve with many segments for graph-like quality
151
+ for (let s = 0; s <= segmentsPerCurve; s++) {
152
+ const t = s / segmentsPerCurve;
153
+ const point = cubicBezier(p1, { x: cp1x, y: cp1y }, { x: cp2x, y: cp2y }, p2, t);
154
+
155
+ if (s === 0 && i === 0) {
156
+ ctx.moveTo(point.x, point.y);
157
+ } else {
158
+ ctx.lineTo(point.x, point.y);
159
+ }
160
+ }
140
161
  }
141
162
 
142
163
  if (closed) {
@@ -145,10 +166,32 @@ export function createSmoothPath(
145
166
  }
146
167
 
147
168
  /**
148
- * Creates a Catmull-Rom spline path
169
+ * Cubic Bezier interpolation helper
170
+ */
171
+ function cubicBezier(
172
+ p0: { x: number; y: number },
173
+ p1: { x: number; y: number },
174
+ p2: { x: number; y: number },
175
+ p3: { x: number; y: number },
176
+ t: number
177
+ ): { x: number; y: number } {
178
+ const mt = 1 - t;
179
+ const mt2 = mt * mt;
180
+ const mt3 = mt2 * mt;
181
+ const t2 = t * t;
182
+ const t3 = t2 * t;
183
+
184
+ return {
185
+ x: mt3 * p0.x + 3 * mt2 * t * p1.x + 3 * mt * t2 * p2.x + t3 * p3.x,
186
+ y: mt3 * p0.y + 3 * mt2 * t * p1.y + 3 * mt * t2 * p2.y + t3 * p3.y
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Creates a Catmull-Rom spline path (ultra-smooth, passes through all points - best for graphs)
149
192
  * @param ctx - Canvas 2D context
150
193
  * @param points - Array of points
151
- * @param tension - Tension (0-1)
194
+ * @param tension - Tension (0-1, default 0.5, lower = tighter curves)
152
195
  * @param closed - Whether path is closed
153
196
  */
154
197
  export function createCatmullRomPath(
@@ -159,6 +202,10 @@ export function createCatmullRomPath(
159
202
  ): void {
160
203
  if (points.length < 2) return;
161
204
 
205
+ // Enable anti-aliasing for smoother rendering
206
+ ctx.imageSmoothingEnabled = true;
207
+ ctx.imageSmoothingQuality = 'high';
208
+
162
209
  ctx.beginPath();
163
210
  ctx.moveTo(points[0].x, points[0].y);
164
211
 
@@ -168,6 +215,7 @@ export function createCatmullRomPath(
168
215
  }
169
216
 
170
217
  const segments = closed ? points.length : points.length - 1;
218
+ const segmentsPerCurve = 60; // Ultra-high resolution for maximum smoothness (graph quality)
171
219
 
172
220
  for (let i = 0; i < segments; i++) {
173
221
  const p0 = closed && i === 0 ? points[points.length - 1] : (i > 0 ? points[i - 1] : points[i]);
@@ -175,9 +223,12 @@ export function createCatmullRomPath(
175
223
  const p2 = points[(i + 1) % points.length];
176
224
  const p3 = closed && i === segments - 1 ? points[0] : (i < points.length - 2 ? points[i + 2] : p2);
177
225
 
178
- for (let t = 0; t <= 1; t += 0.1) {
226
+ // Draw ultra-smooth curve with maximum resolution for graph-like quality
227
+ for (let s = 0; s <= segmentsPerCurve; s++) {
228
+ const t = s / segmentsPerCurve;
179
229
  const point = catmullRom(p0, p1, p2, p3, t, tension);
180
- if (t === 0) {
230
+
231
+ if (s === 0 && i === 0) {
181
232
  ctx.moveTo(point.x, point.y);
182
233
  } else {
183
234
  ctx.lineTo(point.x, point.y);
@@ -191,7 +242,8 @@ export function createCatmullRomPath(
191
242
  }
192
243
 
193
244
  /**
194
- * Catmull-Rom interpolation
245
+ * Catmull-Rom spline interpolation (corrected formula)
246
+ * This creates curves that pass through all control points
195
247
  */
196
248
  function catmullRom(
197
249
  p0: { x: number; y: number },
@@ -204,21 +256,21 @@ function catmullRom(
204
256
  const t2 = t * t;
205
257
  const t3 = t2 * t;
206
258
 
207
- const x = 0.5 * (
208
- (2 * p1.x) +
209
- (-p0.x + p2.x) * t +
210
- (2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x) * t2 +
211
- (-p0.x + 3 * p1.x - 3 * p2.x + p3.x) * t3
212
- ) * tension;
259
+ // Proper Catmull-Rom spline formula with tension
260
+ // Tension typically ranges from 0 (tight) to 1 (loose)
261
+ const s = (1 - tension) * 0.5;
262
+
263
+ const x = (2 * p1.x) +
264
+ s * ((-p0.x + p2.x) * t +
265
+ (2 * p0.x - 5 * p1.x + 4 * p2.x - p3.x) * t2 +
266
+ (-p0.x + 3 * p1.x - 3 * p2.x + p3.x) * t3);
213
267
 
214
- const y = 0.5 * (
215
- (2 * p1.y) +
216
- (-p0.y + p2.y) * t +
217
- (2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y) * t2 +
218
- (-p0.y + 3 * p1.y - 3 * p2.y + p3.y) * t3
219
- ) * tension;
268
+ const y = (2 * p1.y) +
269
+ s * ((-p0.y + p2.y) * t +
270
+ (2 * p0.y - 5 * p1.y + 4 * p2.y - p3.y) * t2 +
271
+ (-p0.y + 3 * p1.y - 3 * p2.y + p3.y) * t3);
220
272
 
221
- return { x: p1.x + x, y: p1.y + y };
273
+ return { x: x * 0.5, y: y * 0.5 };
222
274
  }
223
275
 
224
276
  /**
@@ -5,6 +5,10 @@ import { drawArrow, drawMarker, createSmoothPath, createCatmullRomPath, applyLin
5
5
 
6
6
 
7
7
  export async function customLines(ctx: SKRSContext2D, options: CustomOptions[]): Promise<void> {
8
+ // Enable high-quality anti-aliasing for ultra-smooth lines (graph quality)
9
+ ctx.imageSmoothingEnabled = true;
10
+ ctx.imageSmoothingQuality = 'high';
11
+
8
12
  let previousEndCoordinates: { x: number; y: number } | null = null;
9
13
  let currentStyle: CustomOptions['lineStyle'] | null = null;
10
14
  let inSingleLineSequence = false;
@@ -91,11 +91,14 @@ export interface CanvasConfig {
91
91
  opacity?: number; // NEW: Background image opacity
92
92
  };
93
93
  videoBg?: {
94
- source: string;
95
- frame?: number; // Extract specific frame (default: 0)
94
+ source: string | Buffer; // Video file path, URL, or Buffer
95
+ frame?: number; // Extract specific frame number (default: 0)
96
+ time?: number; // Extract frame at specific time in seconds (overrides frame if provided)
96
97
  loop?: boolean; // Loop video (default: false)
97
98
  autoplay?: boolean; // Autoplay (default: false)
98
99
  opacity?: number; // Video opacity (default: 1)
100
+ format?: 'jpg' | 'png'; // Output format (default: 'jpg')
101
+ quality?: number; // JPEG quality 1-31, lower = better (default: 2)
99
102
  };
100
103
 
101
104
  colorBg?: string;
@@ -887,6 +890,7 @@ export interface PaletteOptions {
887
890
  }
888
891
 
889
892
  export interface ExtractFramesOptions {
893
+ outputDirectory?: string; // Directory to save frames
890
894
  interval: number;
891
895
  outputFormat?: 'jpg' | 'png';
892
896
  frameSelection?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apexify.js",
3
- "version": "5.0.3",
3
+ "version": "5.1.0",
4
4
  "description": "🎨 Advanced Canvas Rendering Library - Professional image processing, shape drawing, text effects, patterns, filters, and charts. Built with TypeScript & Rust for high performance.",
5
5
  "author": "zenith-79",
6
6
  "license": "MIT",
@@ -182,7 +182,6 @@
182
182
  "@napi-rs/canvas": "^0.1.80",
183
183
  "apexify.js": "^5.0.0",
184
184
  "axios": "^1.7.7",
185
- "fluent-ffmpeg": "^2.1.3",
186
185
  "fs-extra": "^11.3.1",
187
186
  "gifencoder": "^2.0.1",
188
187
  "imgur": "^2.5.0",
@@ -191,7 +190,6 @@
191
190
  "sharp": "^0.34.4"
192
191
  },
193
192
  "devDependencies": {
194
- "@types/fluent-ffmpeg": "^2.1.27",
195
193
  "@types/gifencoder": "^2.0.3",
196
194
  "@types/node": "^22.5.4",
197
195
  "ts-node": "^10.9.2",