@sarmal/core 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  // src/engine.ts
4
4
  var TWO_PI = Math.PI * 2;
@@ -51,7 +51,7 @@ function resolveCurve(curveDef) {
51
51
  period: curveDef.period ?? TWO_PI,
52
52
  speed: curveDef.speed ?? 1,
53
53
  skeleton: curveDef.skeleton,
54
- skeletonFn: curveDef.skeletonFn,
54
+ skeletonFn: curveDef.skeletonFn
55
55
  };
56
56
  }
57
57
  function createEngine(curveDef, trailLength = 120) {
@@ -77,7 +77,7 @@ function createEngine(curveDef, trailLength = 120) {
77
77
  actualTime += deltaTime;
78
78
  if (morphCurveB !== null && _morphAlpha !== null) {
79
79
  const a = curve.fn(t, actualTime, {});
80
- const tB = _morphStrategy === "normalized" ? (t / curve.period) * morphCurveB.period : t;
80
+ const tB = _morphStrategy === "normalized" ? t / curve.period * morphCurveB.period : t;
81
81
  const b = morphCurveB.fn(tB, actualTime, {});
82
82
  trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
83
83
  } else {
@@ -101,14 +101,14 @@ function createEngine(curveDef, trailLength = 120) {
101
101
  trail.clear();
102
102
  },
103
103
  seek(newT, { clearTrail = false } = {}) {
104
- t = ((newT % curve.period) + curve.period) % curve.period;
104
+ t = (newT % curve.period + curve.period) % curve.period;
105
105
  if (clearTrail) {
106
106
  trail.clear();
107
107
  }
108
108
  },
109
109
  seekWithTrail(targetT, { wrap = false, step = curve.period / trailLength } = {}) {
110
110
  const advance = curve.speed * step;
111
- const target = ((targetT % curve.period) + curve.period) % curve.period;
111
+ const target = (targetT % curve.period + curve.period) % curve.period;
112
112
  const targetTime = target / curve.speed;
113
113
  t = target;
114
114
  actualTime = targetTime;
@@ -134,16 +134,13 @@ function createEngine(curveDef, trailLength = 120) {
134
134
  ...frozenB,
135
135
  fn: (sampleT, time, params) => {
136
136
  const a = frozenA.fn(sampleT, time, params);
137
- const tB =
138
- frozenStrategy === "normalized"
139
- ? (sampleT / frozenA.period) * frozenB.period
140
- : sampleT;
137
+ const tB = frozenStrategy === "normalized" ? sampleT / frozenA.period * frozenB.period : sampleT;
141
138
  const b = frozenB.fn(tB, time, params);
142
139
  return {
143
140
  x: a.x + (b.x - a.x) * frozenAlpha,
144
- y: a.y + (b.y - a.y) * frozenAlpha,
141
+ y: a.y + (b.y - a.y) * frozenAlpha
145
142
  };
146
- },
143
+ }
147
144
  };
148
145
  }
149
146
  _morphStrategy = strategy;
@@ -155,6 +152,9 @@ function createEngine(curveDef, trailLength = 120) {
155
152
  },
156
153
  completeMorph() {
157
154
  if (morphCurveB !== null) {
155
+ if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
156
+ t = t / curve.period * morphCurveB.period;
157
+ }
158
158
  curve = morphCurveB;
159
159
  }
160
160
  morphCurveB = null;
@@ -165,26 +165,23 @@ function createEngine(curveDef, trailLength = 120) {
165
165
  const points = new Array(steps);
166
166
  if (morphCurveB !== null && _morphAlpha !== null) {
167
167
  for (let i = 0; i < steps; i++) {
168
- const sampleT = (i / (steps - 1)) * curve.period;
168
+ const sampleT = i / (steps - 1) * curve.period;
169
169
  const a = sampleSkeleton(curve, sampleT);
170
- const tB =
171
- _morphStrategy === "normalized"
172
- ? (sampleT / curve.period) * morphCurveB.period
173
- : sampleT;
170
+ const tB = _morphStrategy === "normalized" ? sampleT / curve.period * morphCurveB.period : sampleT;
174
171
  const b = sampleSkeleton(morphCurveB, tB);
175
172
  points[i] = {
176
173
  x: a.x + (b.x - a.x) * _morphAlpha,
177
- y: a.y + (b.y - a.y) * _morphAlpha,
174
+ y: a.y + (b.y - a.y) * _morphAlpha
178
175
  };
179
176
  }
180
177
  return points;
181
178
  }
182
179
  for (let i = 0; i < steps; i++) {
183
- const sampleT = (i / (steps - 1)) * curve.period;
180
+ const sampleT = i / (steps - 1) * curve.period;
184
181
  points[i] = sampleSkeleton(curve, sampleT);
185
182
  }
186
183
  return points;
187
- },
184
+ }
188
185
  };
189
186
  }
190
187
 
@@ -204,7 +201,7 @@ var GLOW_INNER_EDGE = 0.4;
204
201
  var GLOW_FALLOFF_OPACITY = 0.53;
205
202
  function hexToRgbComponents(hex) {
206
203
  const n = parseInt(hex.slice(1), 16);
207
- return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
204
+ return `${n >> 16},${n >> 8 & 255},${n & 255}`;
208
205
  }
209
206
  function createRenderer(options) {
210
207
  const canvas = options.canvas;
@@ -218,7 +215,7 @@ function createRenderer(options) {
218
215
  trailColor: options.trailColor ?? "#ffffff",
219
216
  headColor: options.headColor ?? "#ffffff",
220
217
  headRadius: options.headRadius ?? DEFAULT_HEAD_RADIUS,
221
- glowSize: options.glowSize ?? DEFAULT_GLOW_SIZE,
218
+ glowSize: options.glowSize ?? DEFAULT_GLOW_SIZE
222
219
  };
223
220
  const trailRgb = hexToRgbComponents(opts.trailColor);
224
221
  const headRgbFalloff = `rgba(${hexToRgbComponents(opts.headColor)},${GLOW_FALLOFF_OPACITY})`;
@@ -234,32 +231,16 @@ function createRenderer(options) {
234
231
  let lastTime = 0;
235
232
  let morphResolve = null;
236
233
  let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
237
- let morphTarget = null;
238
234
  let morphAlpha = 0;
239
- let skeletonCanvasA = null;
240
- let skeletonCanvasB = null;
241
- function calculateBoundaries() {
242
- if (skeleton.length === 0) {
243
- return;
244
- }
245
- const first = skeleton[0];
246
- let minX = first.x,
247
- maxX = first.x,
248
- minY = first.y,
249
- maxY = first.y;
250
- for (const p of skeleton) {
251
- if (p.x < minX) {
252
- minX = p.x;
253
- }
254
- if (p.x > maxX) {
255
- maxX = p.x;
256
- }
257
- if (p.y < minY) {
258
- minY = p.y;
259
- }
260
- if (p.y > maxY) {
261
- maxY = p.y;
262
- }
235
+ function computeBoundaries(pts) {
236
+ if (pts.length === 0) return null;
237
+ const first = pts[0];
238
+ let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
239
+ for (const p of pts) {
240
+ if (p.x < minX) minX = p.x;
241
+ if (p.x > maxX) maxX = p.x;
242
+ if (p.y < minY) minY = p.y;
243
+ if (p.y > maxY) maxY = p.y;
263
244
  }
264
245
  const width = maxX - minX;
265
246
  const height = maxY - minY;
@@ -267,11 +248,22 @@ function createRenderer(options) {
267
248
  const canvasHeight = canvas.height;
268
249
  const scaleX = canvasWidth / (width * (1 + FIT_PADDING * 2));
269
250
  const scaleY = canvasHeight / (height * (1 + FIT_PADDING * 2));
270
- scale = Math.min(scaleX, scaleY);
271
- const boundsWidth = width * scale;
272
- const boundsHeight = height * scale;
273
- offsetX = (canvasWidth - boundsWidth) / 2 - minX * scale;
274
- offsetY = (canvasHeight - boundsHeight) / 2 - minY * scale;
251
+ const s = Math.min(scaleX, scaleY);
252
+ const boundsWidth = width * s;
253
+ const boundsHeight = height * s;
254
+ return {
255
+ scale: s,
256
+ offsetX: (canvasWidth - boundsWidth) / 2 - minX * s,
257
+ offsetY: (canvasHeight - boundsHeight) / 2 - minY * s
258
+ };
259
+ }
260
+ function calculateBoundaries() {
261
+ const b = computeBoundaries(skeleton);
262
+ if (b) {
263
+ scale = b.scale;
264
+ offsetX = b.offsetX;
265
+ offsetY = b.offsetY;
266
+ }
275
267
  }
276
268
  function buildSkeletonCanvas() {
277
269
  if (skeleton.length < 2) return;
@@ -288,20 +280,23 @@ function createRenderer(options) {
288
280
  }
289
281
  skeletonCtx.stroke();
290
282
  }
283
+ function drawSkeletonPath(pts, opacity) {
284
+ if (pts.length < 2) return;
285
+ ctx.strokeStyle = `rgba(${hexToRgbComponents(opts.skeletonColor)},${opacity})`;
286
+ ctx.lineWidth = 1.5;
287
+ ctx.beginPath();
288
+ ctx.moveTo(pts[0].x * scale + offsetX, pts[0].y * scale + offsetY);
289
+ for (let i = 1; i < pts.length; i++) {
290
+ ctx.lineTo(pts[i].x * scale + offsetX, pts[i].y * scale + offsetY);
291
+ }
292
+ ctx.stroke();
293
+ }
291
294
  function drawSkeleton() {
292
295
  if (opts.skeletonColor === "transparent") {
293
296
  return;
294
297
  }
295
298
  if (engine.morphAlpha !== null) {
296
- if (skeletonCanvasA) {
297
- ctx.globalAlpha = (1 - morphAlpha) * DEFAULT_SKELETON_OPACITY;
298
- ctx.drawImage(skeletonCanvasA, 0, 0);
299
- }
300
- if (skeletonCanvasB) {
301
- ctx.globalAlpha = morphAlpha * DEFAULT_SKELETON_OPACITY;
302
- ctx.drawImage(skeletonCanvasB, 0, 0);
303
- }
304
- ctx.globalAlpha = 1;
299
+ drawSkeletonPath(engine.getSarmalSkeleton(), DEFAULT_SKELETON_OPACITY);
305
300
  return;
306
301
  }
307
302
  if (engine.isLiveSkeleton) {
@@ -373,23 +368,29 @@ function createRenderer(options) {
373
368
  if (engine.morphAlpha !== null) {
374
369
  morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1e3));
375
370
  engine.setMorphAlpha(morphAlpha);
376
- skeleton = engine.getSarmalSkeleton();
377
- calculateBoundaries();
371
+ const interpolatedSkeleton = engine.getSarmalSkeleton();
372
+ const bounds = computeBoundaries(interpolatedSkeleton);
373
+ if (bounds) {
374
+ scale = bounds.scale;
375
+ offsetX = bounds.offsetX;
376
+ offsetY = bounds.offsetY;
377
+ }
378
378
  if (morphAlpha >= 1) {
379
379
  engine.completeMorph();
380
380
  morphResolve?.();
381
381
  morphResolve = null;
382
- morphTarget = null;
383
382
  morphAlpha = 0;
384
- skeletonCanvasA = null;
385
- skeletonCanvasB = null;
383
+ skeleton = engine.getSarmalSkeleton();
384
+ if (!engine.isLiveSkeleton) {
385
+ buildSkeletonCanvas();
386
+ }
386
387
  }
387
388
  }
388
389
  trail = engine.tick(deltaTime);
389
390
  trailCount = engine.trailCount;
390
391
  head = trailCount > 0 ? trail[trailCount - 1] : null;
391
392
  ctx.clearRect(0, 0, canvas.width, canvas.height);
392
- if (engine.isLiveSkeleton || engine.morphAlpha !== null) {
393
+ if (engine.isLiveSkeleton && engine.morphAlpha === null) {
393
394
  skeleton = engine.getSarmalSkeleton();
394
395
  calculateBoundaries();
395
396
  }
@@ -441,49 +442,14 @@ function createRenderer(options) {
441
442
  morphResolve();
442
443
  morphResolve = null;
443
444
  morphAlpha = 0;
444
- skeletonCanvasA = null;
445
- skeletonCanvasB = null;
446
445
  }
447
446
  morphDurationMs = options2?.duration ?? DEFAULT_MORPH_DURATION_MS;
448
- morphTarget = target;
449
447
  morphAlpha = 0;
450
- const currentSkeleton = engine.getSarmalSkeleton();
451
- if (currentSkeleton.length >= 2) {
452
- skeletonCanvasA = new OffscreenCanvas(canvas.width, canvas.height);
453
- const ctxA = skeletonCanvasA.getContext("2d");
454
- ctxA.strokeStyle = `rgba(${hexToRgbComponents(opts.skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
455
- ctxA.lineWidth = 1.5;
456
- ctxA.beginPath();
457
- const first = currentSkeleton[0];
458
- ctxA.moveTo(first.x * scale + offsetX, first.y * scale + offsetY);
459
- for (let i = 1; i < currentSkeleton.length; i++) {
460
- const p = currentSkeleton[i];
461
- ctxA.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);
462
- }
463
- ctxA.stroke();
464
- }
465
448
  engine.startMorph(target, options2?.morphStrategy);
466
- if (morphTarget && !engine.isLiveSkeleton) {
467
- skeletonCanvasB = new OffscreenCanvas(canvas.width, canvas.height);
468
- const skeletonCtx = skeletonCanvasB.getContext("2d");
469
- skeletonCtx.strokeStyle = `rgba(${hexToRgbComponents(opts.skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
470
- skeletonCtx.lineWidth = 1.5;
471
- skeletonCtx.beginPath();
472
- const period = morphTarget.period ?? Math.PI * 2;
473
- const samples = Math.max(50, Math.round(period * 20));
474
- const firstB = morphTarget.fn(0, 0, {});
475
- skeletonCtx.moveTo(firstB.x * scale + offsetX, firstB.y * scale + offsetY);
476
- for (let i = 1; i <= samples; i++) {
477
- const t = (i / samples) * period;
478
- const p = morphTarget.fn(t, 0, {});
479
- skeletonCtx.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);
480
- }
481
- skeletonCtx.stroke();
482
- }
483
449
  return new Promise((resolve) => {
484
450
  morphResolve = resolve;
485
451
  });
486
- },
452
+ }
487
453
  };
488
454
  }
489
455
 
@@ -510,7 +476,7 @@ function createSVGRenderer(options) {
510
476
  headColor: options.headColor ?? "#ffffff",
511
477
  headRadius: options.headRadius ?? 4,
512
478
  glowSize: options.glowSize ?? 20,
513
- ariaLabel: options.ariaLabel ?? "Loading",
479
+ ariaLabel: options.ariaLabel ?? "Loading"
514
480
  };
515
481
  const uid = ++instanceCount;
516
482
  const gradientId = `sarmal-glow-${uid}`;
@@ -594,10 +560,7 @@ function createSVGRenderer(options) {
594
560
  return;
595
561
  }
596
562
  const first = skeleton2[0];
597
- let minX = first.x,
598
- maxX = first.x,
599
- minY = first.y,
600
- maxY = first.y;
563
+ let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
601
564
  for (const p of skeleton2) {
602
565
  if (p.x < minX) {
603
566
  minX = p.x;
@@ -684,8 +647,7 @@ function createSVGRenderer(options) {
684
647
  }
685
648
  let animationId = null;
686
649
  let lastTime = 0;
687
- const prefersReducedMotion =
688
- typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
650
+ const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
689
651
  let morphResolve = null;
690
652
  let morphDurationMs = DEFAULT_MORPH_DURATION_MS2;
691
653
  let morphTarget = null;
@@ -695,7 +657,7 @@ function createSVGRenderer(options) {
695
657
  const samples = Math.max(50, Math.round(period * 20));
696
658
  const points = [];
697
659
  for (let i = 0; i <= samples; i++) {
698
- const t = (i / samples) * period;
660
+ const t = i / samples * period;
699
661
  const p = target.fn(t, 0, {});
700
662
  points.push(p);
701
663
  }
@@ -718,26 +680,18 @@ function createSVGRenderer(options) {
718
680
  if (engine.morphAlpha !== null) {
719
681
  morphAlpha = Math.min(1, morphAlpha + dt / (morphDurationMs / 1e3));
720
682
  engine.setMorphAlpha(morphAlpha);
721
- const morphSkeleton = engine.getSarmalSkeleton();
722
- calculateBoundaries(morphSkeleton);
723
- if (!engine.isLiveSkeleton) {
724
- updateSkeleton(morphSkeleton);
725
- }
726
683
  if (morphPathABuilt) {
727
684
  skeletonPathA.setAttribute("d", morphPathABuilt);
728
685
  skeletonPathA.setAttribute("visibility", "visible");
729
686
  skeletonPathA.setAttribute(
730
687
  "stroke-opacity",
731
- String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY2),
688
+ String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY2)
732
689
  );
733
690
  }
734
691
  if (morphPathBBuilt) {
735
692
  skeletonPathB.setAttribute("d", morphPathBBuilt);
736
693
  skeletonPathB.setAttribute("visibility", "visible");
737
- skeletonPathB.setAttribute(
738
- "stroke-opacity",
739
- String(morphAlpha * DEFAULT_SKELETON_OPACITY2),
740
- );
694
+ skeletonPathB.setAttribute("stroke-opacity", String(morphAlpha * DEFAULT_SKELETON_OPACITY2));
741
695
  }
742
696
  if (morphAlpha >= 1) {
743
697
  engine.completeMorph();
@@ -749,11 +703,14 @@ function createSVGRenderer(options) {
749
703
  morphPathBBuilt = "";
750
704
  skeletonPathA.setAttribute("visibility", "hidden");
751
705
  skeletonPathB.setAttribute("visibility", "hidden");
706
+ const newSkeleton = engine.getSarmalSkeleton();
707
+ calculateBoundaries(newSkeleton);
708
+ updateSkeleton(newSkeleton);
752
709
  }
753
710
  }
754
711
  const trail = engine.tick(dt);
755
712
  const trailCount = engine.trailCount;
756
- if (engine.isLiveSkeleton) {
713
+ if (engine.isLiveSkeleton && engine.morphAlpha === null) {
757
714
  const liveSkeleton = engine.getSarmalSkeleton();
758
715
  calculateBoundaries(liveSkeleton);
759
716
  updateSkeleton(liveSkeleton);
@@ -826,7 +783,7 @@ function createSVGRenderer(options) {
826
783
  return new Promise((resolve) => {
827
784
  morphResolve = resolve;
828
785
  });
829
- },
786
+ }
830
787
  };
831
788
  }
832
789
  function createSarmalSVG(container, curveDef, options) {
@@ -838,29 +795,26 @@ function createSarmalSVG(container, curveDef, options) {
838
795
  // src/curves.ts
839
796
  var TWO_PI2 = Math.PI * 2;
840
797
  function artemis2(t, _time, _params) {
841
- const a = 0.35,
842
- b = 0.15,
843
- ox = 0.175;
844
- const s = Math.sin(t),
845
- c = Math.cos(t);
798
+ const a = 0.35, b = 0.15, ox = 0.175;
799
+ const s = Math.sin(t), c = Math.cos(t);
846
800
  const denom = 1 + s * s;
847
801
  return {
848
- x: (c * (1 + a * c)) / denom - ox,
849
- y: (s * c * (1 + b * c)) / denom,
802
+ x: c * (1 + a * c) / denom - ox,
803
+ y: s * c * (1 + b * c) / denom
850
804
  };
851
805
  }
852
806
  function epitrochoid7(t, _time, _params) {
853
807
  const d = 1 + 0.55 * Math.sin(t * 0.5);
854
808
  return {
855
809
  x: 7 * Math.cos(t) - d * Math.cos(7 * t),
856
- y: 7 * Math.sin(t) - d * Math.sin(7 * t),
810
+ y: 7 * Math.sin(t) - d * Math.sin(7 * t)
857
811
  };
858
812
  }
859
813
  function epitrochoid7Skeleton(t) {
860
814
  const d = 1.275;
861
815
  return {
862
816
  x: 7 * Math.cos(t) - d * Math.cos(7 * t),
863
- y: 7 * Math.sin(t) - d * Math.sin(7 * t),
817
+ y: 7 * Math.sin(t) - d * Math.sin(7 * t)
864
818
  };
865
819
  }
866
820
  function astroid(t, _time, _params) {
@@ -868,56 +822,55 @@ function astroid(t, _time, _params) {
868
822
  const s = Math.sin(t);
869
823
  return {
870
824
  x: c * c * c,
871
- y: s * s * s,
825
+ y: s * s * s
872
826
  };
873
827
  }
874
828
  function deltoid(t, _time, _params) {
875
829
  return {
876
830
  x: 2 * Math.cos(t) + Math.cos(2 * t),
877
- y: 2 * Math.sin(t) - Math.sin(2 * t),
831
+ y: 2 * Math.sin(t) - Math.sin(2 * t)
878
832
  };
879
833
  }
880
834
  function rose5(t, _time, _params) {
881
835
  const r = Math.cos(5 * t);
882
836
  return {
883
837
  x: r * Math.cos(t),
884
- y: r * Math.sin(t),
838
+ y: r * Math.sin(t)
885
839
  };
886
840
  }
887
841
  function rose3(t, _time, _params) {
888
842
  const r = Math.cos(3 * t);
889
843
  return {
890
844
  x: r * Math.cos(t),
891
- y: r * Math.sin(t),
845
+ y: r * Math.sin(t)
892
846
  };
893
847
  }
894
848
  function lissajous32(t, time, _params) {
895
849
  const phi = time * 0.45;
896
850
  return {
897
851
  x: Math.sin(3 * t + phi),
898
- y: Math.sin(2 * t),
852
+ y: Math.sin(2 * t)
899
853
  };
900
854
  }
901
855
  function lissajous43(t, time, _params) {
902
856
  const phi = time * 0.38;
903
857
  return {
904
858
  x: Math.sin(4 * t + phi),
905
- y: Math.sin(3 * t),
859
+ y: Math.sin(3 * t)
906
860
  };
907
861
  }
908
862
  function epicycloid3(t, _time, _params) {
909
863
  return {
910
864
  x: 4 * Math.cos(t) - Math.cos(4 * t),
911
- y: 4 * Math.sin(t) - Math.sin(4 * t),
865
+ y: 4 * Math.sin(t) - Math.sin(4 * t)
912
866
  };
913
867
  }
914
868
  function lame(t, time, _params) {
915
869
  const p = 1.75 + 1.25 * Math.sin(time * 0.48);
916
- const c = Math.cos(t),
917
- s = Math.sin(t);
870
+ const c = Math.cos(t), s = Math.sin(t);
918
871
  return {
919
872
  x: Math.sign(c) * Math.pow(Math.abs(c), p),
920
- y: Math.sign(s) * Math.pow(Math.abs(s), p),
873
+ y: Math.sign(s) * Math.pow(Math.abs(s), p)
921
874
  };
922
875
  }
923
876
  var curves = {
@@ -925,66 +878,66 @@ var curves = {
925
878
  name: "Artemis II",
926
879
  fn: artemis2,
927
880
  period: TWO_PI2,
928
- speed: 0.7,
881
+ speed: 0.7
929
882
  },
930
883
  epitrochoid7: {
931
884
  name: "Epitrochoid",
932
885
  fn: epitrochoid7,
933
886
  period: TWO_PI2,
934
887
  speed: 1.4,
935
- skeletonFn: epitrochoid7Skeleton,
888
+ skeletonFn: epitrochoid7Skeleton
936
889
  },
937
890
  astroid: {
938
891
  name: "Astroid",
939
892
  fn: astroid,
940
893
  period: TWO_PI2,
941
- speed: 1.1,
894
+ speed: 1.1
942
895
  },
943
896
  deltoid: {
944
897
  name: "Deltoid",
945
898
  fn: deltoid,
946
899
  period: TWO_PI2,
947
- speed: 0.9,
900
+ speed: 0.9
948
901
  },
949
902
  rose5: {
950
903
  name: "Rose (n=5)",
951
904
  fn: rose5,
952
905
  period: TWO_PI2,
953
- speed: 1,
906
+ speed: 1
954
907
  },
955
908
  rose3: {
956
909
  name: "Rose (n=3)",
957
910
  fn: rose3,
958
911
  period: TWO_PI2,
959
- speed: 1.15,
912
+ speed: 1.15
960
913
  },
961
914
  lissajous32: {
962
915
  name: "Lissajous 3:2",
963
916
  fn: lissajous32,
964
917
  period: TWO_PI2,
965
918
  speed: 2,
966
- skeleton: "live",
919
+ skeleton: "live"
967
920
  },
968
921
  lissajous43: {
969
922
  name: "Lissajous 4:3",
970
923
  fn: lissajous43,
971
924
  period: TWO_PI2,
972
925
  speed: 1.8,
973
- skeleton: "live",
926
+ skeleton: "live"
974
927
  },
975
928
  epicycloid3: {
976
929
  name: "Epicycloid (n=3)",
977
930
  fn: epicycloid3,
978
931
  period: TWO_PI2,
979
- speed: 0.75,
932
+ speed: 0.75
980
933
  },
981
934
  lame: {
982
935
  name: "Lam\xE9 Curve",
983
936
  fn: lame,
984
937
  period: TWO_PI2,
985
938
  speed: 1,
986
- skeleton: "live",
987
- },
939
+ skeleton: "live"
940
+ }
988
941
  };
989
942
 
990
943
  // src/index.ts
@@ -1001,4 +954,4 @@ exports.createSarmal = createSarmal;
1001
954
  exports.createSarmalSVG = createSarmalSVG;
1002
955
  exports.curves = curves;
1003
956
  //# sourceMappingURL=index.cjs.map
1004
- //# sourceMappingURL=index.cjs.map
957
+ //# sourceMappingURL=index.cjs.map