@sarmal/core 0.30.0 → 0.33.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/dist/auto-init.cjs +115 -31
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +115 -31
- package/dist/auto-init.js.map +1 -1
- package/dist/cli.js +8 -7
- package/dist/cli.js.map +1 -1
- package/dist/curves/artemis2.d.cts +1 -1
- package/dist/curves/artemis2.d.ts +1 -1
- package/dist/curves/astroid.d.cts +1 -1
- package/dist/curves/astroid.d.ts +1 -1
- package/dist/curves/deltoid.d.cts +1 -1
- package/dist/curves/deltoid.d.ts +1 -1
- package/dist/curves/epicycloid3.d.cts +1 -1
- package/dist/curves/epicycloid3.d.ts +1 -1
- package/dist/curves/epitrochoid7.d.cts +1 -1
- package/dist/curves/epitrochoid7.d.ts +1 -1
- package/dist/curves/index.d.cts +1 -1
- package/dist/curves/index.d.ts +1 -1
- package/dist/curves/lame.d.cts +1 -1
- package/dist/curves/lame.d.ts +1 -1
- package/dist/curves/lissajous32.d.cts +1 -1
- package/dist/curves/lissajous32.d.ts +1 -1
- package/dist/curves/lissajous43.d.cts +1 -1
- package/dist/curves/lissajous43.d.ts +1 -1
- package/dist/curves/rose3.d.cts +1 -1
- package/dist/curves/rose3.d.ts +1 -1
- package/dist/curves/rose5.d.cts +1 -1
- package/dist/curves/rose5.d.ts +1 -1
- package/dist/curves/rose52.d.cts +1 -1
- package/dist/curves/rose52.d.ts +1 -1
- package/dist/curves/star.d.cts +1 -1
- package/dist/curves/star.d.ts +1 -1
- package/dist/curves/star4.d.cts +1 -1
- package/dist/curves/star4.d.ts +1 -1
- package/dist/curves/star7.d.cts +1 -1
- package/dist/curves/star7.d.ts +1 -1
- package/dist/index.cjs +122 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +122 -34
- package/dist/index.js.map +1 -1
- package/dist/{renderer-shared-OR--cv-t.d.ts → renderer-shared-Bdca4O4G.d.ts} +8 -4
- package/dist/{renderer-shared-jqw_Q1WO.d.cts → renderer-shared-Ke9BeK1P.d.cts} +8 -4
- package/dist/terminal.cjs +8 -7
- package/dist/terminal.cjs.map +1 -1
- package/dist/terminal.d.cts +2 -2
- package/dist/terminal.d.ts +2 -2
- package/dist/terminal.js +8 -7
- package/dist/terminal.js.map +1 -1
- package/dist/{types-zbxUgcmZ.d.cts → types-BBuUk6nn.d.cts} +9 -0
- package/dist/{types-zbxUgcmZ.d.ts → types-BBuUk6nn.d.ts} +9 -0
- package/package.json +1 -1
package/dist/auto-init.js
CHANGED
|
@@ -404,6 +404,49 @@ function parseColorToRgb(s) {
|
|
|
404
404
|
}
|
|
405
405
|
return null;
|
|
406
406
|
}
|
|
407
|
+
var OKLCH_RE = /^oklch\(\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*[\d.]+)?\s*\)$/i;
|
|
408
|
+
function parseOklchToOklab(s) {
|
|
409
|
+
const m = OKLCH_RE.exec(s.trim());
|
|
410
|
+
if (!m) {
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
const L = parseFloat(m[1]);
|
|
414
|
+
const C = parseFloat(m[2]);
|
|
415
|
+
const H = parseFloat(m[3]);
|
|
416
|
+
if (Number.isNaN(L) || Number.isNaN(C) || Number.isNaN(H)) {
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
const clampedL = Math.max(0, Math.min(1, L));
|
|
420
|
+
const clampedC = Math.max(0, Math.min(0.4, C));
|
|
421
|
+
const H_rad = H * (Math.PI / 180);
|
|
422
|
+
return {
|
|
423
|
+
L: clampedL,
|
|
424
|
+
a: clampedC * Math.cos(H_rad),
|
|
425
|
+
b: clampedC * Math.sin(H_rad)
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
function parseColorToOklab(s) {
|
|
429
|
+
const oklab = parseOklchToOklab(s);
|
|
430
|
+
if (oklab !== null) {
|
|
431
|
+
return oklab;
|
|
432
|
+
}
|
|
433
|
+
const rgb = parseColorToRgb(s);
|
|
434
|
+
if (rgb === null) {
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
return rgbToOklab(rgb);
|
|
438
|
+
}
|
|
439
|
+
function colorToRgb(color) {
|
|
440
|
+
const rgb = parseColorToRgb(color);
|
|
441
|
+
if (rgb !== null) {
|
|
442
|
+
return rgb;
|
|
443
|
+
}
|
|
444
|
+
const lab = parseOklchToOklab(color);
|
|
445
|
+
if (lab !== null) {
|
|
446
|
+
return oklabToRgb(lab);
|
|
447
|
+
}
|
|
448
|
+
throw new Error(`[sarmal] unrecognized color "${color}"`);
|
|
449
|
+
}
|
|
407
450
|
function srgbByteToLinear(c) {
|
|
408
451
|
const n = c / 255;
|
|
409
452
|
return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
|
|
@@ -441,26 +484,25 @@ var lerpOklab = (a, b, t) => {
|
|
|
441
484
|
if (t >= 1) {
|
|
442
485
|
return b;
|
|
443
486
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
});
|
|
487
|
+
return {
|
|
488
|
+
L: a.L + (b.L - a.L) * t,
|
|
489
|
+
a: a.a + (b.a - a.a) * t,
|
|
490
|
+
b: a.b + (b.b - a.b) * t
|
|
491
|
+
};
|
|
450
492
|
};
|
|
451
493
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
452
494
|
if (palette.length === 0) {
|
|
453
|
-
return {
|
|
495
|
+
return { L: 1, a: 0, b: 0 };
|
|
454
496
|
}
|
|
455
497
|
if (palette.length === 1) {
|
|
456
|
-
return
|
|
498
|
+
return palette[0];
|
|
457
499
|
}
|
|
458
500
|
const cyclePos = ((position + timeOffset) % 1 + 1) % 1;
|
|
459
501
|
const scaled = cyclePos * palette.length;
|
|
460
502
|
const idx = Math.floor(scaled);
|
|
461
503
|
const t = scaled - idx;
|
|
462
|
-
const c1 =
|
|
463
|
-
const c2 =
|
|
504
|
+
const c1 = palette[idx % palette.length];
|
|
505
|
+
const c2 = palette[(idx + 1) % palette.length];
|
|
464
506
|
return lerpOklab(c1, c2, t);
|
|
465
507
|
}
|
|
466
508
|
var TRAIL_STYLES = ["default", "gradient-static", "gradient-animated"];
|
|
@@ -469,7 +511,8 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
|
469
511
|
"headColor",
|
|
470
512
|
"skeletonColor",
|
|
471
513
|
"trailStyle",
|
|
472
|
-
"headRadius"
|
|
514
|
+
"headRadius",
|
|
515
|
+
"trailWidth"
|
|
473
516
|
]);
|
|
474
517
|
function validateRenderOptions(partial) {
|
|
475
518
|
for (const key of Object.keys(partial)) {
|
|
@@ -492,12 +535,15 @@ function validateRenderOptions(partial) {
|
|
|
492
535
|
if (partial.headRadius !== void 0) {
|
|
493
536
|
assertHeadRadius(partial.headRadius);
|
|
494
537
|
}
|
|
538
|
+
if (partial.trailWidth !== void 0) {
|
|
539
|
+
assertTrailWidth(partial.trailWidth);
|
|
540
|
+
}
|
|
495
541
|
}
|
|
496
542
|
function assertTrailColor(value) {
|
|
497
543
|
if (typeof value === "string") {
|
|
498
|
-
if (
|
|
544
|
+
if (parseColorToOklab(value) === null) {
|
|
499
545
|
throw new TypeError(
|
|
500
|
-
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got "${value}"`
|
|
546
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got "${value}"`
|
|
501
547
|
);
|
|
502
548
|
}
|
|
503
549
|
return;
|
|
@@ -510,25 +556,25 @@ function assertTrailColor(value) {
|
|
|
510
556
|
}
|
|
511
557
|
for (let i = 0; i < value.length; i++) {
|
|
512
558
|
const entry = value[i];
|
|
513
|
-
if (typeof entry !== "string" ||
|
|
559
|
+
if (typeof entry !== "string" || parseColorToOklab(entry) === null) {
|
|
514
560
|
throw new TypeError(
|
|
515
|
-
`[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got ${JSON.stringify(entry)}`
|
|
561
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got ${JSON.stringify(entry)}`
|
|
516
562
|
);
|
|
517
563
|
}
|
|
518
564
|
}
|
|
519
565
|
return;
|
|
520
566
|
}
|
|
521
567
|
throw new TypeError(
|
|
522
|
-
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or an array of color strings, got ${JSON.stringify(value)}`
|
|
568
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or an array of color strings, got ${JSON.stringify(value)}`
|
|
523
569
|
);
|
|
524
570
|
}
|
|
525
571
|
function assertHeadColor(value) {
|
|
526
572
|
if (value === null) {
|
|
527
573
|
return;
|
|
528
574
|
}
|
|
529
|
-
if (typeof value !== "string" ||
|
|
575
|
+
if (typeof value !== "string" || parseColorToOklab(value) === null) {
|
|
530
576
|
throw new TypeError(
|
|
531
|
-
`[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or null, got ${JSON.stringify(value)}`
|
|
577
|
+
`[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or null, got ${JSON.stringify(value)}`
|
|
532
578
|
);
|
|
533
579
|
}
|
|
534
580
|
}
|
|
@@ -536,9 +582,9 @@ function assertSkeletonColor(value) {
|
|
|
536
582
|
if (value === "transparent") {
|
|
537
583
|
return;
|
|
538
584
|
}
|
|
539
|
-
if (typeof value !== "string" ||
|
|
585
|
+
if (typeof value !== "string" || parseColorToOklab(value) === null) {
|
|
540
586
|
throw new TypeError(
|
|
541
|
-
`[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or "transparent", got ${JSON.stringify(value)}`
|
|
587
|
+
`[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or "transparent", got ${JSON.stringify(value)}`
|
|
542
588
|
);
|
|
543
589
|
}
|
|
544
590
|
}
|
|
@@ -561,6 +607,18 @@ function assertHeadRadius(value) {
|
|
|
561
607
|
);
|
|
562
608
|
}
|
|
563
609
|
}
|
|
610
|
+
function assertTrailWidth(value) {
|
|
611
|
+
if (typeof value !== "number") {
|
|
612
|
+
throw new TypeError(
|
|
613
|
+
`[sarmal] setRenderOptions: trailWidth must be a number, got ${JSON.stringify(value)}`
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
617
|
+
throw new TypeError(
|
|
618
|
+
`[sarmal] setRenderOptions: trailWidth must be a finite positive number, got ${value}`
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
564
622
|
function resolveTrailMainColor(trailColor) {
|
|
565
623
|
return typeof trailColor === "string" ? trailColor : trailColor[0];
|
|
566
624
|
}
|
|
@@ -573,7 +631,7 @@ function resolveHeadColor(trailColor, trailStyle) {
|
|
|
573
631
|
}
|
|
574
632
|
const palette = resolveTrailPalette(trailColor);
|
|
575
633
|
const last = palette[palette.length - 1];
|
|
576
|
-
const { r, g, b } =
|
|
634
|
+
const { r, g, b } = colorToRgb(last);
|
|
577
635
|
return `rgb(${r},${g},${b})`;
|
|
578
636
|
}
|
|
579
637
|
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
@@ -594,8 +652,8 @@ function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
|
594
652
|
var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160));
|
|
595
653
|
var WHITE_HEX = "#ffffff";
|
|
596
654
|
function colorToRgbComponents(color) {
|
|
597
|
-
const
|
|
598
|
-
return `${
|
|
655
|
+
const { r, g, b } = colorToRgb(color);
|
|
656
|
+
return `${r},${g},${b}`;
|
|
599
657
|
}
|
|
600
658
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
601
659
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -617,6 +675,7 @@ function createRenderer(options) {
|
|
|
617
675
|
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
618
676
|
let trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
619
677
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
678
|
+
let trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
620
679
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
621
680
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
622
681
|
function setupCanvas() {
|
|
@@ -628,7 +687,14 @@ function createRenderer(options) {
|
|
|
628
687
|
setupCanvas();
|
|
629
688
|
let logicalWidth = canvas.width / dpr;
|
|
630
689
|
let logicalHeight = canvas.height / dpr;
|
|
690
|
+
if (options.headRadius !== void 0) {
|
|
691
|
+
validateRenderOptions({ headRadius: options.headRadius });
|
|
692
|
+
}
|
|
693
|
+
if (options.trailWidth !== void 0) {
|
|
694
|
+
validateRenderOptions({ trailWidth: options.trailWidth });
|
|
695
|
+
}
|
|
631
696
|
let headRadius = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);
|
|
697
|
+
let trailWidth = options.trailWidth ?? 1;
|
|
632
698
|
let skeleton = [];
|
|
633
699
|
let skeletonCanvas = null;
|
|
634
700
|
let trail = [];
|
|
@@ -722,14 +788,16 @@ function createRenderer(options) {
|
|
|
722
788
|
i,
|
|
723
789
|
trailCount,
|
|
724
790
|
toX,
|
|
725
|
-
toY
|
|
791
|
+
toY,
|
|
792
|
+
TRAIL_MIN_WIDTH * trailWidth,
|
|
793
|
+
TRAIL_MAX_WIDTH * trailWidth
|
|
726
794
|
);
|
|
727
795
|
if (trailStyle === "default") {
|
|
728
796
|
ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
|
|
729
797
|
} else {
|
|
730
798
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
731
|
-
const
|
|
732
|
-
ctx.fillStyle = `rgba(${
|
|
799
|
+
const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));
|
|
800
|
+
ctx.fillStyle = `rgba(${r},${g},${b},${opacity})`;
|
|
733
801
|
}
|
|
734
802
|
ctx.beginPath();
|
|
735
803
|
ctx.moveTo(l0x, l0y);
|
|
@@ -863,6 +931,7 @@ function createRenderer(options) {
|
|
|
863
931
|
trailColor = partial.trailColor;
|
|
864
932
|
trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
865
933
|
trailPalette = resolveTrailPalette(trailColor);
|
|
934
|
+
trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
866
935
|
}
|
|
867
936
|
if (partial.skeletonColor !== void 0) {
|
|
868
937
|
skeletonColor = partial.skeletonColor;
|
|
@@ -879,6 +948,9 @@ function createRenderer(options) {
|
|
|
879
948
|
if (partial.headRadius !== void 0) {
|
|
880
949
|
headRadius = partial.headRadius;
|
|
881
950
|
}
|
|
951
|
+
if (partial.trailWidth !== void 0) {
|
|
952
|
+
trailWidth = partial.trailWidth;
|
|
953
|
+
}
|
|
882
954
|
if (userHeadColor === null) {
|
|
883
955
|
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
884
956
|
} else {
|
|
@@ -946,8 +1018,8 @@ function el(tag) {
|
|
|
946
1018
|
return document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
947
1019
|
}
|
|
948
1020
|
function colorToRgbAttr(color) {
|
|
949
|
-
const
|
|
950
|
-
return `rgb(${
|
|
1021
|
+
const { r, g, b } = colorToRgb(color);
|
|
1022
|
+
return `rgb(${r},${g},${b})`;
|
|
951
1023
|
}
|
|
952
1024
|
function createSVGRenderer(options) {
|
|
953
1025
|
const { container, engine } = options;
|
|
@@ -965,6 +1037,7 @@ function createSVGRenderer(options) {
|
|
|
965
1037
|
let headRadius;
|
|
966
1038
|
let trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
967
1039
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
1040
|
+
let trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
968
1041
|
const ariaLabel = options.ariaLabel ?? "Loading";
|
|
969
1042
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
970
1043
|
const viewSize = 100;
|
|
@@ -976,7 +1049,14 @@ function createSVGRenderer(options) {
|
|
|
976
1049
|
const svgTrailMinWidth = TRAIL_MIN_WIDTH * viewSize / containerPx;
|
|
977
1050
|
const svgTrailMaxWidth = TRAIL_MAX_WIDTH * viewSize / containerPx;
|
|
978
1051
|
const svgSkeletonStrokeWidth = String(SKELETON_STROKE_WIDTH_PX * viewSize / containerPx);
|
|
1052
|
+
if (options.headRadius !== void 0) {
|
|
1053
|
+
validateRenderOptions({ headRadius: options.headRadius });
|
|
1054
|
+
}
|
|
1055
|
+
if (options.trailWidth !== void 0) {
|
|
1056
|
+
validateRenderOptions({ trailWidth: options.trailWidth });
|
|
1057
|
+
}
|
|
979
1058
|
headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;
|
|
1059
|
+
let trailWidth = options.trailWidth ?? 1;
|
|
980
1060
|
container.setAttribute("viewBox", `0 0 ${viewSize} ${viewSize}`);
|
|
981
1061
|
container.setAttribute("role", "img");
|
|
982
1062
|
container.setAttribute("aria-label", ariaLabel);
|
|
@@ -1071,15 +1151,15 @@ function createSVGRenderer(options) {
|
|
|
1071
1151
|
trailCount,
|
|
1072
1152
|
px,
|
|
1073
1153
|
py,
|
|
1074
|
-
svgTrailMinWidth,
|
|
1075
|
-
svgTrailMaxWidth
|
|
1154
|
+
svgTrailMinWidth * trailWidth,
|
|
1155
|
+
svgTrailMaxWidth * trailWidth
|
|
1076
1156
|
);
|
|
1077
1157
|
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`;
|
|
1078
1158
|
trailPaths[i].setAttribute("d", d);
|
|
1079
1159
|
trailPaths[i].setAttribute("fill-opacity", opacity.toFixed(3));
|
|
1080
1160
|
if (trailStyle !== "default") {
|
|
1081
1161
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
1082
|
-
const { r, g, b } = getPaletteColor(
|
|
1162
|
+
const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));
|
|
1083
1163
|
trailPaths[i].setAttribute("fill", `rgb(${r},${g},${b})`);
|
|
1084
1164
|
}
|
|
1085
1165
|
}
|
|
@@ -1231,6 +1311,7 @@ function createSVGRenderer(options) {
|
|
|
1231
1311
|
trailColor = partial.trailColor;
|
|
1232
1312
|
trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
1233
1313
|
trailPalette = resolveTrailPalette(trailColor);
|
|
1314
|
+
trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
1234
1315
|
if (trailStyle === "default") {
|
|
1235
1316
|
for (const p of trailPaths) {
|
|
1236
1317
|
p.setAttribute("fill", trailSolid);
|
|
@@ -1263,6 +1344,9 @@ function createSVGRenderer(options) {
|
|
|
1263
1344
|
headRadius = partial.headRadius;
|
|
1264
1345
|
headCircle.setAttribute("r", String(headRadius));
|
|
1265
1346
|
}
|
|
1347
|
+
if (partial.trailWidth !== void 0) {
|
|
1348
|
+
trailWidth = partial.trailWidth;
|
|
1349
|
+
}
|
|
1266
1350
|
if (userHeadColor === null) {
|
|
1267
1351
|
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
1268
1352
|
} else {
|