@sarmal/core 0.13.0 → 0.15.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 +172 -53
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +172 -53
- 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 +246 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -5
- package/dist/index.d.ts +20 -5
- package/dist/index.js +246 -58
- package/dist/index.js.map +1 -1
- package/dist/{types-BW0bpL1Z.d.cts → types-BL9HhEmk.d.cts} +43 -21
- package/dist/{types-BW0bpL1Z.d.ts → types-BL9HhEmk.d.ts} +43 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -376,10 +376,7 @@ function enginePassthroughs(engine) {
|
|
|
376
376
|
setSpeedOver: engine.setSpeedOver,
|
|
377
377
|
};
|
|
378
378
|
}
|
|
379
|
-
|
|
380
|
-
// src/renderer.ts
|
|
381
|
-
var DEFAULT_SKELETON_COLOR = "#ffffff";
|
|
382
|
-
var GRADIENT = {
|
|
379
|
+
var palettes = {
|
|
383
380
|
bard: ["#a855f7", "#3b82f6", "#14b8a6", "#ec4899"],
|
|
384
381
|
sunset: ["#f97316", "#dc2626", "#9333ea", "#f472b6"],
|
|
385
382
|
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
@@ -387,14 +384,6 @@ var GRADIENT = {
|
|
|
387
384
|
fire: ["#7f1d1d", "#fbbf24"],
|
|
388
385
|
forest: ["#14532d", "#86efac"],
|
|
389
386
|
};
|
|
390
|
-
var PRESETS = {
|
|
391
|
-
bard: GRADIENT.bard,
|
|
392
|
-
sunset: GRADIENT.sunset,
|
|
393
|
-
ocean: GRADIENT.ocean,
|
|
394
|
-
ice: GRADIENT.ice,
|
|
395
|
-
fire: GRADIENT.fire,
|
|
396
|
-
forest: GRADIENT.forest,
|
|
397
|
-
};
|
|
398
387
|
function hexToRgb(hex) {
|
|
399
388
|
const n = parseInt(hex.slice(1), 16);
|
|
400
389
|
return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
|
|
@@ -405,8 +394,12 @@ var lerpRgb = (a, b, t) => ({
|
|
|
405
394
|
b: Math.round(a.b + (b.b - a.b) * t),
|
|
406
395
|
});
|
|
407
396
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
408
|
-
if (palette.length === 0)
|
|
409
|
-
|
|
397
|
+
if (palette.length === 0) {
|
|
398
|
+
return { r: 255, g: 255, b: 255 };
|
|
399
|
+
}
|
|
400
|
+
if (palette.length === 1) {
|
|
401
|
+
return hexToRgb(palette[0]);
|
|
402
|
+
}
|
|
410
403
|
const cyclePos = (position + timeOffset) % 1;
|
|
411
404
|
const scaled = cyclePos * palette.length;
|
|
412
405
|
const idx = Math.floor(scaled);
|
|
@@ -415,11 +408,120 @@ function getPaletteColor(palette, position, timeOffset = 0) {
|
|
|
415
408
|
const c2 = hexToRgb(palette[(idx + 1) % palette.length]);
|
|
416
409
|
return lerpRgb(c1, c2, t);
|
|
417
410
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
411
|
+
var HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;
|
|
412
|
+
var TRAIL_STYLES = ["default", "gradient-static", "gradient-animated"];
|
|
413
|
+
var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
414
|
+
"trailColor",
|
|
415
|
+
"headColor",
|
|
416
|
+
"skeletonColor",
|
|
417
|
+
"trailStyle",
|
|
418
|
+
]);
|
|
419
|
+
function validateRenderOptions(partial) {
|
|
420
|
+
for (const key of Object.keys(partial)) {
|
|
421
|
+
if (!RENDER_OPTION_KEYS.has(key)) {
|
|
422
|
+
throw new TypeError(`[sarmal] setRenderOptions: unknown key "${key}"`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
if (partial.trailColor !== void 0) {
|
|
426
|
+
assertTrailColor(partial.trailColor);
|
|
427
|
+
}
|
|
428
|
+
if (partial.headColor !== void 0) {
|
|
429
|
+
assertHeadColor(partial.headColor);
|
|
430
|
+
}
|
|
431
|
+
if (partial.skeletonColor !== void 0) {
|
|
432
|
+
assertSkeletonColor(partial.skeletonColor);
|
|
433
|
+
}
|
|
434
|
+
if (partial.trailStyle !== void 0) {
|
|
435
|
+
assertTrailStyle(partial.trailStyle);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function assertTrailColor(value) {
|
|
439
|
+
if (typeof value === "string") {
|
|
440
|
+
if (!HEX_COLOR_RE.test(value)) {
|
|
441
|
+
throw new TypeError(
|
|
442
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`,
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
if (Array.isArray(value)) {
|
|
448
|
+
if (value.length < 2) {
|
|
449
|
+
throw new RangeError(
|
|
450
|
+
`[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
for (let i = 0; i < value.length; i++) {
|
|
454
|
+
const entry = value[i];
|
|
455
|
+
if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
|
|
456
|
+
throw new TypeError(
|
|
457
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
throw new TypeError(
|
|
464
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`,
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
function assertHeadColor(value) {
|
|
468
|
+
if (value === null) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
472
|
+
throw new TypeError(
|
|
473
|
+
`[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`,
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
function assertSkeletonColor(value) {
|
|
478
|
+
if (value === "transparent") {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
482
|
+
throw new TypeError(
|
|
483
|
+
`[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`,
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function assertTrailStyle(value) {
|
|
488
|
+
if (!TRAIL_STYLES.includes(value)) {
|
|
489
|
+
throw new RangeError(
|
|
490
|
+
`[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`,
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
function resolveTrailMainColor(trailColor) {
|
|
495
|
+
return typeof trailColor === "string" ? trailColor : trailColor[0];
|
|
496
|
+
}
|
|
497
|
+
function resolveTrailPalette(trailColor) {
|
|
498
|
+
return typeof trailColor === "string" ? [trailColor] : trailColor;
|
|
499
|
+
}
|
|
500
|
+
function resolveHeadColor(trailColor, trailStyle) {
|
|
501
|
+
if (trailStyle === "default") {
|
|
502
|
+
return resolveTrailMainColor(trailColor);
|
|
503
|
+
}
|
|
504
|
+
const palette = resolveTrailPalette(trailColor);
|
|
505
|
+
const last = palette[palette.length - 1];
|
|
506
|
+
const { r, g, b } = hexToRgb(last);
|
|
507
|
+
return `rgb(${r},${g},${b})`;
|
|
508
|
+
}
|
|
509
|
+
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
510
|
+
if (trailStyle === "default" && Array.isArray(trailColor)) {
|
|
511
|
+
console.warn(
|
|
512
|
+
'[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.',
|
|
513
|
+
);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
if (trailStyle !== "default" && typeof trailColor === "string") {
|
|
517
|
+
console.warn(
|
|
518
|
+
`[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.`,
|
|
519
|
+
);
|
|
520
|
+
}
|
|
422
521
|
}
|
|
522
|
+
|
|
523
|
+
// src/renderer.ts
|
|
524
|
+
var WHITE_HEX = "#ffffff";
|
|
423
525
|
function hexToRgbComponents(hex) {
|
|
424
526
|
const n = parseInt(hex.slice(1), 16);
|
|
425
527
|
return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
|
|
@@ -437,22 +539,14 @@ function createRenderer(options) {
|
|
|
437
539
|
}
|
|
438
540
|
const ctx = canvas.getContext("2d");
|
|
439
541
|
const engine = options.engine;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return trailColor;
|
|
449
|
-
}
|
|
450
|
-
const opts = {
|
|
451
|
-
skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,
|
|
452
|
-
trailColor,
|
|
453
|
-
headColor: options.headColor ?? defaultHeadColor(),
|
|
454
|
-
};
|
|
455
|
-
const trailRgb = hexToRgbComponents(opts.trailColor);
|
|
542
|
+
let trailStyle = options.trailStyle ?? "default";
|
|
543
|
+
let trailColor = options.trailColor ?? WHITE_HEX;
|
|
544
|
+
let skeletonColor = options.skeletonColor ?? WHITE_HEX;
|
|
545
|
+
let userHeadColor = options.headColor ?? null;
|
|
546
|
+
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
547
|
+
let trailSolidRgb = hexToRgbComponents(resolveTrailMainColor(trailColor));
|
|
548
|
+
let trailPalette = resolveTrailPalette(trailColor);
|
|
549
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
456
550
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
457
551
|
function setupCanvas() {
|
|
458
552
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -487,11 +581,13 @@ function createRenderer(options) {
|
|
|
487
581
|
}
|
|
488
582
|
}
|
|
489
583
|
function buildSkeletonCanvas() {
|
|
490
|
-
if (skeleton.length < 2)
|
|
584
|
+
if (skeleton.length < 2) {
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
491
587
|
skeletonCanvas = new OffscreenCanvas(canvas.width, canvas.height);
|
|
492
588
|
const skeletonCtx = skeletonCanvas.getContext("2d");
|
|
493
589
|
skeletonCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
494
|
-
skeletonCtx.strokeStyle = `rgba(${hexToRgbComponents(
|
|
590
|
+
skeletonCtx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
495
591
|
skeletonCtx.lineWidth = 1.5;
|
|
496
592
|
skeletonCtx.beginPath();
|
|
497
593
|
const first = skeleton[0];
|
|
@@ -503,8 +599,10 @@ function createRenderer(options) {
|
|
|
503
599
|
skeletonCtx.stroke();
|
|
504
600
|
}
|
|
505
601
|
function drawSkeletonPath(pts, opacity) {
|
|
506
|
-
if (pts.length < 2)
|
|
507
|
-
|
|
602
|
+
if (pts.length < 2) {
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
ctx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${opacity})`;
|
|
508
606
|
ctx.lineWidth = 1.5;
|
|
509
607
|
ctx.beginPath();
|
|
510
608
|
ctx.moveTo(pts[0].x * scale + offsetX, pts[0].y * scale + offsetY);
|
|
@@ -514,7 +612,7 @@ function createRenderer(options) {
|
|
|
514
612
|
ctx.stroke();
|
|
515
613
|
}
|
|
516
614
|
function drawSkeleton() {
|
|
517
|
-
if (
|
|
615
|
+
if (skeletonColor === "transparent") {
|
|
518
616
|
return;
|
|
519
617
|
}
|
|
520
618
|
if (engine.morphAlpha !== null) {
|
|
@@ -525,7 +623,7 @@ function createRenderer(options) {
|
|
|
525
623
|
if (skeleton.length < 2) {
|
|
526
624
|
return;
|
|
527
625
|
}
|
|
528
|
-
ctx.strokeStyle = `rgba(${hexToRgbComponents(
|
|
626
|
+
ctx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
529
627
|
ctx.lineWidth = 1.5;
|
|
530
628
|
ctx.beginPath();
|
|
531
629
|
const first = skeleton[0];
|
|
@@ -554,10 +652,10 @@ function createRenderer(options) {
|
|
|
554
652
|
toY,
|
|
555
653
|
);
|
|
556
654
|
if (trailStyle === "default") {
|
|
557
|
-
ctx.fillStyle = `rgba(${
|
|
655
|
+
ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
|
|
558
656
|
} else {
|
|
559
657
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
560
|
-
const color = getPaletteColor(
|
|
658
|
+
const color = getPaletteColor(trailPalette, progress, timeOffset);
|
|
561
659
|
ctx.fillStyle = `rgba(${color.r},${color.g},${color.b},${opacity})`;
|
|
562
660
|
}
|
|
563
661
|
ctx.beginPath();
|
|
@@ -577,7 +675,7 @@ function createRenderer(options) {
|
|
|
577
675
|
const y = head.y * scale + offsetY;
|
|
578
676
|
const r =
|
|
579
677
|
options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(logicalWidth, logicalHeight) / 160));
|
|
580
|
-
ctx.fillStyle =
|
|
678
|
+
ctx.fillStyle = headColor;
|
|
581
679
|
ctx.beginPath();
|
|
582
680
|
ctx.arc(x, y, r, 0, Math.PI * 2);
|
|
583
681
|
ctx.fill();
|
|
@@ -678,6 +776,34 @@ function createRenderer(options) {
|
|
|
678
776
|
morphResolve = resolve;
|
|
679
777
|
});
|
|
680
778
|
},
|
|
779
|
+
setRenderOptions(partial) {
|
|
780
|
+
validateRenderOptions(partial);
|
|
781
|
+
if (partial.trailColor !== void 0) {
|
|
782
|
+
trailColor = partial.trailColor;
|
|
783
|
+
trailSolidRgb = hexToRgbComponents(resolveTrailMainColor(trailColor));
|
|
784
|
+
trailPalette = resolveTrailPalette(trailColor);
|
|
785
|
+
}
|
|
786
|
+
if (partial.skeletonColor !== void 0) {
|
|
787
|
+
skeletonColor = partial.skeletonColor;
|
|
788
|
+
if (skeletonColor !== "transparent" && !engine.isLiveSkeleton) {
|
|
789
|
+
buildSkeletonCanvas();
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if (partial.trailStyle !== void 0) {
|
|
793
|
+
trailStyle = partial.trailStyle;
|
|
794
|
+
}
|
|
795
|
+
if (partial.headColor !== void 0) {
|
|
796
|
+
userHeadColor = partial.headColor;
|
|
797
|
+
}
|
|
798
|
+
if (userHeadColor === null) {
|
|
799
|
+
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
800
|
+
} else {
|
|
801
|
+
headColor = userHeadColor;
|
|
802
|
+
}
|
|
803
|
+
if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
|
|
804
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
805
|
+
}
|
|
806
|
+
},
|
|
681
807
|
};
|
|
682
808
|
if (shouldAutoStart) {
|
|
683
809
|
instance.play();
|
|
@@ -713,13 +839,15 @@ function el(tag) {
|
|
|
713
839
|
}
|
|
714
840
|
function createSVGRenderer(options) {
|
|
715
841
|
const { container, engine } = options;
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
842
|
+
let trailStyle = options.trailStyle ?? "default";
|
|
843
|
+
let trailColor = options.trailColor ?? "#ffffff";
|
|
844
|
+
let skeletonColor = options.skeletonColor ?? "#ffffff";
|
|
845
|
+
let userHeadColor = options.headColor ?? null;
|
|
846
|
+
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
847
|
+
let trailSolid = resolveTrailMainColor(trailColor);
|
|
848
|
+
let trailPalette = resolveTrailPalette(trailColor);
|
|
849
|
+
const ariaLabel = options.ariaLabel ?? "Loading";
|
|
850
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
723
851
|
const rect = container.getBoundingClientRect();
|
|
724
852
|
const width = rect.width || 200;
|
|
725
853
|
const height = rect.height || 200;
|
|
@@ -730,25 +858,29 @@ function createSVGRenderer(options) {
|
|
|
730
858
|
svg.setAttribute("height", String(height));
|
|
731
859
|
svg.setAttribute("viewBox", `0 0 ${width} ${height}`);
|
|
732
860
|
svg.setAttribute("role", "img");
|
|
733
|
-
svg.setAttribute("aria-label",
|
|
861
|
+
svg.setAttribute("aria-label", ariaLabel);
|
|
734
862
|
const titleEl = el("title");
|
|
735
|
-
titleEl.textContent =
|
|
863
|
+
titleEl.textContent = ariaLabel;
|
|
736
864
|
svg.appendChild(titleEl);
|
|
737
865
|
const skeletonPath = el("path");
|
|
866
|
+
skeletonPath.setAttribute("data-sarmal-role", "skeleton");
|
|
738
867
|
skeletonPath.setAttribute("fill", "none");
|
|
739
|
-
skeletonPath.setAttribute("stroke",
|
|
868
|
+
skeletonPath.setAttribute("stroke", skeletonColor);
|
|
740
869
|
skeletonPath.setAttribute("stroke-opacity", String(DEFAULT_SKELETON_OPACITY));
|
|
741
870
|
skeletonPath.setAttribute("stroke-width", "1.5");
|
|
871
|
+
if (skeletonColor === "transparent") {
|
|
872
|
+
skeletonPath.setAttribute("visibility", "hidden");
|
|
873
|
+
}
|
|
742
874
|
svg.appendChild(skeletonPath);
|
|
743
875
|
const skeletonPathA = el("path");
|
|
744
876
|
skeletonPathA.setAttribute("fill", "none");
|
|
745
|
-
skeletonPathA.setAttribute("stroke",
|
|
877
|
+
skeletonPathA.setAttribute("stroke", skeletonColor);
|
|
746
878
|
skeletonPathA.setAttribute("stroke-width", "1.5");
|
|
747
879
|
skeletonPathA.setAttribute("visibility", "hidden");
|
|
748
880
|
svg.appendChild(skeletonPathA);
|
|
749
881
|
const skeletonPathB = el("path");
|
|
750
882
|
skeletonPathB.setAttribute("fill", "none");
|
|
751
|
-
skeletonPathB.setAttribute("stroke",
|
|
883
|
+
skeletonPathB.setAttribute("stroke", skeletonColor);
|
|
752
884
|
skeletonPathB.setAttribute("stroke-width", "1.5");
|
|
753
885
|
skeletonPathB.setAttribute("visibility", "hidden");
|
|
754
886
|
svg.appendChild(skeletonPathB);
|
|
@@ -757,15 +889,17 @@ function createSVGRenderer(options) {
|
|
|
757
889
|
const trailPaths = [];
|
|
758
890
|
for (let i = 0; i < MAX_TRAIL_SEGMENTS; i++) {
|
|
759
891
|
const path = el("path");
|
|
760
|
-
path.setAttribute("fill",
|
|
892
|
+
path.setAttribute("fill", trailSolid);
|
|
761
893
|
svg.appendChild(path);
|
|
762
894
|
trailPaths.push(path);
|
|
763
895
|
}
|
|
764
896
|
const headCircle = el("circle");
|
|
765
|
-
headCircle.setAttribute("
|
|
897
|
+
headCircle.setAttribute("data-sarmal-role", "head");
|
|
898
|
+
headCircle.setAttribute("fill", headColor);
|
|
766
899
|
headCircle.setAttribute("r", String(headRadius));
|
|
767
900
|
svg.appendChild(headCircle);
|
|
768
901
|
container.appendChild(svg);
|
|
902
|
+
let gradientAnimTime = 0;
|
|
769
903
|
let scale = 1;
|
|
770
904
|
let offsetX = 0;
|
|
771
905
|
let offsetY = 0;
|
|
@@ -799,7 +933,7 @@ function createSVGRenderer(options) {
|
|
|
799
933
|
return;
|
|
800
934
|
}
|
|
801
935
|
for (let i = 0; i < trailCount - 1; i++) {
|
|
802
|
-
const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity } = computeTrailQuad(
|
|
936
|
+
const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(
|
|
803
937
|
trail,
|
|
804
938
|
i,
|
|
805
939
|
trailCount,
|
|
@@ -809,6 +943,11 @@ function createSVGRenderer(options) {
|
|
|
809
943
|
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`;
|
|
810
944
|
trailPaths[i].setAttribute("d", d);
|
|
811
945
|
trailPaths[i].setAttribute("fill-opacity", opacity.toFixed(3));
|
|
946
|
+
if (trailStyle !== "default") {
|
|
947
|
+
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
948
|
+
const { r, g, b } = getPaletteColor(trailPalette, progress, timeOffset);
|
|
949
|
+
trailPaths[i].setAttribute("fill", `rgb(${r},${g},${b})`);
|
|
950
|
+
}
|
|
812
951
|
}
|
|
813
952
|
for (let i = trailCount - 1; i < trailPaths.length; i++) {
|
|
814
953
|
trailPaths[i].setAttribute("d", "");
|
|
@@ -833,6 +972,9 @@ function createSVGRenderer(options) {
|
|
|
833
972
|
let morphTarget = null;
|
|
834
973
|
let morphAlpha = 0;
|
|
835
974
|
function renderFrame(deltaTime) {
|
|
975
|
+
if (trailStyle === "gradient-animated") {
|
|
976
|
+
gradientAnimTime += deltaTime * 1e3;
|
|
977
|
+
}
|
|
836
978
|
if (engine.morphAlpha !== null) {
|
|
837
979
|
morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1e3));
|
|
838
980
|
engine.setMorphAlpha(morphAlpha);
|
|
@@ -938,6 +1080,51 @@ function createSVGRenderer(options) {
|
|
|
938
1080
|
morphResolve = resolve;
|
|
939
1081
|
});
|
|
940
1082
|
},
|
|
1083
|
+
setRenderOptions(partial) {
|
|
1084
|
+
validateRenderOptions(partial);
|
|
1085
|
+
const prevTrailStyle = trailStyle;
|
|
1086
|
+
if (partial.trailColor !== void 0) {
|
|
1087
|
+
trailColor = partial.trailColor;
|
|
1088
|
+
trailSolid = resolveTrailMainColor(trailColor);
|
|
1089
|
+
trailPalette = resolveTrailPalette(trailColor);
|
|
1090
|
+
if (trailStyle === "default") {
|
|
1091
|
+
for (const p of trailPaths) {
|
|
1092
|
+
p.setAttribute("fill", trailSolid);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
if (partial.skeletonColor !== void 0) {
|
|
1097
|
+
skeletonColor = partial.skeletonColor;
|
|
1098
|
+
if (skeletonColor === "transparent") {
|
|
1099
|
+
skeletonPath.setAttribute("visibility", "hidden");
|
|
1100
|
+
} else {
|
|
1101
|
+
skeletonPath.setAttribute("stroke", skeletonColor);
|
|
1102
|
+
skeletonPath.removeAttribute("visibility");
|
|
1103
|
+
skeletonPathA.setAttribute("stroke", skeletonColor);
|
|
1104
|
+
skeletonPathB.setAttribute("stroke", skeletonColor);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
if (partial.trailStyle !== void 0) {
|
|
1108
|
+
trailStyle = partial.trailStyle;
|
|
1109
|
+
if (prevTrailStyle !== "default" && trailStyle === "default") {
|
|
1110
|
+
for (const p of trailPaths) {
|
|
1111
|
+
p.setAttribute("fill", trailSolid);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
if (partial.headColor !== void 0) {
|
|
1116
|
+
userHeadColor = partial.headColor;
|
|
1117
|
+
}
|
|
1118
|
+
if (userHeadColor === null) {
|
|
1119
|
+
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
1120
|
+
} else {
|
|
1121
|
+
headColor = userHeadColor;
|
|
1122
|
+
}
|
|
1123
|
+
headCircle.setAttribute("fill", headColor);
|
|
1124
|
+
if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
|
|
1125
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
1126
|
+
}
|
|
1127
|
+
},
|
|
941
1128
|
};
|
|
942
1129
|
if (shouldAutoStart) {
|
|
943
1130
|
instance.play();
|
|
@@ -1163,6 +1350,7 @@ export {
|
|
|
1163
1350
|
lame,
|
|
1164
1351
|
lissajous32,
|
|
1165
1352
|
lissajous43,
|
|
1353
|
+
palettes,
|
|
1166
1354
|
rose3,
|
|
1167
1355
|
rose5,
|
|
1168
1356
|
};
|