@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/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { B as BaseRendererOptions, E as Engine, S as SarmalInstance, C as CurveDef, R as RendererOptions, a as ControlPoint, P as Point, b as SarmalOptions } from './types-
|
|
2
|
-
export { J as JumpOptions, c as RuntimeRenderOptions, d as SeekOptions, T as TrailColor, e as TrailStyle } from './types-
|
|
1
|
+
import { B as BaseRendererOptions, E as Engine, S as SarmalInstance, C as CurveDef, R as RendererOptions, a as ControlPoint, P as Point, b as SarmalOptions } from './types-BBuUk6nn.cjs';
|
|
2
|
+
export { J as JumpOptions, c as RuntimeRenderOptions, d as SeekOptions, T as TrailColor, e as TrailStyle } from './types-BBuUk6nn.cjs';
|
|
3
3
|
export { CurveName, curves } from './curves/index.cjs';
|
|
4
|
-
export { B as BoundaryResult, S as SarmalPalette, c as computeBoundaries, p as palettes } from './renderer-shared-
|
|
4
|
+
export { B as BoundaryResult, S as SarmalPalette, c as computeBoundaries, p as palettes } from './renderer-shared-Ke9BeK1P.cjs';
|
|
5
5
|
export { artemis2 } from './curves/artemis2.cjs';
|
|
6
6
|
export { astroid } from './curves/astroid.cjs';
|
|
7
7
|
export { deltoid } from './curves/deltoid.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { B as BaseRendererOptions, E as Engine, S as SarmalInstance, C as CurveDef, R as RendererOptions, a as ControlPoint, P as Point, b as SarmalOptions } from './types-
|
|
2
|
-
export { J as JumpOptions, c as RuntimeRenderOptions, d as SeekOptions, T as TrailColor, e as TrailStyle } from './types-
|
|
1
|
+
import { B as BaseRendererOptions, E as Engine, S as SarmalInstance, C as CurveDef, R as RendererOptions, a as ControlPoint, P as Point, b as SarmalOptions } from './types-BBuUk6nn.js';
|
|
2
|
+
export { J as JumpOptions, c as RuntimeRenderOptions, d as SeekOptions, T as TrailColor, e as TrailStyle } from './types-BBuUk6nn.js';
|
|
3
3
|
export { CurveName, curves } from './curves/index.js';
|
|
4
|
-
export { B as BoundaryResult, S as SarmalPalette, c as computeBoundaries, p as palettes } from './renderer-shared-
|
|
4
|
+
export { B as BoundaryResult, S as SarmalPalette, c as computeBoundaries, p as palettes } from './renderer-shared-Bdca4O4G.js';
|
|
5
5
|
export { artemis2 } from './curves/artemis2.js';
|
|
6
6
|
export { astroid } from './curves/astroid.js';
|
|
7
7
|
export { deltoid } from './curves/deltoid.js';
|
package/dist/index.js
CHANGED
|
@@ -373,11 +373,15 @@ function enginePassthroughs(engine) {
|
|
|
373
373
|
}
|
|
374
374
|
var palettes = {
|
|
375
375
|
bard: ["#a855f7", "#3b82f6", "#14b8a6", "#ec4899"],
|
|
376
|
-
|
|
376
|
+
carnival: ["#ff6b6b", "#4ecdc4", "#ffe66d"],
|
|
377
377
|
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
378
|
+
sunset: ["#f97316", "#dc2626", "#9333ea", "#f472b6"],
|
|
378
379
|
ice: ["#1e3a8a", "#67e8f9"],
|
|
379
|
-
|
|
380
|
-
|
|
380
|
+
rocketpop: ["#08b8cd", "#ffffff", "#ff001f"],
|
|
381
|
+
neon: ["#00e5ff", "#7c3aed", "#e040fb"],
|
|
382
|
+
vaporwave: ["#ff71ce", "#01cdfe", "#b967ff"],
|
|
383
|
+
pastel: ["#c4b5fd", "#fbcfe8", "#bae6fd"],
|
|
384
|
+
sakura: ["#fff1f2", "#fda4af", "#fb7185"]
|
|
381
385
|
};
|
|
382
386
|
function hexToRgb(hex) {
|
|
383
387
|
const n = parseInt(hex.slice(1), 16);
|
|
@@ -412,6 +416,49 @@ function parseColorToRgb(s) {
|
|
|
412
416
|
}
|
|
413
417
|
return null;
|
|
414
418
|
}
|
|
419
|
+
var OKLCH_RE = /^oklch\(\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*[\d.]+)?\s*\)$/i;
|
|
420
|
+
function parseOklchToOklab(s) {
|
|
421
|
+
const m = OKLCH_RE.exec(s.trim());
|
|
422
|
+
if (!m) {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
const L = parseFloat(m[1]);
|
|
426
|
+
const C = parseFloat(m[2]);
|
|
427
|
+
const H = parseFloat(m[3]);
|
|
428
|
+
if (Number.isNaN(L) || Number.isNaN(C) || Number.isNaN(H)) {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
const clampedL = Math.max(0, Math.min(1, L));
|
|
432
|
+
const clampedC = Math.max(0, Math.min(0.4, C));
|
|
433
|
+
const H_rad = H * (Math.PI / 180);
|
|
434
|
+
return {
|
|
435
|
+
L: clampedL,
|
|
436
|
+
a: clampedC * Math.cos(H_rad),
|
|
437
|
+
b: clampedC * Math.sin(H_rad)
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function parseColorToOklab(s) {
|
|
441
|
+
const oklab = parseOklchToOklab(s);
|
|
442
|
+
if (oklab !== null) {
|
|
443
|
+
return oklab;
|
|
444
|
+
}
|
|
445
|
+
const rgb = parseColorToRgb(s);
|
|
446
|
+
if (rgb === null) {
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
return rgbToOklab(rgb);
|
|
450
|
+
}
|
|
451
|
+
function colorToRgb(color) {
|
|
452
|
+
const rgb = parseColorToRgb(color);
|
|
453
|
+
if (rgb !== null) {
|
|
454
|
+
return rgb;
|
|
455
|
+
}
|
|
456
|
+
const lab = parseOklchToOklab(color);
|
|
457
|
+
if (lab !== null) {
|
|
458
|
+
return oklabToRgb(lab);
|
|
459
|
+
}
|
|
460
|
+
throw new Error(`[sarmal] unrecognized color "${color}"`);
|
|
461
|
+
}
|
|
415
462
|
function srgbByteToLinear(c) {
|
|
416
463
|
const n = c / 255;
|
|
417
464
|
return n <= 0.04045 ? n / 12.92 : Math.pow((n + 0.055) / 1.055, 2.4);
|
|
@@ -449,26 +496,25 @@ var lerpOklab = (a, b, t) => {
|
|
|
449
496
|
if (t >= 1) {
|
|
450
497
|
return b;
|
|
451
498
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
});
|
|
499
|
+
return {
|
|
500
|
+
L: a.L + (b.L - a.L) * t,
|
|
501
|
+
a: a.a + (b.a - a.a) * t,
|
|
502
|
+
b: a.b + (b.b - a.b) * t
|
|
503
|
+
};
|
|
458
504
|
};
|
|
459
505
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
460
506
|
if (palette.length === 0) {
|
|
461
|
-
return {
|
|
507
|
+
return { L: 1, a: 0, b: 0 };
|
|
462
508
|
}
|
|
463
509
|
if (palette.length === 1) {
|
|
464
|
-
return
|
|
510
|
+
return palette[0];
|
|
465
511
|
}
|
|
466
512
|
const cyclePos = ((position + timeOffset) % 1 + 1) % 1;
|
|
467
513
|
const scaled = cyclePos * palette.length;
|
|
468
514
|
const idx = Math.floor(scaled);
|
|
469
515
|
const t = scaled - idx;
|
|
470
|
-
const c1 =
|
|
471
|
-
const c2 =
|
|
516
|
+
const c1 = palette[idx % palette.length];
|
|
517
|
+
const c2 = palette[(idx + 1) % palette.length];
|
|
472
518
|
return lerpOklab(c1, c2, t);
|
|
473
519
|
}
|
|
474
520
|
var TRAIL_STYLES = ["default", "gradient-static", "gradient-animated"];
|
|
@@ -477,7 +523,8 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
|
477
523
|
"headColor",
|
|
478
524
|
"skeletonColor",
|
|
479
525
|
"trailStyle",
|
|
480
|
-
"headRadius"
|
|
526
|
+
"headRadius",
|
|
527
|
+
"trailWidth"
|
|
481
528
|
]);
|
|
482
529
|
function validateRenderOptions(partial) {
|
|
483
530
|
for (const key of Object.keys(partial)) {
|
|
@@ -500,12 +547,15 @@ function validateRenderOptions(partial) {
|
|
|
500
547
|
if (partial.headRadius !== void 0) {
|
|
501
548
|
assertHeadRadius(partial.headRadius);
|
|
502
549
|
}
|
|
550
|
+
if (partial.trailWidth !== void 0) {
|
|
551
|
+
assertTrailWidth(partial.trailWidth);
|
|
552
|
+
}
|
|
503
553
|
}
|
|
504
554
|
function assertTrailColor(value) {
|
|
505
555
|
if (typeof value === "string") {
|
|
506
|
-
if (
|
|
556
|
+
if (parseColorToOklab(value) === null) {
|
|
507
557
|
throw new TypeError(
|
|
508
|
-
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got "${value}"`
|
|
558
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got "${value}"`
|
|
509
559
|
);
|
|
510
560
|
}
|
|
511
561
|
return;
|
|
@@ -518,25 +568,25 @@ function assertTrailColor(value) {
|
|
|
518
568
|
}
|
|
519
569
|
for (let i = 0; i < value.length; i++) {
|
|
520
570
|
const entry = value[i];
|
|
521
|
-
if (typeof entry !== "string" ||
|
|
571
|
+
if (typeof entry !== "string" || parseColorToOklab(entry) === null) {
|
|
522
572
|
throw new TypeError(
|
|
523
|
-
`[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba()), got ${JSON.stringify(entry)}`
|
|
573
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()), got ${JSON.stringify(entry)}`
|
|
524
574
|
);
|
|
525
575
|
}
|
|
526
576
|
}
|
|
527
577
|
return;
|
|
528
578
|
}
|
|
529
579
|
throw new TypeError(
|
|
530
|
-
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or an array of color strings, got ${JSON.stringify(value)}`
|
|
580
|
+
`[sarmal] setRenderOptions: trailColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or an array of color strings, got ${JSON.stringify(value)}`
|
|
531
581
|
);
|
|
532
582
|
}
|
|
533
583
|
function assertHeadColor(value) {
|
|
534
584
|
if (value === null) {
|
|
535
585
|
return;
|
|
536
586
|
}
|
|
537
|
-
if (typeof value !== "string" ||
|
|
587
|
+
if (typeof value !== "string" || parseColorToOklab(value) === null) {
|
|
538
588
|
throw new TypeError(
|
|
539
|
-
`[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or null, got ${JSON.stringify(value)}`
|
|
589
|
+
`[sarmal] setRenderOptions: headColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or null, got ${JSON.stringify(value)}`
|
|
540
590
|
);
|
|
541
591
|
}
|
|
542
592
|
}
|
|
@@ -544,9 +594,9 @@ function assertSkeletonColor(value) {
|
|
|
544
594
|
if (value === "transparent") {
|
|
545
595
|
return;
|
|
546
596
|
}
|
|
547
|
-
if (typeof value !== "string" ||
|
|
597
|
+
if (typeof value !== "string" || parseColorToOklab(value) === null) {
|
|
548
598
|
throw new TypeError(
|
|
549
|
-
`[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba()) or "transparent", got ${JSON.stringify(value)}`
|
|
599
|
+
`[sarmal] setRenderOptions: skeletonColor must be a valid color string (#rrggbb, #rgb, rgb(), rgba(), oklch()) or "transparent", got ${JSON.stringify(value)}`
|
|
550
600
|
);
|
|
551
601
|
}
|
|
552
602
|
}
|
|
@@ -569,6 +619,18 @@ function assertHeadRadius(value) {
|
|
|
569
619
|
);
|
|
570
620
|
}
|
|
571
621
|
}
|
|
622
|
+
function assertTrailWidth(value) {
|
|
623
|
+
if (typeof value !== "number") {
|
|
624
|
+
throw new TypeError(
|
|
625
|
+
`[sarmal] setRenderOptions: trailWidth must be a number, got ${JSON.stringify(value)}`
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
629
|
+
throw new TypeError(
|
|
630
|
+
`[sarmal] setRenderOptions: trailWidth must be a finite positive number, got ${value}`
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
572
634
|
function resolveTrailMainColor(trailColor) {
|
|
573
635
|
return typeof trailColor === "string" ? trailColor : trailColor[0];
|
|
574
636
|
}
|
|
@@ -581,7 +643,7 @@ function resolveHeadColor(trailColor, trailStyle) {
|
|
|
581
643
|
}
|
|
582
644
|
const palette = resolveTrailPalette(trailColor);
|
|
583
645
|
const last = palette[palette.length - 1];
|
|
584
|
-
const { r, g, b } =
|
|
646
|
+
const { r, g, b } = colorToRgb(last);
|
|
585
647
|
return `rgb(${r},${g},${b})`;
|
|
586
648
|
}
|
|
587
649
|
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
@@ -602,8 +664,8 @@ function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
|
602
664
|
var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160));
|
|
603
665
|
var WHITE_HEX = "#ffffff";
|
|
604
666
|
function colorToRgbComponents(color) {
|
|
605
|
-
const
|
|
606
|
-
return `${
|
|
667
|
+
const { r, g, b } = colorToRgb(color);
|
|
668
|
+
return `${r},${g},${b}`;
|
|
607
669
|
}
|
|
608
670
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
609
671
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -625,6 +687,7 @@ function createRenderer(options) {
|
|
|
625
687
|
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
626
688
|
let trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
627
689
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
690
|
+
let trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
628
691
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
629
692
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
630
693
|
function setupCanvas() {
|
|
@@ -636,7 +699,14 @@ function createRenderer(options) {
|
|
|
636
699
|
setupCanvas();
|
|
637
700
|
let logicalWidth = canvas.width / dpr;
|
|
638
701
|
let logicalHeight = canvas.height / dpr;
|
|
702
|
+
if (options.headRadius !== void 0) {
|
|
703
|
+
validateRenderOptions({ headRadius: options.headRadius });
|
|
704
|
+
}
|
|
705
|
+
if (options.trailWidth !== void 0) {
|
|
706
|
+
validateRenderOptions({ trailWidth: options.trailWidth });
|
|
707
|
+
}
|
|
639
708
|
let headRadius = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);
|
|
709
|
+
let trailWidth = options.trailWidth ?? 1;
|
|
640
710
|
let skeleton = [];
|
|
641
711
|
let skeletonCanvas = null;
|
|
642
712
|
let trail = [];
|
|
@@ -730,14 +800,16 @@ function createRenderer(options) {
|
|
|
730
800
|
i,
|
|
731
801
|
trailCount,
|
|
732
802
|
toX,
|
|
733
|
-
toY
|
|
803
|
+
toY,
|
|
804
|
+
TRAIL_MIN_WIDTH * trailWidth,
|
|
805
|
+
TRAIL_MAX_WIDTH * trailWidth
|
|
734
806
|
);
|
|
735
807
|
if (trailStyle === "default") {
|
|
736
808
|
ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
|
|
737
809
|
} else {
|
|
738
810
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
739
|
-
const
|
|
740
|
-
ctx.fillStyle = `rgba(${
|
|
811
|
+
const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));
|
|
812
|
+
ctx.fillStyle = `rgba(${r},${g},${b},${opacity})`;
|
|
741
813
|
}
|
|
742
814
|
ctx.beginPath();
|
|
743
815
|
ctx.moveTo(l0x, l0y);
|
|
@@ -871,6 +943,7 @@ function createRenderer(options) {
|
|
|
871
943
|
trailColor = partial.trailColor;
|
|
872
944
|
trailSolidRgb = colorToRgbComponents(resolveTrailMainColor(trailColor));
|
|
873
945
|
trailPalette = resolveTrailPalette(trailColor);
|
|
946
|
+
trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
874
947
|
}
|
|
875
948
|
if (partial.skeletonColor !== void 0) {
|
|
876
949
|
skeletonColor = partial.skeletonColor;
|
|
@@ -887,6 +960,9 @@ function createRenderer(options) {
|
|
|
887
960
|
if (partial.headRadius !== void 0) {
|
|
888
961
|
headRadius = partial.headRadius;
|
|
889
962
|
}
|
|
963
|
+
if (partial.trailWidth !== void 0) {
|
|
964
|
+
trailWidth = partial.trailWidth;
|
|
965
|
+
}
|
|
890
966
|
if (userHeadColor === null) {
|
|
891
967
|
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
892
968
|
} else {
|
|
@@ -954,8 +1030,8 @@ function el(tag) {
|
|
|
954
1030
|
return document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
955
1031
|
}
|
|
956
1032
|
function colorToRgbAttr(color) {
|
|
957
|
-
const
|
|
958
|
-
return `rgb(${
|
|
1033
|
+
const { r, g, b } = colorToRgb(color);
|
|
1034
|
+
return `rgb(${r},${g},${b})`;
|
|
959
1035
|
}
|
|
960
1036
|
function createSVGRenderer(options) {
|
|
961
1037
|
const { container, engine } = options;
|
|
@@ -973,6 +1049,7 @@ function createSVGRenderer(options) {
|
|
|
973
1049
|
let headRadius;
|
|
974
1050
|
let trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
975
1051
|
let trailPalette = resolveTrailPalette(trailColor);
|
|
1052
|
+
let trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
976
1053
|
const ariaLabel = options.ariaLabel ?? "Loading";
|
|
977
1054
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
978
1055
|
const viewSize = 100;
|
|
@@ -984,7 +1061,14 @@ function createSVGRenderer(options) {
|
|
|
984
1061
|
const svgTrailMinWidth = TRAIL_MIN_WIDTH * viewSize / containerPx;
|
|
985
1062
|
const svgTrailMaxWidth = TRAIL_MAX_WIDTH * viewSize / containerPx;
|
|
986
1063
|
const svgSkeletonStrokeWidth = String(SKELETON_STROKE_WIDTH_PX * viewSize / containerPx);
|
|
1064
|
+
if (options.headRadius !== void 0) {
|
|
1065
|
+
validateRenderOptions({ headRadius: options.headRadius });
|
|
1066
|
+
}
|
|
1067
|
+
if (options.trailWidth !== void 0) {
|
|
1068
|
+
validateRenderOptions({ trailWidth: options.trailWidth });
|
|
1069
|
+
}
|
|
987
1070
|
headRadius = options.headRadius ?? SVG_DEFAULT_HEAD_RADIUS;
|
|
1071
|
+
let trailWidth = options.trailWidth ?? 1;
|
|
988
1072
|
container.setAttribute("viewBox", `0 0 ${viewSize} ${viewSize}`);
|
|
989
1073
|
container.setAttribute("role", "img");
|
|
990
1074
|
container.setAttribute("aria-label", ariaLabel);
|
|
@@ -1079,15 +1163,15 @@ function createSVGRenderer(options) {
|
|
|
1079
1163
|
trailCount,
|
|
1080
1164
|
px,
|
|
1081
1165
|
py,
|
|
1082
|
-
svgTrailMinWidth,
|
|
1083
|
-
svgTrailMaxWidth
|
|
1166
|
+
svgTrailMinWidth * trailWidth,
|
|
1167
|
+
svgTrailMaxWidth * trailWidth
|
|
1084
1168
|
);
|
|
1085
1169
|
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`;
|
|
1086
1170
|
trailPaths[i].setAttribute("d", d);
|
|
1087
1171
|
trailPaths[i].setAttribute("fill-opacity", opacity.toFixed(3));
|
|
1088
1172
|
if (trailStyle !== "default") {
|
|
1089
1173
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
1090
|
-
const { r, g, b } = getPaletteColor(
|
|
1174
|
+
const { r, g, b } = oklabToRgb(getPaletteColor(trailPaletteOklab, progress, timeOffset));
|
|
1091
1175
|
trailPaths[i].setAttribute("fill", `rgb(${r},${g},${b})`);
|
|
1092
1176
|
}
|
|
1093
1177
|
}
|
|
@@ -1239,6 +1323,7 @@ function createSVGRenderer(options) {
|
|
|
1239
1323
|
trailColor = partial.trailColor;
|
|
1240
1324
|
trailSolid = colorToRgbAttr(resolveTrailMainColor(trailColor));
|
|
1241
1325
|
trailPalette = resolveTrailPalette(trailColor);
|
|
1326
|
+
trailPaletteOklab = trailPalette.map((c) => parseColorToOklab(c));
|
|
1242
1327
|
if (trailStyle === "default") {
|
|
1243
1328
|
for (const p of trailPaths) {
|
|
1244
1329
|
p.setAttribute("fill", trailSolid);
|
|
@@ -1271,6 +1356,9 @@ function createSVGRenderer(options) {
|
|
|
1271
1356
|
headRadius = partial.headRadius;
|
|
1272
1357
|
headCircle.setAttribute("r", String(headRadius));
|
|
1273
1358
|
}
|
|
1359
|
+
if (partial.trailWidth !== void 0) {
|
|
1360
|
+
trailWidth = partial.trailWidth;
|
|
1361
|
+
}
|
|
1274
1362
|
if (userHeadColor === null) {
|
|
1275
1363
|
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
1276
1364
|
} else {
|