@sarmal/core 0.17.1 → 0.18.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 (75) hide show
  1. package/dist/auto-init.cjs +113 -89
  2. package/dist/auto-init.cjs.map +1 -1
  3. package/dist/auto-init.js +112 -88
  4. package/dist/auto-init.js.map +1 -1
  5. package/dist/curves/artemis2.cjs +10 -7
  6. package/dist/curves/artemis2.d.cts +1 -1
  7. package/dist/curves/artemis2.d.ts +1 -1
  8. package/dist/curves/artemis2.js +9 -6
  9. package/dist/curves/astroid.cjs +4 -4
  10. package/dist/curves/astroid.d.cts +1 -1
  11. package/dist/curves/astroid.d.ts +1 -1
  12. package/dist/curves/astroid.js +3 -3
  13. package/dist/curves/deltoid.cjs +4 -4
  14. package/dist/curves/deltoid.d.cts +1 -1
  15. package/dist/curves/deltoid.d.ts +1 -1
  16. package/dist/curves/deltoid.js +3 -3
  17. package/dist/curves/epicycloid3.cjs +4 -4
  18. package/dist/curves/epicycloid3.d.cts +1 -1
  19. package/dist/curves/epicycloid3.d.ts +1 -1
  20. package/dist/curves/epicycloid3.js +3 -3
  21. package/dist/curves/epitrochoid7.cjs +5 -5
  22. package/dist/curves/epitrochoid7.d.cts +1 -1
  23. package/dist/curves/epitrochoid7.d.ts +1 -1
  24. package/dist/curves/epitrochoid7.js +4 -4
  25. package/dist/curves/index.cjs +53 -40
  26. package/dist/curves/index.d.cts +29 -29
  27. package/dist/curves/index.d.ts +29 -29
  28. package/dist/curves/index.js +69 -40
  29. package/dist/curves/lame.cjs +6 -5
  30. package/dist/curves/lame.d.cts +1 -1
  31. package/dist/curves/lame.d.ts +1 -1
  32. package/dist/curves/lame.js +5 -4
  33. package/dist/curves/lissajous32.cjs +4 -4
  34. package/dist/curves/lissajous32.d.cts +1 -1
  35. package/dist/curves/lissajous32.d.ts +1 -1
  36. package/dist/curves/lissajous32.js +3 -3
  37. package/dist/curves/lissajous43.cjs +4 -4
  38. package/dist/curves/lissajous43.d.cts +1 -1
  39. package/dist/curves/lissajous43.d.ts +1 -1
  40. package/dist/curves/lissajous43.js +3 -3
  41. package/dist/curves/rose3.cjs +4 -4
  42. package/dist/curves/rose3.d.cts +1 -1
  43. package/dist/curves/rose3.d.ts +1 -1
  44. package/dist/curves/rose3.js +3 -3
  45. package/dist/curves/rose5.cjs +4 -4
  46. package/dist/curves/rose5.d.cts +1 -1
  47. package/dist/curves/rose5.d.ts +1 -1
  48. package/dist/curves/rose5.js +3 -3
  49. package/dist/curves/rose52.cjs +5 -5
  50. package/dist/curves/rose52.d.cts +1 -1
  51. package/dist/curves/rose52.d.ts +1 -1
  52. package/dist/curves/rose52.js +4 -4
  53. package/dist/curves/star.cjs +8 -5
  54. package/dist/curves/star.d.cts +1 -1
  55. package/dist/curves/star.d.ts +1 -1
  56. package/dist/curves/star.js +7 -4
  57. package/dist/curves/star4.cjs +8 -5
  58. package/dist/curves/star4.d.cts +1 -1
  59. package/dist/curves/star4.d.ts +1 -1
  60. package/dist/curves/star4.js +7 -4
  61. package/dist/curves/star7.cjs +8 -5
  62. package/dist/curves/star7.d.cts +1 -1
  63. package/dist/curves/star7.d.ts +1 -1
  64. package/dist/curves/star7.js +7 -4
  65. package/dist/index.cjs +125 -93
  66. package/dist/index.cjs.map +1 -1
  67. package/dist/index.d.cts +74 -35
  68. package/dist/index.d.ts +74 -35
  69. package/dist/index.js +143 -93
  70. package/dist/index.js.map +1 -1
  71. package/dist/types-frtEoAq6.d.cts +317 -0
  72. package/dist/types-frtEoAq6.d.ts +317 -0
  73. package/package.json +1 -1
  74. package/dist/types-BL9HhEmk.d.cts +0 -299
  75. package/dist/types-BL9HhEmk.d.ts +0 -299
package/dist/index.js CHANGED
@@ -61,13 +61,13 @@ function resolveCurve(curveDef) {
61
61
  period,
62
62
  speed,
63
63
  skeleton: curveDef.skeleton,
64
- skeletonFn: curveDef.skeletonFn
64
+ skeletonFn: curveDef.skeletonFn,
65
65
  };
66
66
  }
67
67
  function createEngine(curveDef, trailLength = 120) {
68
68
  if (!Number.isFinite(trailLength) || trailLength <= 0) {
69
69
  throw new RangeError(
70
- `[sarmal] trailLength must be a positive finite number, got ${trailLength}`
70
+ `[sarmal] trailLength must be a positive finite number, got ${trailLength}`,
71
71
  );
72
72
  }
73
73
  let curve = resolveCurve(curveDef);
@@ -108,7 +108,7 @@ function createEngine(curveDef, trailLength = 120) {
108
108
  actualTime += deltaTime;
109
109
  if (morphCurveB !== null && _morphAlpha !== null) {
110
110
  const a = curve.fn(t, actualTime, EMPTY_PARAMS);
111
- const tB = _morphStrategy === "normalized" ? t / curve.period * morphCurveB.period : t;
111
+ const tB = _morphStrategy === "normalized" ? (t / curve.period) * morphCurveB.period : t;
112
112
  const b = morphCurveB.fn(tB, actualTime, EMPTY_PARAMS);
113
113
  trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
114
114
  } else {
@@ -120,6 +120,9 @@ function createEngine(curveDef, trailLength = 120) {
120
120
  get trailCount() {
121
121
  return trail.length;
122
122
  },
123
+ get trailLength() {
124
+ return trailLength;
125
+ },
123
126
  get isLiveSkeleton() {
124
127
  return curve.skeleton === "live";
125
128
  },
@@ -132,14 +135,14 @@ function createEngine(curveDef, trailLength = 120) {
132
135
  trail.clear();
133
136
  },
134
137
  jump(newT, { clearTrail = false } = {}) {
135
- t = (newT % curve.period + curve.period) % curve.period;
138
+ t = ((newT % curve.period) + curve.period) % curve.period;
136
139
  if (clearTrail) {
137
140
  trail.clear();
138
141
  }
139
142
  },
140
143
  seek(targetT, { wrap = false, step = curve.period / trailLength } = {}) {
141
144
  const advance = curve.speed * step;
142
- const target = (targetT % curve.period + curve.period) % curve.period;
145
+ const target = ((targetT % curve.period) + curve.period) % curve.period;
143
146
  const targetTime = target / curve.speed;
144
147
  t = target;
145
148
  actualTime = targetTime;
@@ -148,7 +151,7 @@ function createEngine(curveDef, trailLength = 120) {
148
151
  const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
149
152
  for (let i = count - 1; i >= 0; i--) {
150
153
  const sampleT = target - i * advance;
151
- const wrappedT = (sampleT % curve.period + curve.period) % curve.period;
154
+ const wrappedT = ((sampleT % curve.period) + curve.period) % curve.period;
152
155
  const time = targetTime - i * step;
153
156
  const point = curve.fn(wrappedT, time, EMPTY_PARAMS);
154
157
  trail.push(point.x, point.y);
@@ -165,13 +168,16 @@ function createEngine(curveDef, trailLength = 120) {
165
168
  ...frozenB,
166
169
  fn: (sampleT, time, params) => {
167
170
  const a = frozenA.fn(sampleT, time, params);
168
- const tB = frozenStrategy === "normalized" ? sampleT / frozenA.period * frozenB.period : sampleT;
171
+ const tB =
172
+ frozenStrategy === "normalized"
173
+ ? (sampleT / frozenA.period) * frozenB.period
174
+ : sampleT;
169
175
  const b = frozenB.fn(tB, time, params);
170
176
  return {
171
177
  x: a.x + (b.x - a.x) * frozenAlpha,
172
- y: a.y + (b.y - a.y) * frozenAlpha
178
+ y: a.y + (b.y - a.y) * frozenAlpha,
173
179
  };
174
- }
180
+ },
175
181
  };
176
182
  }
177
183
  _morphStrategy = strategy;
@@ -184,7 +190,7 @@ function createEngine(curveDef, trailLength = 120) {
184
190
  completeMorph() {
185
191
  if (morphCurveB !== null) {
186
192
  if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
187
- t = t / curve.period * morphCurveB.period;
193
+ t = (t / curve.period) * morphCurveB.period;
188
194
  }
189
195
  curve = morphCurveB;
190
196
  }
@@ -196,19 +202,22 @@ function createEngine(curveDef, trailLength = 120) {
196
202
  const points = new Array(steps);
197
203
  if (morphCurveB !== null && _morphAlpha !== null) {
198
204
  for (let i = 0; i < steps; i++) {
199
- const sampleT = i / (steps - 1) * curve.period;
205
+ const sampleT = (i / (steps - 1)) * curve.period;
200
206
  const a = sampleSkeleton(curve, sampleT);
201
- const tB = _morphStrategy === "normalized" ? sampleT / curve.period * morphCurveB.period : sampleT;
207
+ const tB =
208
+ _morphStrategy === "normalized"
209
+ ? (sampleT / curve.period) * morphCurveB.period
210
+ : sampleT;
202
211
  const b = sampleSkeleton(morphCurveB, tB);
203
212
  points[i] = {
204
213
  x: a.x + (b.x - a.x) * _morphAlpha,
205
- y: a.y + (b.y - a.y) * _morphAlpha
214
+ y: a.y + (b.y - a.y) * _morphAlpha,
206
215
  };
207
216
  }
208
217
  return points;
209
218
  }
210
219
  for (let i = 0; i < steps; i++) {
211
- const sampleT = i / (steps - 1) * curve.period;
220
+ const sampleT = (i / (steps - 1)) * curve.period;
212
221
  points[i] = sampleSkeleton(curve, sampleT);
213
222
  }
214
223
  return points;
@@ -250,7 +259,7 @@ function createEngine(curveDef, trailLength = 120) {
250
259
  _speedTransition.reject(new Error("Speed transition cancelled"));
251
260
  _speedTransition = null;
252
261
  }
253
- }
262
+ },
254
263
  };
255
264
  }
256
265
 
@@ -313,13 +322,16 @@ function computeTrailQuad(trail, i, trailCount, toX, toY) {
313
322
  r1x: nx - n1.x * w1,
314
323
  r1y: ny - n1.y * w1,
315
324
  opacity,
316
- progress
325
+ progress,
317
326
  };
318
327
  }
319
328
  function computeBoundaries(pts, logicalWidth, logicalHeight) {
320
329
  if (pts.length === 0) return null;
321
330
  const first = pts[0];
322
- let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
331
+ let minX = first.x,
332
+ maxX = first.x,
333
+ minY = first.y,
334
+ maxY = first.y;
323
335
  for (const p of pts) {
324
336
  if (p.x < minX) {
325
337
  minX = p.x;
@@ -338,7 +350,7 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
338
350
  const h = maxY - minY;
339
351
  if (w === 0 && h === 0) {
340
352
  throw new Error(
341
- "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
353
+ "[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
342
354
  );
343
355
  }
344
356
  const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
@@ -349,12 +361,12 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
349
361
  scaleXProportional,
350
362
  scaleYProportional,
351
363
  scaleXMinPadding,
352
- scaleYMinPadding
364
+ scaleYMinPadding,
353
365
  );
354
366
  return {
355
367
  scale,
356
368
  offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
357
- offsetY: (logicalHeight - h * scale) / 2 - minY * scale
369
+ offsetY: (logicalHeight - h * scale) / 2 - minY * scale,
358
370
  };
359
371
  }
360
372
  function enginePassthroughs(engine) {
@@ -364,7 +376,7 @@ function enginePassthroughs(engine) {
364
376
  setSpeed: engine.setSpeed,
365
377
  getSpeed: engine.getSpeed,
366
378
  resetSpeed: engine.resetSpeed,
367
- setSpeedOver: engine.setSpeedOver
379
+ setSpeedOver: engine.setSpeedOver,
368
380
  };
369
381
  }
370
382
  var palettes = {
@@ -373,16 +385,16 @@ var palettes = {
373
385
  ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
374
386
  ice: ["#1e3a8a", "#67e8f9"],
375
387
  fire: ["#7f1d1d", "#fbbf24"],
376
- forest: ["#14532d", "#86efac"]
388
+ forest: ["#14532d", "#86efac"],
377
389
  };
378
390
  function hexToRgb(hex) {
379
391
  const n = parseInt(hex.slice(1), 16);
380
- return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
392
+ return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
381
393
  }
382
394
  var lerpRgb = (a, b, t) => ({
383
395
  r: Math.round(a.r + (b.r - a.r) * t),
384
396
  g: Math.round(a.g + (b.g - a.g) * t),
385
- b: Math.round(a.b + (b.b - a.b) * t)
397
+ b: Math.round(a.b + (b.b - a.b) * t),
386
398
  });
387
399
  function getPaletteColor(palette, position, timeOffset = 0) {
388
400
  if (palette.length === 0) {
@@ -391,7 +403,7 @@ function getPaletteColor(palette, position, timeOffset = 0) {
391
403
  if (palette.length === 1) {
392
404
  return hexToRgb(palette[0]);
393
405
  }
394
- const cyclePos = (position + timeOffset) % 1;
406
+ const cyclePos = (((position + timeOffset) % 1) + 1) % 1;
395
407
  const scaled = cyclePos * palette.length;
396
408
  const idx = Math.floor(scaled);
397
409
  const t = scaled - idx;
@@ -405,7 +417,7 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
405
417
  "trailColor",
406
418
  "headColor",
407
419
  "skeletonColor",
408
- "trailStyle"
420
+ "trailStyle",
409
421
  ]);
410
422
  function validateRenderOptions(partial) {
411
423
  for (const key of Object.keys(partial)) {
@@ -430,7 +442,7 @@ function assertTrailColor(value) {
430
442
  if (typeof value === "string") {
431
443
  if (!HEX_COLOR_RE.test(value)) {
432
444
  throw new TypeError(
433
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`
445
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`,
434
446
  );
435
447
  }
436
448
  return;
@@ -438,21 +450,21 @@ function assertTrailColor(value) {
438
450
  if (Array.isArray(value)) {
439
451
  if (value.length < 2) {
440
452
  throw new RangeError(
441
- `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`
453
+ `[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,
442
454
  );
443
455
  }
444
456
  for (let i = 0; i < value.length; i++) {
445
457
  const entry = value[i];
446
458
  if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
447
459
  throw new TypeError(
448
- `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`
460
+ `[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,
449
461
  );
450
462
  }
451
463
  }
452
464
  return;
453
465
  }
454
466
  throw new TypeError(
455
- `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`
467
+ `[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`,
456
468
  );
457
469
  }
458
470
  function assertHeadColor(value) {
@@ -461,7 +473,7 @@ function assertHeadColor(value) {
461
473
  }
462
474
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
463
475
  throw new TypeError(
464
- `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`
476
+ `[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`,
465
477
  );
466
478
  }
467
479
  }
@@ -471,14 +483,14 @@ function assertSkeletonColor(value) {
471
483
  }
472
484
  if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
473
485
  throw new TypeError(
474
- `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`
486
+ `[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`,
475
487
  );
476
488
  }
477
489
  }
478
490
  function assertTrailStyle(value) {
479
491
  if (!TRAIL_STYLES.includes(value)) {
480
492
  throw new RangeError(
481
- `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`
493
+ `[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`,
482
494
  );
483
495
  }
484
496
  }
@@ -500,13 +512,13 @@ function resolveHeadColor(trailColor, trailStyle) {
500
512
  function warnIfTrailColorMismatch(trailColor, trailStyle) {
501
513
  if (trailStyle === "default" && Array.isArray(trailColor)) {
502
514
  console.warn(
503
- '[sarmal] trailColor is an array but trailStyle is "default"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.'
515
+ '[sarmal] trailColor is an array but trailStyle is "default"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.',
504
516
  );
505
517
  return;
506
518
  }
507
519
  if (trailStyle !== "default" && typeof trailColor === "string") {
508
520
  console.warn(
509
- `[sarmal] trailColor is a single color but trailStyle is "${trailStyle}"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`
521
+ `[sarmal] trailColor is a single color but trailStyle is "${trailStyle}"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`,
510
522
  );
511
523
  }
512
524
  }
@@ -516,7 +528,7 @@ var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160)
516
528
  var WHITE_HEX = "#ffffff";
517
529
  function hexToRgbComponents(hex) {
518
530
  const n = parseInt(hex.slice(1), 16);
519
- return `${n >> 16},${n >> 8 & 255},${n & 255}`;
531
+ return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
520
532
  }
521
533
  function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
522
534
  target.style.width = `${logicalWidth}px`;
@@ -641,7 +653,7 @@ function createRenderer(options) {
641
653
  i,
642
654
  trailCount,
643
655
  toX,
644
- toY
656
+ toY,
645
657
  );
646
658
  if (trailStyle === "default") {
647
659
  ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
@@ -802,7 +814,7 @@ function createRenderer(options) {
802
814
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
803
815
  warnIfTrailColorMismatch(trailColor, trailStyle);
804
816
  }
805
- }
817
+ },
806
818
  };
807
819
  if (shouldAutoStart) {
808
820
  instance.play();
@@ -811,10 +823,12 @@ function createRenderer(options) {
811
823
  }
812
824
 
813
825
  // src/renderer-svg.ts
814
- var MAX_TRAIL_SEGMENTS = 200;
815
826
  var EMPTY_PARAMS2 = {};
827
+ var HIGH_TRAIL_LENGTH_THRESHOLD = 5e3;
816
828
  function pointsToPathString(pts, scale, offsetX, offsetY) {
817
- if (pts.length < 2) return "";
829
+ if (pts.length < 2) {
830
+ return "";
831
+ }
818
832
  const px = (p) => (p.x * scale + offsetX).toFixed(2);
819
833
  const py = (p) => (p.y * scale + offsetY).toFixed(2);
820
834
  let d = `M${px(pts[0])} ${py(pts[0])}`;
@@ -828,7 +842,7 @@ function sampleCurveSkeleton(curveDef) {
828
842
  const samples = Math.ceil(period * 50);
829
843
  const pts = Array.from({ length: samples });
830
844
  for (let i = 0; i < samples; i++) {
831
- const t = i / (samples - 1) * period;
845
+ const t = (i / (samples - 1)) * period;
832
846
  pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(t) : curveDef.fn(t, 0, EMPTY_PARAMS2);
833
847
  }
834
848
  return pts;
@@ -838,6 +852,12 @@ function el(tag) {
838
852
  }
839
853
  function createSVGRenderer(options) {
840
854
  const { container, engine } = options;
855
+ const poolSize = engine.trailLength;
856
+ if (poolSize > HIGH_TRAIL_LENGTH_THRESHOLD) {
857
+ console.warn(
858
+ `[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`,
859
+ );
860
+ }
841
861
  let trailStyle = options.trailStyle ?? "default";
842
862
  let trailColor = options.trailColor ?? "#ffffff";
843
863
  let skeletonColor = options.skeletonColor ?? "#ffffff";
@@ -885,7 +905,7 @@ function createSVGRenderer(options) {
885
905
  let morphPathABuilt = "";
886
906
  let morphPathBBuilt = "";
887
907
  const trailPaths = [];
888
- for (let i = 0; i < MAX_TRAIL_SEGMENTS; i++) {
908
+ for (let i = 0; i < poolSize; i++) {
889
909
  const path = el("path");
890
910
  path.setAttribute("fill", trailSolid);
891
911
  svg.appendChild(path);
@@ -930,24 +950,22 @@ function createSVGRenderer(options) {
930
950
  }
931
951
  return;
932
952
  }
933
- const startIdx = Math.max(0, trailCount - 1 - MAX_TRAIL_SEGMENTS);
934
- const drawnCount = trailCount - 1 - startIdx;
935
- for (let i = startIdx; i < trailCount - 1; i++) {
936
- const j = i - startIdx;
953
+ const drawnCount = trailCount - 1;
954
+ for (let i = 0; i < drawnCount; i++) {
937
955
  const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(
938
956
  trail,
939
957
  i,
940
958
  trailCount,
941
959
  px,
942
- py
960
+ py,
943
961
  );
944
962
  const d = `M${l0x.toFixed(2)} ${l0y.toFixed(2)} L${l1x.toFixed(2)} ${l1y.toFixed(2)} L${r1x.toFixed(2)} ${r1y.toFixed(2)} L${r0x.toFixed(2)} ${r0y.toFixed(2)} Z`;
945
- trailPaths[j].setAttribute("d", d);
946
- trailPaths[j].setAttribute("fill-opacity", opacity.toFixed(3));
963
+ trailPaths[i].setAttribute("d", d);
964
+ trailPaths[i].setAttribute("fill-opacity", opacity.toFixed(3));
947
965
  if (trailStyle !== "default") {
948
966
  const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
949
967
  const { r, g, b } = getPaletteColor(trailPalette, progress, timeOffset);
950
- trailPaths[j].setAttribute("fill", `rgb(${r},${g},${b})`);
968
+ trailPaths[i].setAttribute("fill", `rgb(${r},${g},${b})`);
951
969
  }
952
970
  }
953
971
  for (let i = drawnCount; i < trailPaths.length; i++) {
@@ -966,7 +984,8 @@ function createSVGRenderer(options) {
966
984
  }
967
985
  let animationId = null;
968
986
  let lastTime = 0;
969
- const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
987
+ const prefersReducedMotion =
988
+ typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
970
989
  let morphResolve = null;
971
990
  let morphReject = null;
972
991
  let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
@@ -984,7 +1003,7 @@ function createSVGRenderer(options) {
984
1003
  skeletonPathA.setAttribute("visibility", "visible");
985
1004
  skeletonPathA.setAttribute(
986
1005
  "stroke-opacity",
987
- String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY)
1006
+ String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),
988
1007
  );
989
1008
  }
990
1009
  if (morphPathBBuilt) {
@@ -1133,7 +1152,7 @@ function createSVGRenderer(options) {
1133
1152
  if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
1134
1153
  warnIfTrailColorMismatch(trailColor, trailStyle);
1135
1154
  }
1136
- }
1155
+ },
1137
1156
  };
1138
1157
  if (shouldAutoStart) {
1139
1158
  instance.play();
@@ -1149,19 +1168,22 @@ function createSarmalSVG(container, curveDef, options) {
1149
1168
  // src/curves/artemis2.ts
1150
1169
  var TWO_PI2 = Math.PI * 2;
1151
1170
  function artemis2Fn(t, _time, _params) {
1152
- const a = 0.35, b = 0.15, ox = 0.175;
1153
- const s = Math.sin(t), c = Math.cos(t);
1171
+ const a = 0.35,
1172
+ b = 0.15,
1173
+ ox = 0.175;
1174
+ const s = Math.sin(t),
1175
+ c = Math.cos(t);
1154
1176
  const denom = 1 + s * s;
1155
1177
  return {
1156
- x: c * (1 + a * c) / denom - ox,
1157
- y: s * c * (1 + b * c) / denom
1178
+ x: (c * (1 + a * c)) / denom - ox,
1179
+ y: (s * c * (1 + b * c)) / denom,
1158
1180
  };
1159
1181
  }
1160
1182
  var artemis2 = {
1161
1183
  name: "Artemis II",
1162
1184
  fn: artemis2Fn,
1163
1185
  period: TWO_PI2,
1164
- speed: 0.7
1186
+ speed: 0.7,
1165
1187
  };
1166
1188
 
1167
1189
  // src/curves/astroid.ts
@@ -1171,14 +1193,14 @@ function astroidFn(t, _time, _params) {
1171
1193
  const s = Math.sin(t);
1172
1194
  return {
1173
1195
  x: c * c * c,
1174
- y: s * s * s
1196
+ y: s * s * s,
1175
1197
  };
1176
1198
  }
1177
1199
  var astroid = {
1178
1200
  name: "Astroid",
1179
1201
  fn: astroidFn,
1180
1202
  period: TWO_PI3,
1181
- speed: 1.1
1203
+ speed: 1.1,
1182
1204
  };
1183
1205
 
1184
1206
  // src/curves/deltoid.ts
@@ -1186,14 +1208,14 @@ var TWO_PI4 = Math.PI * 2;
1186
1208
  function deltoidFn(t, _time, _params) {
1187
1209
  return {
1188
1210
  x: 2 * Math.cos(t) + Math.cos(2 * t),
1189
- y: 2 * Math.sin(t) - Math.sin(2 * t)
1211
+ y: 2 * Math.sin(t) - Math.sin(2 * t),
1190
1212
  };
1191
1213
  }
1192
1214
  var deltoid = {
1193
1215
  name: "Deltoid",
1194
1216
  fn: deltoidFn,
1195
1217
  period: TWO_PI4,
1196
- speed: 0.9
1218
+ speed: 0.9,
1197
1219
  };
1198
1220
 
1199
1221
  // src/curves/epicycloid3.ts
@@ -1201,14 +1223,14 @@ var TWO_PI5 = Math.PI * 2;
1201
1223
  function epicycloid3Fn(t, _time, _params) {
1202
1224
  return {
1203
1225
  x: 4 * Math.cos(t) - Math.cos(4 * t),
1204
- y: 4 * Math.sin(t) - Math.sin(4 * t)
1226
+ y: 4 * Math.sin(t) - Math.sin(4 * t),
1205
1227
  };
1206
1228
  }
1207
1229
  var epicycloid3 = {
1208
1230
  name: "Epicycloid (n=3)",
1209
1231
  fn: epicycloid3Fn,
1210
1232
  period: TWO_PI5,
1211
- speed: 0.75
1233
+ speed: 0.75,
1212
1234
  };
1213
1235
 
1214
1236
  // src/curves/epitrochoid7.ts
@@ -1217,14 +1239,14 @@ function epitrochoid7Fn(t, _time, _params) {
1217
1239
  const d = 1 + 0.55 * Math.sin(t * 0.5);
1218
1240
  return {
1219
1241
  x: 7 * Math.cos(t) - d * Math.cos(7 * t),
1220
- y: 7 * Math.sin(t) - d * Math.sin(7 * t)
1242
+ y: 7 * Math.sin(t) - d * Math.sin(7 * t),
1221
1243
  };
1222
1244
  }
1223
1245
  function epitrochoid7SkeletonFn(t) {
1224
1246
  const d = 1.275;
1225
1247
  return {
1226
1248
  x: 7 * Math.cos(t) - d * Math.cos(7 * t),
1227
- y: 7 * Math.sin(t) - d * Math.sin(7 * t)
1249
+ y: 7 * Math.sin(t) - d * Math.sin(7 * t),
1228
1250
  };
1229
1251
  }
1230
1252
  var epitrochoid7 = {
@@ -1232,7 +1254,7 @@ var epitrochoid7 = {
1232
1254
  fn: epitrochoid7Fn,
1233
1255
  period: TWO_PI6,
1234
1256
  speed: 1.4,
1235
- skeletonFn: epitrochoid7SkeletonFn
1257
+ skeletonFn: epitrochoid7SkeletonFn,
1236
1258
  };
1237
1259
 
1238
1260
  // src/curves/lissajous32.ts
@@ -1241,7 +1263,7 @@ function lissajous32Fn(t, time, _params) {
1241
1263
  const phi = time * 0.45;
1242
1264
  return {
1243
1265
  x: Math.sin(3 * t + phi),
1244
- y: Math.sin(2 * t)
1266
+ y: Math.sin(2 * t),
1245
1267
  };
1246
1268
  }
1247
1269
  var lissajous32 = {
@@ -1249,7 +1271,7 @@ var lissajous32 = {
1249
1271
  fn: lissajous32Fn,
1250
1272
  period: TWO_PI7,
1251
1273
  speed: 2,
1252
- skeleton: "live"
1274
+ skeleton: "live",
1253
1275
  };
1254
1276
 
1255
1277
  // src/curves/lissajous43.ts
@@ -1258,7 +1280,7 @@ function lissajous43Fn(t, time, _params) {
1258
1280
  const phi = time * 0.38;
1259
1281
  return {
1260
1282
  x: Math.sin(4 * t + phi),
1261
- y: Math.sin(3 * t)
1283
+ y: Math.sin(3 * t),
1262
1284
  };
1263
1285
  }
1264
1286
  var lissajous43 = {
@@ -1266,17 +1288,18 @@ var lissajous43 = {
1266
1288
  fn: lissajous43Fn,
1267
1289
  period: TWO_PI8,
1268
1290
  speed: 1.8,
1269
- skeleton: "live"
1291
+ skeleton: "live",
1270
1292
  };
1271
1293
 
1272
1294
  // src/curves/lame.ts
1273
1295
  var TWO_PI9 = Math.PI * 2;
1274
1296
  function lameFn(t, time, _params) {
1275
1297
  const p = 1.75 + 1.25 * Math.sin(time * 0.48);
1276
- const c = Math.cos(t), s = Math.sin(t);
1298
+ const c = Math.cos(t),
1299
+ s = Math.sin(t);
1277
1300
  return {
1278
1301
  x: Math.sign(c) * Math.pow(Math.abs(c), p),
1279
- y: Math.sign(s) * Math.pow(Math.abs(s), p)
1302
+ y: Math.sign(s) * Math.pow(Math.abs(s), p),
1280
1303
  };
1281
1304
  }
1282
1305
  var lame = {
@@ -1284,7 +1307,7 @@ var lame = {
1284
1307
  fn: lameFn,
1285
1308
  period: TWO_PI9,
1286
1309
  speed: 1,
1287
- skeleton: "live"
1310
+ skeleton: "live",
1288
1311
  };
1289
1312
 
1290
1313
  // src/curves/rose3.ts
@@ -1293,14 +1316,14 @@ function rose3Fn(t, _time, _params) {
1293
1316
  const r = Math.cos(3 * t);
1294
1317
  return {
1295
1318
  x: r * Math.cos(t),
1296
- y: r * Math.sin(t)
1319
+ y: r * Math.sin(t),
1297
1320
  };
1298
1321
  }
1299
1322
  var rose3 = {
1300
1323
  name: "Rose (n=3)",
1301
1324
  fn: rose3Fn,
1302
1325
  period: TWO_PI10,
1303
- speed: 1.15
1326
+ speed: 1.15,
1304
1327
  };
1305
1328
 
1306
1329
  // src/curves/rose5.ts
@@ -1309,78 +1332,87 @@ function rose5Fn(t, _time, _params) {
1309
1332
  const r = Math.cos(5 * t);
1310
1333
  return {
1311
1334
  x: r * Math.cos(t),
1312
- y: r * Math.sin(t)
1335
+ y: r * Math.sin(t),
1313
1336
  };
1314
1337
  }
1315
1338
  var rose5 = {
1316
1339
  name: "Rose (n=5)",
1317
1340
  fn: rose5Fn,
1318
1341
  period: TWO_PI11,
1319
- speed: 1
1342
+ speed: 1,
1320
1343
  };
1321
1344
 
1322
1345
  // src/curves/rose52.ts
1323
1346
  var FOUR_PI = Math.PI * 4;
1324
1347
  function rose52Fn(t, _time, _params) {
1325
- const r = Math.cos(5 / 2 * t);
1348
+ const r = Math.cos((5 / 2) * t);
1326
1349
  return {
1327
1350
  x: r * Math.cos(t),
1328
- y: r * Math.sin(t)
1351
+ y: r * Math.sin(t),
1329
1352
  };
1330
1353
  }
1331
1354
  var rose52 = {
1332
1355
  name: "Rose (n=5/2)",
1333
1356
  fn: rose52Fn,
1334
1357
  period: FOUR_PI,
1335
- speed: 0.8
1358
+ speed: 0.8,
1336
1359
  };
1337
1360
 
1338
1361
  // src/curves/star.ts
1339
1362
  var TWO_PI12 = Math.PI * 2;
1340
1363
  function starFn(t, _time, _params) {
1341
- const r = Math.abs(Math.cos(5 / 2 * t)) + 0.35 * Math.abs(Math.cos(15 / 2 * t)) + 0.15 * Math.abs(Math.cos(25 / 2 * t));
1364
+ const r =
1365
+ Math.abs(Math.cos((5 / 2) * t)) +
1366
+ 0.35 * Math.abs(Math.cos((15 / 2) * t)) +
1367
+ 0.15 * Math.abs(Math.cos((25 / 2) * t));
1342
1368
  return {
1343
1369
  x: r * Math.cos(t),
1344
- y: r * Math.sin(t)
1370
+ y: r * Math.sin(t),
1345
1371
  };
1346
1372
  }
1347
1373
  var star = {
1348
1374
  name: "Star",
1349
1375
  fn: starFn,
1350
1376
  period: TWO_PI12,
1351
- speed: 1
1377
+ speed: 1,
1352
1378
  };
1353
1379
 
1354
1380
  // src/curves/star4.ts
1355
1381
  var TWO_PI13 = Math.PI * 2;
1356
1382
  function star4Fn(t, _time, _params) {
1357
- const r = Math.abs(Math.cos(2 * t)) + 0.35 * Math.abs(Math.cos(6 * t)) + 0.15 * Math.abs(Math.cos(10 * t));
1383
+ const r =
1384
+ Math.abs(Math.cos(2 * t)) +
1385
+ 0.35 * Math.abs(Math.cos(6 * t)) +
1386
+ 0.15 * Math.abs(Math.cos(10 * t));
1358
1387
  return {
1359
1388
  x: r * Math.cos(t),
1360
- y: r * Math.sin(t)
1389
+ y: r * Math.sin(t),
1361
1390
  };
1362
1391
  }
1363
1392
  var star4 = {
1364
1393
  name: "Star (4-arm)",
1365
1394
  fn: star4Fn,
1366
1395
  period: TWO_PI13,
1367
- speed: 1
1396
+ speed: 1,
1368
1397
  };
1369
1398
 
1370
1399
  // src/curves/star7.ts
1371
1400
  var TWO_PI14 = Math.PI * 2;
1372
1401
  function star7Fn(t, _time, _params) {
1373
- const r = Math.abs(Math.cos(7 / 2 * t)) + 0.35 * Math.abs(Math.cos(21 / 2 * t)) + 0.15 * Math.abs(Math.cos(35 / 2 * t));
1402
+ const r =
1403
+ Math.abs(Math.cos((7 / 2) * t)) +
1404
+ 0.35 * Math.abs(Math.cos((21 / 2) * t)) +
1405
+ 0.15 * Math.abs(Math.cos((35 / 2) * t));
1374
1406
  return {
1375
1407
  x: r * Math.cos(t),
1376
- y: r * Math.sin(t)
1408
+ y: r * Math.sin(t),
1377
1409
  };
1378
1410
  }
1379
1411
  var star7 = {
1380
1412
  name: "Star (7-arm)",
1381
1413
  fn: star7Fn,
1382
1414
  period: TWO_PI14,
1383
- speed: 1
1415
+ speed: 1,
1384
1416
  };
1385
1417
 
1386
1418
  // src/curves/index.ts
@@ -1398,7 +1430,7 @@ var curves = {
1398
1430
  lissajous32,
1399
1431
  lissajous43,
1400
1432
  epicycloid3,
1401
- lame
1433
+ lame,
1402
1434
  };
1403
1435
 
1404
1436
  // src/index.ts
@@ -1408,6 +1440,24 @@ function createSarmal(canvas, curveDef, options) {
1408
1440
  return createRenderer({ canvas, engine, ...rendererOpts });
1409
1441
  }
1410
1442
 
1411
- export { artemis2, astroid, createEngine, createRenderer, createSVGRenderer, createSarmal, createSarmalSVG, curves, deltoid, epicycloid3, epitrochoid7, lame, lissajous32, lissajous43, palettes, rose3, rose5 };
1443
+ export {
1444
+ artemis2,
1445
+ astroid,
1446
+ createEngine,
1447
+ createRenderer,
1448
+ createSVGRenderer,
1449
+ createSarmal,
1450
+ createSarmalSVG,
1451
+ curves,
1452
+ deltoid,
1453
+ epicycloid3,
1454
+ epitrochoid7,
1455
+ lame,
1456
+ lissajous32,
1457
+ lissajous43,
1458
+ palettes,
1459
+ rose3,
1460
+ rose5,
1461
+ };
1462
+ //# sourceMappingURL=index.js.map
1412
1463
  //# sourceMappingURL=index.js.map
1413
- //# sourceMappingURL=index.js.map