@sarmal/core 0.14.0 → 0.15.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/auto-init.cjs +173 -57
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.d.cts +2 -1
- package/dist/auto-init.d.ts +2 -1
- package/dist/auto-init.js +173 -57
- package/dist/auto-init.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/index.cjs +233 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -3
- package/dist/index.d.ts +16 -3
- package/dist/index.js +233 -70
- package/dist/index.js.map +1 -1
- package/dist/{types-BQosOzlf.d.cts → types-BL9HhEmk.d.cts} +33 -10
- package/dist/{types-BQosOzlf.d.ts → types-BL9HhEmk.d.ts} +33 -10
- package/package.json +1 -1
package/dist/auto-init.cjs
CHANGED
|
@@ -369,22 +369,6 @@ function enginePassthroughs(engine) {
|
|
|
369
369
|
setSpeedOver: engine.setSpeedOver
|
|
370
370
|
};
|
|
371
371
|
}
|
|
372
|
-
var GRADIENT = {
|
|
373
|
-
bard: ["#a855f7", "#3b82f6", "#14b8a6", "#ec4899"],
|
|
374
|
-
sunset: ["#f97316", "#dc2626", "#9333ea", "#f472b6"],
|
|
375
|
-
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
376
|
-
ice: ["#1e3a8a", "#67e8f9"],
|
|
377
|
-
fire: ["#7f1d1d", "#fbbf24"],
|
|
378
|
-
forest: ["#14532d", "#86efac"]
|
|
379
|
-
};
|
|
380
|
-
var PRESETS = {
|
|
381
|
-
bard: GRADIENT.bard,
|
|
382
|
-
sunset: GRADIENT.sunset,
|
|
383
|
-
ocean: GRADIENT.ocean,
|
|
384
|
-
ice: GRADIENT.ice,
|
|
385
|
-
fire: GRADIENT.fire,
|
|
386
|
-
forest: GRADIENT.forest
|
|
387
|
-
};
|
|
388
372
|
function hexToRgb(hex) {
|
|
389
373
|
const n = parseInt(hex.slice(1), 16);
|
|
390
374
|
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
@@ -409,18 +393,121 @@ function getPaletteColor(palette, position, timeOffset = 0) {
|
|
|
409
393
|
const c2 = hexToRgb(palette[(idx + 1) % palette.length]);
|
|
410
394
|
return lerpRgb(c1, c2, t);
|
|
411
395
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
396
|
+
var HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;
|
|
397
|
+
var TRAIL_STYLES = ["default", "gradient-static", "gradient-animated"];
|
|
398
|
+
var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
399
|
+
"trailColor",
|
|
400
|
+
"headColor",
|
|
401
|
+
"skeletonColor",
|
|
402
|
+
"trailStyle"
|
|
403
|
+
]);
|
|
404
|
+
function validateRenderOptions(partial) {
|
|
405
|
+
for (const key of Object.keys(partial)) {
|
|
406
|
+
if (!RENDER_OPTION_KEYS.has(key)) {
|
|
407
|
+
throw new TypeError(`[sarmal] setRenderOptions: unknown key "${key}"`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (partial.trailColor !== void 0) {
|
|
411
|
+
assertTrailColor(partial.trailColor);
|
|
415
412
|
}
|
|
416
|
-
if (
|
|
417
|
-
|
|
413
|
+
if (partial.headColor !== void 0) {
|
|
414
|
+
assertHeadColor(partial.headColor);
|
|
415
|
+
}
|
|
416
|
+
if (partial.skeletonColor !== void 0) {
|
|
417
|
+
assertSkeletonColor(partial.skeletonColor);
|
|
418
|
+
}
|
|
419
|
+
if (partial.trailStyle !== void 0) {
|
|
420
|
+
assertTrailStyle(partial.trailStyle);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function assertTrailColor(value) {
|
|
424
|
+
if (typeof value === "string") {
|
|
425
|
+
if (!HEX_COLOR_RE.test(value)) {
|
|
426
|
+
throw new TypeError(
|
|
427
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
if (Array.isArray(value)) {
|
|
433
|
+
if (value.length < 2) {
|
|
434
|
+
throw new RangeError(
|
|
435
|
+
`[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
for (let i = 0; i < value.length; i++) {
|
|
439
|
+
const entry = value[i];
|
|
440
|
+
if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
|
|
441
|
+
throw new TypeError(
|
|
442
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return;
|
|
418
447
|
}
|
|
419
|
-
|
|
448
|
+
throw new TypeError(
|
|
449
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
function assertHeadColor(value) {
|
|
453
|
+
if (value === null) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
457
|
+
throw new TypeError(
|
|
458
|
+
`[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
function assertSkeletonColor(value) {
|
|
463
|
+
if (value === "transparent") {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
467
|
+
throw new TypeError(
|
|
468
|
+
`[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function assertTrailStyle(value) {
|
|
473
|
+
if (!TRAIL_STYLES.includes(value)) {
|
|
474
|
+
throw new RangeError(
|
|
475
|
+
`[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
function resolveTrailMainColor(trailColor) {
|
|
480
|
+
return typeof trailColor === "string" ? trailColor : trailColor[0];
|
|
420
481
|
}
|
|
482
|
+
function resolveTrailPalette(trailColor) {
|
|
483
|
+
return typeof trailColor === "string" ? [trailColor] : trailColor;
|
|
484
|
+
}
|
|
485
|
+
function resolveHeadColor(trailColor, trailStyle) {
|
|
486
|
+
if (trailStyle === "default") {
|
|
487
|
+
return resolveTrailMainColor(trailColor);
|
|
488
|
+
}
|
|
489
|
+
const palette = resolveTrailPalette(trailColor);
|
|
490
|
+
const last = palette[palette.length - 1];
|
|
491
|
+
const { r, g, b } = hexToRgb(last);
|
|
492
|
+
return `rgb(${r},${g},${b})`;
|
|
493
|
+
}
|
|
494
|
+
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
495
|
+
if (trailStyle === "default" && Array.isArray(trailColor)) {
|
|
496
|
+
console.warn(
|
|
497
|
+
'[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.'
|
|
498
|
+
);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
if (trailStyle !== "default" && typeof trailColor === "string") {
|
|
502
|
+
console.warn(
|
|
503
|
+
`[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.`
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160));
|
|
421
508
|
|
|
422
509
|
// src/renderer.ts
|
|
423
|
-
var
|
|
510
|
+
var WHITE_HEX = "#ffffff";
|
|
424
511
|
function hexToRgbComponents(hex) {
|
|
425
512
|
const n = parseInt(hex.slice(1), 16);
|
|
426
513
|
return `${n >> 16},${n >> 8 & 255},${n & 255}`;
|
|
@@ -438,27 +525,18 @@ function createRenderer(options) {
|
|
|
438
525
|
}
|
|
439
526
|
const ctx = canvas.getContext("2d");
|
|
440
527
|
const engine = options.engine;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
return trailColor;
|
|
450
|
-
}
|
|
451
|
-
const opts = {
|
|
452
|
-
skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,
|
|
453
|
-
trailColor,
|
|
454
|
-
headColor: options.headColor ?? defaultHeadColor()
|
|
455
|
-
};
|
|
456
|
-
const trailRgb = hexToRgbComponents(opts.trailColor);
|
|
528
|
+
let trailStyle = options.trailStyle ?? "default";
|
|
529
|
+
let trailColor = options.trailColor ?? WHITE_HEX;
|
|
530
|
+
let skeletonColor = options.skeletonColor ?? WHITE_HEX;
|
|
531
|
+
let userHeadColor = options.headColor ?? null;
|
|
532
|
+
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
533
|
+
let trailSolidRgb = hexToRgbComponents(resolveTrailMainColor(trailColor));
|
|
534
|
+
let trailPalette = resolveTrailPalette(trailColor);
|
|
535
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
457
536
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
458
537
|
function setupCanvas() {
|
|
459
|
-
const
|
|
460
|
-
const
|
|
461
|
-
const lh = rect.height || 200;
|
|
538
|
+
const lw = canvas.offsetWidth || 200;
|
|
539
|
+
const lh = canvas.offsetHeight || 200;
|
|
462
540
|
applyDprSizing(canvas, lw, lh, dpr);
|
|
463
541
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
464
542
|
}
|
|
@@ -488,11 +566,13 @@ function createRenderer(options) {
|
|
|
488
566
|
}
|
|
489
567
|
}
|
|
490
568
|
function buildSkeletonCanvas() {
|
|
491
|
-
if (skeleton.length < 2)
|
|
569
|
+
if (skeleton.length < 2) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
492
572
|
skeletonCanvas = new OffscreenCanvas(canvas.width, canvas.height);
|
|
493
573
|
const skeletonCtx = skeletonCanvas.getContext("2d");
|
|
494
574
|
skeletonCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
495
|
-
skeletonCtx.strokeStyle = `rgba(${hexToRgbComponents(
|
|
575
|
+
skeletonCtx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
496
576
|
skeletonCtx.lineWidth = 1.5;
|
|
497
577
|
skeletonCtx.beginPath();
|
|
498
578
|
const first = skeleton[0];
|
|
@@ -504,8 +584,10 @@ function createRenderer(options) {
|
|
|
504
584
|
skeletonCtx.stroke();
|
|
505
585
|
}
|
|
506
586
|
function drawSkeletonPath(pts, opacity) {
|
|
507
|
-
if (pts.length < 2)
|
|
508
|
-
|
|
587
|
+
if (pts.length < 2) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
ctx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${opacity})`;
|
|
509
591
|
ctx.lineWidth = 1.5;
|
|
510
592
|
ctx.beginPath();
|
|
511
593
|
ctx.moveTo(pts[0].x * scale + offsetX, pts[0].y * scale + offsetY);
|
|
@@ -515,7 +597,7 @@ function createRenderer(options) {
|
|
|
515
597
|
ctx.stroke();
|
|
516
598
|
}
|
|
517
599
|
function drawSkeleton() {
|
|
518
|
-
if (
|
|
600
|
+
if (skeletonColor === "transparent") {
|
|
519
601
|
return;
|
|
520
602
|
}
|
|
521
603
|
if (engine.morphAlpha !== null) {
|
|
@@ -526,7 +608,7 @@ function createRenderer(options) {
|
|
|
526
608
|
if (skeleton.length < 2) {
|
|
527
609
|
return;
|
|
528
610
|
}
|
|
529
|
-
ctx.strokeStyle = `rgba(${hexToRgbComponents(
|
|
611
|
+
ctx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
530
612
|
ctx.lineWidth = 1.5;
|
|
531
613
|
ctx.beginPath();
|
|
532
614
|
const first = skeleton[0];
|
|
@@ -555,10 +637,10 @@ function createRenderer(options) {
|
|
|
555
637
|
toY
|
|
556
638
|
);
|
|
557
639
|
if (trailStyle === "default") {
|
|
558
|
-
ctx.fillStyle = `rgba(${
|
|
640
|
+
ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
|
|
559
641
|
} else {
|
|
560
642
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
561
|
-
const color = getPaletteColor(
|
|
643
|
+
const color = getPaletteColor(trailPalette, progress, timeOffset);
|
|
562
644
|
ctx.fillStyle = `rgba(${color.r},${color.g},${color.b},${opacity})`;
|
|
563
645
|
}
|
|
564
646
|
ctx.beginPath();
|
|
@@ -576,8 +658,8 @@ function createRenderer(options) {
|
|
|
576
658
|
}
|
|
577
659
|
const x = head.x * scale + offsetX;
|
|
578
660
|
const y = head.y * scale + offsetY;
|
|
579
|
-
const r = options.headRadius ??
|
|
580
|
-
ctx.fillStyle =
|
|
661
|
+
const r = options.headRadius ?? getHeadDotRadius(logicalWidth, logicalHeight);
|
|
662
|
+
ctx.fillStyle = headColor;
|
|
581
663
|
ctx.beginPath();
|
|
582
664
|
ctx.arc(x, y, r, 0, Math.PI * 2);
|
|
583
665
|
ctx.fill();
|
|
@@ -677,6 +759,34 @@ function createRenderer(options) {
|
|
|
677
759
|
return new Promise((resolve) => {
|
|
678
760
|
morphResolve = resolve;
|
|
679
761
|
});
|
|
762
|
+
},
|
|
763
|
+
setRenderOptions(partial) {
|
|
764
|
+
validateRenderOptions(partial);
|
|
765
|
+
if (partial.trailColor !== void 0) {
|
|
766
|
+
trailColor = partial.trailColor;
|
|
767
|
+
trailSolidRgb = hexToRgbComponents(resolveTrailMainColor(trailColor));
|
|
768
|
+
trailPalette = resolveTrailPalette(trailColor);
|
|
769
|
+
}
|
|
770
|
+
if (partial.skeletonColor !== void 0) {
|
|
771
|
+
skeletonColor = partial.skeletonColor;
|
|
772
|
+
if (skeletonColor !== "transparent" && !engine.isLiveSkeleton) {
|
|
773
|
+
buildSkeletonCanvas();
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if (partial.trailStyle !== void 0) {
|
|
777
|
+
trailStyle = partial.trailStyle;
|
|
778
|
+
}
|
|
779
|
+
if (partial.headColor !== void 0) {
|
|
780
|
+
userHeadColor = partial.headColor;
|
|
781
|
+
}
|
|
782
|
+
if (userHeadColor === null) {
|
|
783
|
+
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
784
|
+
} else {
|
|
785
|
+
headColor = userHeadColor;
|
|
786
|
+
}
|
|
787
|
+
if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
|
|
788
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
789
|
+
}
|
|
680
790
|
}
|
|
681
791
|
};
|
|
682
792
|
if (shouldAutoStart) {
|
|
@@ -880,7 +990,7 @@ function createSarmal(canvas, curveDef, options) {
|
|
|
880
990
|
}
|
|
881
991
|
|
|
882
992
|
// src/auto-init.ts
|
|
883
|
-
function
|
|
993
|
+
function parseTrailColor(value) {
|
|
884
994
|
try {
|
|
885
995
|
const parsed = JSON.parse(value);
|
|
886
996
|
if (Array.isArray(parsed)) {
|
|
@@ -901,17 +1011,21 @@ function init() {
|
|
|
901
1011
|
if (!curveDef) {
|
|
902
1012
|
return console.error(`[sarmal] "${curveName}" is not a valid curve name`);
|
|
903
1013
|
}
|
|
904
|
-
createSarmal(canvas, curveDef, {
|
|
905
|
-
...canvas.dataset.trailColor && {
|
|
1014
|
+
const instance = createSarmal(canvas, curveDef, {
|
|
1015
|
+
...canvas.dataset.trailColor && {
|
|
1016
|
+
trailColor: parseTrailColor(canvas.dataset.trailColor)
|
|
1017
|
+
},
|
|
906
1018
|
...canvas.dataset.skeletonColor && { skeletonColor: canvas.dataset.skeletonColor },
|
|
907
1019
|
...canvas.dataset.headColor && { headColor: canvas.dataset.headColor },
|
|
908
1020
|
...canvas.dataset.headRadius && { headRadius: parseFloat(canvas.dataset.headRadius) },
|
|
909
1021
|
...canvas.dataset.trailLength && { trailLength: parseInt(canvas.dataset.trailLength, 10) },
|
|
910
1022
|
...canvas.dataset.trailStyle && {
|
|
911
1023
|
trailStyle: canvas.dataset.trailStyle
|
|
912
|
-
}
|
|
913
|
-
...canvas.dataset.palette && { palette: parsePalette(canvas.dataset.palette) }
|
|
1024
|
+
}
|
|
914
1025
|
});
|
|
1026
|
+
if (canvas.dataset.speed) {
|
|
1027
|
+
instance.setSpeed(parseFloat(canvas.dataset.speed));
|
|
1028
|
+
}
|
|
915
1029
|
});
|
|
916
1030
|
}
|
|
917
1031
|
if (document.readyState === "loading") {
|
|
@@ -921,5 +1035,7 @@ if (document.readyState === "loading") {
|
|
|
921
1035
|
} else {
|
|
922
1036
|
requestAnimationFrame(init);
|
|
923
1037
|
}
|
|
1038
|
+
|
|
1039
|
+
exports.init = init;
|
|
924
1040
|
//# sourceMappingURL=auto-init.cjs.map
|
|
925
1041
|
//# sourceMappingURL=auto-init.cjs.map
|