@sarmal/core 0.35.0 → 0.35.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/README.md +5 -3
- package/dist/index.cjs +32 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +32 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
<strong>Parametric curve animations for loading/thinking indicators</strong>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
<
|
|
8
|
-
<a href="https://sarmal.art"
|
|
9
|
-
|
|
7
|
+
<div align="center">
|
|
8
|
+
<a href="https://sarmal.art">
|
|
9
|
+
<img src="../../docs/public/curves-light.gif" alt="Sarmal demo" width="100%" max-width="720">
|
|
10
|
+
</a>
|
|
11
|
+
</div>
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
package/dist/index.cjs
CHANGED
|
@@ -1441,14 +1441,8 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1441
1441
|
const cellW = W / cols;
|
|
1442
1442
|
const cellH = H / rows;
|
|
1443
1443
|
const dotR = Math.min(cellW, cellH) * 0.36;
|
|
1444
|
-
let
|
|
1445
|
-
|
|
1446
|
-
validateBaseRenderOptions({ trailColor: initialColor });
|
|
1447
|
-
gradientRgb = initialColor.map(colorToRgb);
|
|
1448
|
-
} else {
|
|
1449
|
-
gradientRgb = null;
|
|
1450
|
-
}
|
|
1451
|
-
let colorRgb = gradientRgb ? gradientRgb[0] : colorToRgb(initialColor);
|
|
1444
|
+
let gradientOklab = null;
|
|
1445
|
+
let colorRgb = { r: 255, g: 255, b: 255 };
|
|
1452
1446
|
let currentTrailStyle = initialTrailStyle;
|
|
1453
1447
|
let animTime = 0;
|
|
1454
1448
|
const ANIM_PERIOD = 6;
|
|
@@ -1520,7 +1514,7 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1520
1514
|
}
|
|
1521
1515
|
function buildBgImageData() {
|
|
1522
1516
|
bgImageData = new ImageData(W, H);
|
|
1523
|
-
const bg =
|
|
1517
|
+
const bg = colorRgb;
|
|
1524
1518
|
const baseAlpha = 0.05 * 255;
|
|
1525
1519
|
const { data } = bgImageData;
|
|
1526
1520
|
const n = cols * rows;
|
|
@@ -1537,18 +1531,14 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1537
1531
|
}
|
|
1538
1532
|
}
|
|
1539
1533
|
}
|
|
1540
|
-
function
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
r: Math.round(a.r + (bStop.r - a.r) * mix),
|
|
1549
|
-
g: Math.round(a.g + (bStop.g - a.g) * mix),
|
|
1550
|
-
b: Math.round(a.b + (bStop.b - a.b) * mix)
|
|
1551
|
-
};
|
|
1534
|
+
function applyColor(color) {
|
|
1535
|
+
if (Array.isArray(color)) {
|
|
1536
|
+
gradientOklab = color.map((c) => parseColorToOklab(c));
|
|
1537
|
+
colorRgb = oklabToRgb(gradientOklab[0]);
|
|
1538
|
+
} else {
|
|
1539
|
+
gradientOklab = null;
|
|
1540
|
+
colorRgb = colorToRgb(color);
|
|
1541
|
+
}
|
|
1552
1542
|
}
|
|
1553
1543
|
function calculateBoundaries(skel) {
|
|
1554
1544
|
const b = computeBoundaries(skel, W, H);
|
|
@@ -1602,7 +1592,7 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1602
1592
|
}
|
|
1603
1593
|
frameImageData.data.set(bgImageData.data);
|
|
1604
1594
|
const { data } = frameImageData;
|
|
1605
|
-
const
|
|
1595
|
+
const timeOffset = currentTrailStyle === "gradient-animated" ? animTime / ANIM_PERIOD : 0;
|
|
1606
1596
|
const n = cols * rows;
|
|
1607
1597
|
for (let dotIdx = 0; dotIdx < n; dotIdx++) {
|
|
1608
1598
|
const intensity = grid[dotIdx];
|
|
@@ -1610,9 +1600,8 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1610
1600
|
continue;
|
|
1611
1601
|
}
|
|
1612
1602
|
let r, g, b;
|
|
1613
|
-
if (
|
|
1614
|
-
|
|
1615
|
-
({ r, g, b } = sampleGradientRgb(gradientRgb, t));
|
|
1603
|
+
if (gradientOklab !== null) {
|
|
1604
|
+
({ r, g, b } = oklabToRgb(getPaletteColor(gradientOklab, intensity, timeOffset)));
|
|
1616
1605
|
} else {
|
|
1617
1606
|
({ r, g, b } = colorRgb);
|
|
1618
1607
|
}
|
|
@@ -1630,17 +1619,20 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1630
1619
|
}
|
|
1631
1620
|
ctx.putImageData(frameImageData, 0, 0);
|
|
1632
1621
|
}
|
|
1622
|
+
function completeMorphNow() {
|
|
1623
|
+
engine.completeMorph();
|
|
1624
|
+
morphResolve?.();
|
|
1625
|
+
morphResolve = null;
|
|
1626
|
+
morphReject = null;
|
|
1627
|
+
morphProgress = 0;
|
|
1628
|
+
}
|
|
1633
1629
|
function renderFrame(deltaTime) {
|
|
1634
1630
|
if (engine.morphAlpha !== null) {
|
|
1635
1631
|
morphProgress = Math.min(1, morphProgress + deltaTime / (morphDurationMs / 1e3));
|
|
1636
1632
|
engine.setMorphAlpha(morphProgress);
|
|
1637
1633
|
calculateBoundaries(engine.getSarmalSkeleton());
|
|
1638
1634
|
if (morphProgress >= 1) {
|
|
1639
|
-
|
|
1640
|
-
morphResolve?.();
|
|
1641
|
-
morphResolve = null;
|
|
1642
|
-
morphReject = null;
|
|
1643
|
-
morphProgress = 0;
|
|
1635
|
+
completeMorphNow();
|
|
1644
1636
|
calculateBoundaries(engine.getSarmalSkeleton());
|
|
1645
1637
|
}
|
|
1646
1638
|
} else if (engine.isLiveSkeleton) {
|
|
@@ -1658,6 +1650,8 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1658
1650
|
renderFrame(deltaTime);
|
|
1659
1651
|
animationId = requestAnimationFrame(loop);
|
|
1660
1652
|
}
|
|
1653
|
+
validateBaseRenderOptions({ trailColor: initialColor });
|
|
1654
|
+
applyColor(initialColor);
|
|
1661
1655
|
calculateBoundaries(engine.getSarmalSkeleton());
|
|
1662
1656
|
computePixelMask();
|
|
1663
1657
|
frameImageData = new ImageData(W, H);
|
|
@@ -1706,11 +1700,7 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1706
1700
|
*/
|
|
1707
1701
|
morphTo(target, opts) {
|
|
1708
1702
|
if (morphResolve !== null) {
|
|
1709
|
-
|
|
1710
|
-
morphResolve();
|
|
1711
|
-
morphResolve = null;
|
|
1712
|
-
morphReject = null;
|
|
1713
|
-
morphProgress = 0;
|
|
1703
|
+
completeMorphNow();
|
|
1714
1704
|
}
|
|
1715
1705
|
morphDurationMs = opts?.duration ?? DEFAULT_MORPH_DURATION_MS;
|
|
1716
1706
|
morphProgress = 0;
|
|
@@ -1731,13 +1721,7 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1731
1721
|
validateBaseRenderOptions(partial);
|
|
1732
1722
|
let needsRebuildBg = false;
|
|
1733
1723
|
if (partial.trailColor !== void 0) {
|
|
1734
|
-
|
|
1735
|
-
gradientRgb = partial.trailColor.map(colorToRgb);
|
|
1736
|
-
colorRgb = gradientRgb[0];
|
|
1737
|
-
} else {
|
|
1738
|
-
gradientRgb = null;
|
|
1739
|
-
colorRgb = colorToRgb(partial.trailColor);
|
|
1740
|
-
}
|
|
1724
|
+
applyColor(partial.trailColor);
|
|
1741
1725
|
needsRebuildBg = true;
|
|
1742
1726
|
}
|
|
1743
1727
|
if (partial.trailStyle !== void 0) {
|
|
@@ -1749,9 +1733,13 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1749
1733
|
if (needsRebuildBg) {
|
|
1750
1734
|
buildBgImageData();
|
|
1751
1735
|
}
|
|
1752
|
-
if (currentTrailStyle !== "default" &&
|
|
1736
|
+
if (currentTrailStyle !== "default" && gradientOklab === null) {
|
|
1737
|
+
console.warn(
|
|
1738
|
+
`[sarmal] dot matrix: trailColor is a single color but trailStyle is "${currentTrailStyle}"; the trail will render as a solid color. Pass an array of hex colors to use a real gradient.`
|
|
1739
|
+
);
|
|
1740
|
+
} else if (currentTrailStyle === "default" && gradientOklab !== null) {
|
|
1753
1741
|
console.warn(
|
|
1754
|
-
|
|
1742
|
+
'[sarmal] dot matrix: trailColor is an array but trailStyle is "default"; only the first color will be used. Pass a gradient trailStyle to use the whole palette.'
|
|
1755
1743
|
);
|
|
1756
1744
|
}
|
|
1757
1745
|
}
|