@sarmal/core 0.8.0 → 0.9.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.
Files changed (81) hide show
  1. package/dist/auto-init.cjs +209 -103
  2. package/dist/auto-init.cjs.map +1 -1
  3. package/dist/auto-init.d.cts +1 -0
  4. package/dist/auto-init.d.ts +1 -0
  5. package/dist/auto-init.js +209 -103
  6. package/dist/auto-init.js.map +1 -1
  7. package/dist/curves/artemis2.cjs +26 -0
  8. package/dist/curves/artemis2.cjs.map +1 -0
  9. package/dist/curves/artemis2.d.cts +9 -0
  10. package/dist/curves/artemis2.d.ts +9 -0
  11. package/dist/curves/artemis2.js +24 -0
  12. package/dist/curves/artemis2.js.map +1 -0
  13. package/dist/curves/astroid.cjs +22 -0
  14. package/dist/curves/astroid.cjs.map +1 -0
  15. package/dist/curves/astroid.d.cts +9 -0
  16. package/dist/curves/astroid.d.ts +9 -0
  17. package/dist/curves/astroid.js +20 -0
  18. package/dist/curves/astroid.js.map +1 -0
  19. package/dist/curves/deltoid.cjs +20 -0
  20. package/dist/curves/deltoid.cjs.map +1 -0
  21. package/dist/curves/deltoid.d.cts +9 -0
  22. package/dist/curves/deltoid.d.ts +9 -0
  23. package/dist/curves/deltoid.js +18 -0
  24. package/dist/curves/deltoid.js.map +1 -0
  25. package/dist/curves/epicycloid3.cjs +20 -0
  26. package/dist/curves/epicycloid3.cjs.map +1 -0
  27. package/dist/curves/epicycloid3.d.cts +9 -0
  28. package/dist/curves/epicycloid3.d.ts +9 -0
  29. package/dist/curves/epicycloid3.js +18 -0
  30. package/dist/curves/epicycloid3.js.map +1 -0
  31. package/dist/curves/epitrochoid7.cjs +29 -0
  32. package/dist/curves/epitrochoid7.cjs.map +1 -0
  33. package/dist/curves/epitrochoid7.d.cts +9 -0
  34. package/dist/curves/epitrochoid7.d.ts +9 -0
  35. package/dist/curves/epitrochoid7.js +27 -0
  36. package/dist/curves/epitrochoid7.js.map +1 -0
  37. package/dist/curves/index.cjs +206 -0
  38. package/dist/curves/index.cjs.map +1 -0
  39. package/dist/curves/index.d.cts +19 -0
  40. package/dist/curves/index.d.ts +19 -0
  41. package/dist/curves/index.js +206 -0
  42. package/dist/curves/index.js.map +1 -0
  43. package/dist/curves/lame.cjs +24 -0
  44. package/dist/curves/lame.cjs.map +1 -0
  45. package/dist/curves/lame.d.cts +9 -0
  46. package/dist/curves/lame.d.ts +9 -0
  47. package/dist/curves/lame.js +22 -0
  48. package/dist/curves/lame.js.map +1 -0
  49. package/dist/curves/lissajous32.cjs +22 -0
  50. package/dist/curves/lissajous32.cjs.map +1 -0
  51. package/dist/curves/lissajous32.d.cts +9 -0
  52. package/dist/curves/lissajous32.d.ts +9 -0
  53. package/dist/curves/lissajous32.js +20 -0
  54. package/dist/curves/lissajous32.js.map +1 -0
  55. package/dist/curves/lissajous43.cjs +22 -0
  56. package/dist/curves/lissajous43.cjs.map +1 -0
  57. package/dist/curves/lissajous43.d.cts +9 -0
  58. package/dist/curves/lissajous43.d.ts +9 -0
  59. package/dist/curves/lissajous43.js +20 -0
  60. package/dist/curves/lissajous43.js.map +1 -0
  61. package/dist/curves/rose3.cjs +21 -0
  62. package/dist/curves/rose3.cjs.map +1 -0
  63. package/dist/curves/rose3.d.cts +9 -0
  64. package/dist/curves/rose3.d.ts +9 -0
  65. package/dist/curves/rose3.js +19 -0
  66. package/dist/curves/rose3.js.map +1 -0
  67. package/dist/curves/rose5.cjs +21 -0
  68. package/dist/curves/rose5.cjs.map +1 -0
  69. package/dist/curves/rose5.d.cts +9 -0
  70. package/dist/curves/rose5.d.ts +9 -0
  71. package/dist/curves/rose5.js +19 -0
  72. package/dist/curves/rose5.js.map +1 -0
  73. package/dist/index.cjs +214 -106
  74. package/dist/index.cjs.map +1 -1
  75. package/dist/index.d.cts +105 -0
  76. package/dist/index.d.ts +105 -0
  77. package/dist/index.js +222 -107
  78. package/dist/index.js.map +1 -1
  79. package/dist/types-DX8VfIVK.d.cts +226 -0
  80. package/dist/types-DX8VfIVK.d.ts +226 -0
  81. package/package.json +11 -1
@@ -201,6 +201,47 @@ var TRAIL_FADE_CURVE = 1.5;
201
201
  var TRAIL_MAX_OPACITY = 0.88;
202
202
  var TRAIL_MIN_WIDTH = 0.5;
203
203
  var TRAIL_MAX_WIDTH = 2.5;
204
+ var GRADIENT = {
205
+ bard: ["#a855f7", "#3b82f6", "#14b8a6", "#ec4899"],
206
+ sunset: ["#f97316", "#dc2626", "#9333ea", "#f472b6"],
207
+ ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
208
+ ice: ["#1e3a8a", "#67e8f9"],
209
+ fire: ["#7f1d1d", "#fbbf24"],
210
+ forest: ["#14532d", "#86efac"],
211
+ };
212
+ var PRESETS = {
213
+ bard: GRADIENT.bard,
214
+ sunset: GRADIENT.sunset,
215
+ ocean: GRADIENT.ocean,
216
+ ice: GRADIENT.ice,
217
+ fire: GRADIENT.fire,
218
+ forest: GRADIENT.forest,
219
+ };
220
+ function hexToRgb(hex) {
221
+ const n = parseInt(hex.slice(1), 16);
222
+ return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
223
+ }
224
+ var lerpRgb = (a, b, t) => ({
225
+ r: Math.round(a.r + (b.r - a.r) * t),
226
+ g: Math.round(a.g + (b.g - a.g) * t),
227
+ b: Math.round(a.b + (b.b - a.b) * t),
228
+ });
229
+ function getPaletteColor(palette, position, timeOffset = 0) {
230
+ if (palette.length === 0) return { r: 255, g: 255, b: 255 };
231
+ if (palette.length === 1) return hexToRgb(palette[0]);
232
+ const cyclePos = (position + timeOffset) % 1;
233
+ const scaled = cyclePos * palette.length;
234
+ const idx = Math.floor(scaled);
235
+ const t = scaled - idx;
236
+ const c1 = hexToRgb(palette[idx % palette.length]);
237
+ const c2 = hexToRgb(palette[(idx + 1) % palette.length]);
238
+ return lerpRgb(c1, c2, t);
239
+ }
240
+ function resolvePalette(palette, trailStyle) {
241
+ if (Array.isArray(palette)) return palette;
242
+ if (palette && palette in PRESETS) return PRESETS[palette];
243
+ return trailStyle === "gradient-animated" ? GRADIENT.bard : GRADIENT.ice;
244
+ }
204
245
  function hexToRgbComponents(hex) {
205
246
  const n = parseInt(hex.slice(1), 16);
206
247
  return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
@@ -250,6 +291,8 @@ function createRenderer(options) {
250
291
  headColor: options.headColor ?? "#ffffff",
251
292
  headRadius: options.headRadius ?? DEFAULT_HEAD_RADIUS,
252
293
  };
294
+ const trailStyle = options.trailStyle ?? "default";
295
+ const palette = resolvePalette(options.palette, trailStyle);
253
296
  const trailRgb = hexToRgbComponents(opts.trailColor);
254
297
  const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
255
298
  function setupCanvas() {
@@ -275,6 +318,7 @@ function createRenderer(options) {
275
318
  let morphResolve = null;
276
319
  let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
277
320
  let morphAlpha = 0;
321
+ let gradientAnimTime = 0;
278
322
  function computeBoundaries(pts) {
279
323
  if (pts.length === 0) return null;
280
324
  const first = pts[0];
@@ -386,7 +430,13 @@ function createRenderer(options) {
386
430
  const l1y = next.y * scale + offsetY + n1.y * halfW1;
387
431
  const r1x = next.x * scale + offsetX - n1.x * halfW1;
388
432
  const r1y = next.y * scale + offsetY - n1.y * halfW1;
389
- ctx.fillStyle = `rgba(${trailRgb},${alpha})`;
433
+ if (trailStyle === "default") {
434
+ ctx.fillStyle = `rgba(${trailRgb},${alpha})`;
435
+ } else {
436
+ const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
437
+ const color = getPaletteColor(palette, progress, timeOffset);
438
+ ctx.fillStyle = `rgba(${color.r},${color.g},${color.b},${alpha})`;
439
+ }
390
440
  ctx.beginPath();
391
441
  ctx.moveTo(l0x, l0y);
392
442
  ctx.lineTo(l1x, l1y);
@@ -411,6 +461,9 @@ function createRenderer(options) {
411
461
  const now = performance.now();
412
462
  const deltaTime = Math.min((now - lastTime) / 1e3, 1 / 30);
413
463
  lastTime = now;
464
+ if (trailStyle === "gradient-animated") {
465
+ gradientAnimTime += deltaTime * 1e3;
466
+ }
414
467
  if (engine.morphAlpha !== null) {
415
468
  morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1e3));
416
469
  engine.setMorphAlpha(morphAlpha);
@@ -499,9 +552,9 @@ function createRenderer(options) {
499
552
  };
500
553
  }
501
554
 
502
- // src/curves.ts
555
+ // src/curves/artemis2.ts
503
556
  var TWO_PI2 = Math.PI * 2;
504
- function artemis2(t, _time, _params) {
557
+ function artemis2Fn(t, _time, _params) {
505
558
  const a = 0.35,
506
559
  b = 0.15,
507
560
  ox = 0.175;
@@ -513,21 +566,16 @@ function artemis2(t, _time, _params) {
513
566
  y: (s * c * (1 + b * c)) / denom,
514
567
  };
515
568
  }
516
- function epitrochoid7(t, _time, _params) {
517
- const d = 1 + 0.55 * Math.sin(t * 0.5);
518
- return {
519
- x: 7 * Math.cos(t) - d * Math.cos(7 * t),
520
- y: 7 * Math.sin(t) - d * Math.sin(7 * t),
521
- };
522
- }
523
- function epitrochoid7Skeleton(t) {
524
- const d = 1.275;
525
- return {
526
- x: 7 * Math.cos(t) - d * Math.cos(7 * t),
527
- y: 7 * Math.sin(t) - d * Math.sin(7 * t),
528
- };
529
- }
530
- function astroid(t, _time, _params) {
569
+ var artemis2 = {
570
+ name: "Artemis II",
571
+ fn: artemis2Fn,
572
+ period: TWO_PI2,
573
+ speed: 0.7,
574
+ };
575
+
576
+ // src/curves/astroid.ts
577
+ var TWO_PI3 = Math.PI * 2;
578
+ function astroidFn(t, _time, _params) {
531
579
  const c = Math.cos(t);
532
580
  const s = Math.sin(t);
533
581
  return {
@@ -535,47 +583,104 @@ function astroid(t, _time, _params) {
535
583
  y: s * s * s,
536
584
  };
537
585
  }
538
- function deltoid(t, _time, _params) {
586
+ var astroid = {
587
+ name: "Astroid",
588
+ fn: astroidFn,
589
+ period: TWO_PI3,
590
+ speed: 1.1,
591
+ };
592
+
593
+ // src/curves/deltoid.ts
594
+ var TWO_PI4 = Math.PI * 2;
595
+ function deltoidFn(t, _time, _params) {
539
596
  return {
540
597
  x: 2 * Math.cos(t) + Math.cos(2 * t),
541
598
  y: 2 * Math.sin(t) - Math.sin(2 * t),
542
599
  };
543
600
  }
544
- function rose5(t, _time, _params) {
545
- const r = Math.cos(5 * t);
601
+ var deltoid = {
602
+ name: "Deltoid",
603
+ fn: deltoidFn,
604
+ period: TWO_PI4,
605
+ speed: 0.9,
606
+ };
607
+
608
+ // src/curves/epicycloid3.ts
609
+ var TWO_PI5 = Math.PI * 2;
610
+ function epicycloid3Fn(t, _time, _params) {
546
611
  return {
547
- x: r * Math.cos(t),
548
- y: r * Math.sin(t),
612
+ x: 4 * Math.cos(t) - Math.cos(4 * t),
613
+ y: 4 * Math.sin(t) - Math.sin(4 * t),
549
614
  };
550
615
  }
551
- function rose3(t, _time, _params) {
552
- const r = Math.cos(3 * t);
616
+ var epicycloid3 = {
617
+ name: "Epicycloid (n=3)",
618
+ fn: epicycloid3Fn,
619
+ period: TWO_PI5,
620
+ speed: 0.75,
621
+ };
622
+
623
+ // src/curves/epitrochoid7.ts
624
+ var TWO_PI6 = Math.PI * 2;
625
+ function epitrochoid7Fn(t, _time, _params) {
626
+ const d = 1 + 0.55 * Math.sin(t * 0.5);
553
627
  return {
554
- x: r * Math.cos(t),
555
- y: r * Math.sin(t),
628
+ x: 7 * Math.cos(t) - d * Math.cos(7 * t),
629
+ y: 7 * Math.sin(t) - d * Math.sin(7 * t),
630
+ };
631
+ }
632
+ function epitrochoid7SkeletonFn(t) {
633
+ const d = 1.275;
634
+ return {
635
+ x: 7 * Math.cos(t) - d * Math.cos(7 * t),
636
+ y: 7 * Math.sin(t) - d * Math.sin(7 * t),
556
637
  };
557
638
  }
558
- function lissajous32(t, time, _params) {
639
+ var epitrochoid7 = {
640
+ name: "Epitrochoid",
641
+ fn: epitrochoid7Fn,
642
+ period: TWO_PI6,
643
+ speed: 1.4,
644
+ skeletonFn: epitrochoid7SkeletonFn,
645
+ };
646
+
647
+ // src/curves/lissajous32.ts
648
+ var TWO_PI7 = Math.PI * 2;
649
+ function lissajous32Fn(t, time, _params) {
559
650
  const phi = time * 0.45;
560
651
  return {
561
652
  x: Math.sin(3 * t + phi),
562
653
  y: Math.sin(2 * t),
563
654
  };
564
655
  }
565
- function lissajous43(t, time, _params) {
656
+ var lissajous32 = {
657
+ name: "Lissajous 3:2",
658
+ fn: lissajous32Fn,
659
+ period: TWO_PI7,
660
+ speed: 2,
661
+ skeleton: "live",
662
+ };
663
+
664
+ // src/curves/lissajous43.ts
665
+ var TWO_PI8 = Math.PI * 2;
666
+ function lissajous43Fn(t, time, _params) {
566
667
  const phi = time * 0.38;
567
668
  return {
568
669
  x: Math.sin(4 * t + phi),
569
670
  y: Math.sin(3 * t),
570
671
  };
571
672
  }
572
- function epicycloid3(t, _time, _params) {
573
- return {
574
- x: 4 * Math.cos(t) - Math.cos(4 * t),
575
- y: 4 * Math.sin(t) - Math.sin(4 * t),
576
- };
577
- }
578
- function lame(t, time, _params) {
673
+ var lissajous43 = {
674
+ name: "Lissajous 4:3",
675
+ fn: lissajous43Fn,
676
+ period: TWO_PI8,
677
+ speed: 1.8,
678
+ skeleton: "live",
679
+ };
680
+
681
+ // src/curves/lame.ts
682
+ var TWO_PI9 = Math.PI * 2;
683
+ function lameFn(t, time, _params) {
579
684
  const p = 1.75 + 1.25 * Math.sin(time * 0.48);
580
685
  const c = Math.cos(t),
581
686
  s = Math.sin(t);
@@ -584,71 +689,58 @@ function lame(t, time, _params) {
584
689
  y: Math.sign(s) * Math.pow(Math.abs(s), p),
585
690
  };
586
691
  }
692
+ var lame = {
693
+ name: "Lam\xE9 Curve",
694
+ fn: lameFn,
695
+ period: TWO_PI9,
696
+ speed: 1,
697
+ skeleton: "live",
698
+ };
699
+
700
+ // src/curves/rose3.ts
701
+ var TWO_PI10 = Math.PI * 2;
702
+ function rose3Fn(t, _time, _params) {
703
+ const r = Math.cos(3 * t);
704
+ return {
705
+ x: r * Math.cos(t),
706
+ y: r * Math.sin(t),
707
+ };
708
+ }
709
+ var rose3 = {
710
+ name: "Rose (n=3)",
711
+ fn: rose3Fn,
712
+ period: TWO_PI10,
713
+ speed: 1.15,
714
+ };
715
+
716
+ // src/curves/rose5.ts
717
+ var TWO_PI11 = Math.PI * 2;
718
+ function rose5Fn(t, _time, _params) {
719
+ const r = Math.cos(5 * t);
720
+ return {
721
+ x: r * Math.cos(t),
722
+ y: r * Math.sin(t),
723
+ };
724
+ }
725
+ var rose5 = {
726
+ name: "Rose (n=5)",
727
+ fn: rose5Fn,
728
+ period: TWO_PI11,
729
+ speed: 1,
730
+ };
731
+
732
+ // src/curves/index.ts
587
733
  var curves = {
588
- artemis2: {
589
- name: "Artemis II",
590
- fn: artemis2,
591
- period: TWO_PI2,
592
- speed: 0.7,
593
- },
594
- epitrochoid7: {
595
- name: "Epitrochoid",
596
- fn: epitrochoid7,
597
- period: TWO_PI2,
598
- speed: 1.4,
599
- skeletonFn: epitrochoid7Skeleton,
600
- },
601
- astroid: {
602
- name: "Astroid",
603
- fn: astroid,
604
- period: TWO_PI2,
605
- speed: 1.1,
606
- },
607
- deltoid: {
608
- name: "Deltoid",
609
- fn: deltoid,
610
- period: TWO_PI2,
611
- speed: 0.9,
612
- },
613
- rose5: {
614
- name: "Rose (n=5)",
615
- fn: rose5,
616
- period: TWO_PI2,
617
- speed: 1,
618
- },
619
- rose3: {
620
- name: "Rose (n=3)",
621
- fn: rose3,
622
- period: TWO_PI2,
623
- speed: 1.15,
624
- },
625
- lissajous32: {
626
- name: "Lissajous 3:2",
627
- fn: lissajous32,
628
- period: TWO_PI2,
629
- speed: 2,
630
- skeleton: "live",
631
- },
632
- lissajous43: {
633
- name: "Lissajous 4:3",
634
- fn: lissajous43,
635
- period: TWO_PI2,
636
- speed: 1.8,
637
- skeleton: "live",
638
- },
639
- epicycloid3: {
640
- name: "Epicycloid (n=3)",
641
- fn: epicycloid3,
642
- period: TWO_PI2,
643
- speed: 0.75,
644
- },
645
- lame: {
646
- name: "Lam\xE9 Curve",
647
- fn: lame,
648
- period: TWO_PI2,
649
- speed: 1,
650
- skeleton: "live",
651
- },
734
+ artemis2,
735
+ epitrochoid7,
736
+ astroid,
737
+ deltoid,
738
+ rose5,
739
+ rose3,
740
+ lissajous32,
741
+ lissajous43,
742
+ epicycloid3,
743
+ lame,
652
744
  };
653
745
 
654
746
  // src/index.ts
@@ -659,6 +751,15 @@ function createSarmal(canvas, curveDef, options) {
659
751
  }
660
752
 
661
753
  // src/auto-init.ts
754
+ function parsePalette(value) {
755
+ try {
756
+ const parsed = JSON.parse(value);
757
+ if (Array.isArray(parsed)) {
758
+ return parsed;
759
+ }
760
+ } catch {}
761
+ return value;
762
+ }
662
763
  function init() {
663
764
  const canvases = document.querySelectorAll("canvas[data-sarmal]");
664
765
  canvases.forEach((canvas) => {
@@ -675,16 +776,21 @@ function init() {
675
776
  ...(canvas.dataset.skeletonColor && { skeletonColor: canvas.dataset.skeletonColor }),
676
777
  ...(canvas.dataset.headColor && { headColor: canvas.dataset.headColor }),
677
778
  ...(canvas.dataset.headRadius && { headRadius: parseFloat(canvas.dataset.headRadius) }),
678
- ...(canvas.dataset.glowSize && { glowSize: parseInt(canvas.dataset.glowSize, 10) }),
679
779
  ...(canvas.dataset.trailLength && { trailLength: parseInt(canvas.dataset.trailLength, 10) }),
780
+ ...(canvas.dataset.trailStyle && {
781
+ trailStyle: canvas.dataset.trailStyle,
782
+ }),
783
+ ...(canvas.dataset.palette && { palette: parsePalette(canvas.dataset.palette) }),
680
784
  });
681
785
  sarmal.start();
682
786
  });
683
787
  }
684
788
  if (document.readyState === "loading") {
685
- document.addEventListener("DOMContentLoaded", init);
789
+ document.addEventListener("DOMContentLoaded", () => {
790
+ requestAnimationFrame(init);
791
+ });
686
792
  } else {
687
- init();
793
+ requestAnimationFrame(init);
688
794
  }
689
795
  //# sourceMappingURL=auto-init.cjs.map
690
796
  //# sourceMappingURL=auto-init.cjs.map