@sarmal/core 0.37.4 → 0.38.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 +111 -14
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +111 -14
- package/dist/auto-init.js.map +1 -1
- 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 +111 -14
- 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 +111 -14
- package/dist/index.js.map +1 -1
- package/dist/{renderer-shared-DElz98PT.d.ts → renderer-shared-2tEwOWJm.d.ts} +1 -1
- package/dist/{renderer-shared-9Xf6sIlx.d.cts → renderer-shared-Bh33A5Av.d.cts} +1 -1
- 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.map +1 -1
- package/dist/{types-D_ERoVvi.d.cts → types-CmPFR9U3.d.cts} +5 -1
- package/dist/{types-D_ERoVvi.d.ts → types-CmPFR9U3.d.ts} +5 -1
- package/package.json +1 -1
package/dist/curves/rose3.d.cts
CHANGED
package/dist/curves/rose3.d.ts
CHANGED
package/dist/curves/rose5.d.cts
CHANGED
package/dist/curves/rose5.d.ts
CHANGED
package/dist/curves/rose52.d.cts
CHANGED
package/dist/curves/rose52.d.ts
CHANGED
package/dist/curves/star.d.cts
CHANGED
package/dist/curves/star.d.ts
CHANGED
package/dist/curves/star4.d.cts
CHANGED
package/dist/curves/star4.d.ts
CHANGED
package/dist/curves/star7.d.cts
CHANGED
package/dist/curves/star7.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -364,15 +364,42 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
|
|
|
364
364
|
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
365
365
|
};
|
|
366
366
|
}
|
|
367
|
-
|
|
367
|
+
var DESTROYED_ERROR = "[sarmal] Instance has been destroyed and cannot be used again. Call pause() instead of destroy() for temporary suspension.";
|
|
368
|
+
function enginePassthroughs(engine, isDestroyed) {
|
|
369
|
+
function guard() {
|
|
370
|
+
if (isDestroyed()) {
|
|
371
|
+
throw new Error(DESTROYED_ERROR);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
368
374
|
return {
|
|
369
|
-
jump
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
375
|
+
jump(phase, options) {
|
|
376
|
+
guard();
|
|
377
|
+
engine.jump(phase, options);
|
|
378
|
+
},
|
|
379
|
+
seek(phase, options) {
|
|
380
|
+
guard();
|
|
381
|
+
engine.seek(phase, options);
|
|
382
|
+
},
|
|
383
|
+
setSpeed(speed) {
|
|
384
|
+
guard();
|
|
385
|
+
engine.setSpeed(speed);
|
|
386
|
+
},
|
|
387
|
+
getSpeed() {
|
|
388
|
+
guard();
|
|
389
|
+
return engine.getSpeed();
|
|
390
|
+
},
|
|
391
|
+
resetSpeed() {
|
|
392
|
+
guard();
|
|
393
|
+
engine.resetSpeed();
|
|
394
|
+
},
|
|
395
|
+
setSpeedOver(speed, duration) {
|
|
396
|
+
guard();
|
|
397
|
+
return engine.setSpeedOver(speed, duration);
|
|
398
|
+
},
|
|
399
|
+
getSarmalSkeleton() {
|
|
400
|
+
guard();
|
|
401
|
+
return engine.getSarmalSkeleton();
|
|
402
|
+
}
|
|
376
403
|
};
|
|
377
404
|
}
|
|
378
405
|
var palettes = {
|
|
@@ -743,6 +770,7 @@ function createRenderer(options) {
|
|
|
743
770
|
let animationId = null;
|
|
744
771
|
let lastTime = 0;
|
|
745
772
|
let pausedByVisibility = false;
|
|
773
|
+
let destroyed = false;
|
|
746
774
|
let morphResolve = null;
|
|
747
775
|
let morphReject = null;
|
|
748
776
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
@@ -914,6 +942,9 @@ function createRenderer(options) {
|
|
|
914
942
|
const shouldAutoStart = options.autoStart !== false;
|
|
915
943
|
const instance = {
|
|
916
944
|
play() {
|
|
945
|
+
if (destroyed) {
|
|
946
|
+
throw new Error(DESTROYED_ERROR);
|
|
947
|
+
}
|
|
917
948
|
if (animationId !== null) {
|
|
918
949
|
return;
|
|
919
950
|
}
|
|
@@ -921,6 +952,9 @@ function createRenderer(options) {
|
|
|
921
952
|
loop();
|
|
922
953
|
},
|
|
923
954
|
pause() {
|
|
955
|
+
if (destroyed) {
|
|
956
|
+
throw new Error(DESTROYED_ERROR);
|
|
957
|
+
}
|
|
924
958
|
if (animationId === null) {
|
|
925
959
|
return;
|
|
926
960
|
}
|
|
@@ -929,24 +963,36 @@ function createRenderer(options) {
|
|
|
929
963
|
engine.cancelSpeedTransition();
|
|
930
964
|
},
|
|
931
965
|
reset() {
|
|
966
|
+
if (destroyed) {
|
|
967
|
+
throw new Error(DESTROYED_ERROR);
|
|
968
|
+
}
|
|
932
969
|
engine.reset();
|
|
933
970
|
trail = [];
|
|
934
971
|
head = null;
|
|
935
972
|
},
|
|
936
973
|
destroy() {
|
|
974
|
+
if (destroyed) {
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
destroyed = true;
|
|
937
978
|
if (animationId !== null) {
|
|
938
979
|
cancelAnimationFrame(animationId);
|
|
939
980
|
animationId = null;
|
|
940
981
|
}
|
|
941
982
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
983
|
+
engine.cancelSpeedTransition();
|
|
942
984
|
if (morphReject !== null) {
|
|
943
|
-
morphReject(new Error("Instance destroyed during morph"));
|
|
985
|
+
morphReject(new Error("[sarmal] Instance destroyed during morph"));
|
|
944
986
|
morphResolve = null;
|
|
945
987
|
morphReject = null;
|
|
946
988
|
}
|
|
989
|
+
ctx.clearRect(0, 0, logicalWidth, logicalHeight);
|
|
947
990
|
},
|
|
948
|
-
...enginePassthroughs(engine),
|
|
991
|
+
...enginePassthroughs(engine, () => destroyed),
|
|
949
992
|
morphTo(target, options2) {
|
|
993
|
+
if (destroyed) {
|
|
994
|
+
throw new Error(DESTROYED_ERROR);
|
|
995
|
+
}
|
|
950
996
|
if (morphResolve !== null) {
|
|
951
997
|
engine.completeMorph();
|
|
952
998
|
morphResolve();
|
|
@@ -963,6 +1009,9 @@ function createRenderer(options) {
|
|
|
963
1009
|
});
|
|
964
1010
|
},
|
|
965
1011
|
setRenderOptions(partial) {
|
|
1012
|
+
if (destroyed) {
|
|
1013
|
+
throw new Error(DESTROYED_ERROR);
|
|
1014
|
+
}
|
|
966
1015
|
validateRenderOptions(partial);
|
|
967
1016
|
if (partial.trailColor !== void 0) {
|
|
968
1017
|
trailColor = partial.trailColor;
|
|
@@ -1217,6 +1266,7 @@ function createSVGRenderer(options) {
|
|
|
1217
1266
|
let animationId = null;
|
|
1218
1267
|
let lastTime = 0;
|
|
1219
1268
|
let pausedByVisibility = false;
|
|
1269
|
+
let destroyed = false;
|
|
1220
1270
|
const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1221
1271
|
let morphResolve = null;
|
|
1222
1272
|
let morphReject = null;
|
|
@@ -1285,6 +1335,9 @@ function createSVGRenderer(options) {
|
|
|
1285
1335
|
const shouldAutoStart = options.autoStart !== false;
|
|
1286
1336
|
const instance = {
|
|
1287
1337
|
play() {
|
|
1338
|
+
if (destroyed) {
|
|
1339
|
+
throw new Error(DESTROYED_ERROR);
|
|
1340
|
+
}
|
|
1288
1341
|
if (animationId !== null) {
|
|
1289
1342
|
return;
|
|
1290
1343
|
}
|
|
@@ -1292,6 +1345,9 @@ function createSVGRenderer(options) {
|
|
|
1292
1345
|
loop();
|
|
1293
1346
|
},
|
|
1294
1347
|
pause() {
|
|
1348
|
+
if (destroyed) {
|
|
1349
|
+
throw new Error(DESTROYED_ERROR);
|
|
1350
|
+
}
|
|
1295
1351
|
if (animationId === null) {
|
|
1296
1352
|
return;
|
|
1297
1353
|
}
|
|
@@ -1300,23 +1356,34 @@ function createSVGRenderer(options) {
|
|
|
1300
1356
|
engine.cancelSpeedTransition();
|
|
1301
1357
|
},
|
|
1302
1358
|
reset() {
|
|
1359
|
+
if (destroyed) {
|
|
1360
|
+
throw new Error(DESTROYED_ERROR);
|
|
1361
|
+
}
|
|
1303
1362
|
engine.reset();
|
|
1304
1363
|
},
|
|
1305
1364
|
destroy() {
|
|
1365
|
+
if (destroyed) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
destroyed = true;
|
|
1306
1369
|
if (animationId !== null) {
|
|
1307
1370
|
cancelAnimationFrame(animationId);
|
|
1308
1371
|
animationId = null;
|
|
1309
1372
|
}
|
|
1310
1373
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1374
|
+
engine.cancelSpeedTransition();
|
|
1311
1375
|
if (morphReject !== null) {
|
|
1312
|
-
morphReject(new Error("Instance destroyed during morph"));
|
|
1376
|
+
morphReject(new Error("[sarmal] Instance destroyed during morph"));
|
|
1313
1377
|
morphResolve = null;
|
|
1314
1378
|
morphReject = null;
|
|
1315
1379
|
}
|
|
1316
1380
|
group.remove();
|
|
1317
1381
|
},
|
|
1318
|
-
...enginePassthroughs(engine),
|
|
1382
|
+
...enginePassthroughs(engine, () => destroyed),
|
|
1319
1383
|
morphTo(target, options2) {
|
|
1384
|
+
if (destroyed) {
|
|
1385
|
+
throw new Error(DESTROYED_ERROR);
|
|
1386
|
+
}
|
|
1320
1387
|
if (morphResolve !== null) {
|
|
1321
1388
|
engine.completeMorph();
|
|
1322
1389
|
morphResolve();
|
|
@@ -1342,6 +1409,9 @@ function createSVGRenderer(options) {
|
|
|
1342
1409
|
});
|
|
1343
1410
|
},
|
|
1344
1411
|
setRenderOptions(partial) {
|
|
1412
|
+
if (destroyed) {
|
|
1413
|
+
throw new Error(DESTROYED_ERROR);
|
|
1414
|
+
}
|
|
1345
1415
|
validateRenderOptions(partial);
|
|
1346
1416
|
const prevTrailStyle = trailStyle;
|
|
1347
1417
|
if (partial.trailColor !== void 0) {
|
|
@@ -1471,6 +1541,7 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1471
1541
|
let animationId = null;
|
|
1472
1542
|
let lastTime = 0;
|
|
1473
1543
|
let pausedByVisibility = false;
|
|
1544
|
+
let destroyed = false;
|
|
1474
1545
|
let morphResolve = null;
|
|
1475
1546
|
let morphReject = null;
|
|
1476
1547
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
@@ -1724,6 +1795,9 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1724
1795
|
const instance = {
|
|
1725
1796
|
/** Starts the animation loop. Does nothing if already running. */
|
|
1726
1797
|
play() {
|
|
1798
|
+
if (destroyed) {
|
|
1799
|
+
throw new Error(DESTROYED_ERROR);
|
|
1800
|
+
}
|
|
1727
1801
|
if (animationId !== null) {
|
|
1728
1802
|
return;
|
|
1729
1803
|
}
|
|
@@ -1732,6 +1806,9 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1732
1806
|
},
|
|
1733
1807
|
/** Pauses the animation loop. Preserves current trail state. */
|
|
1734
1808
|
pause() {
|
|
1809
|
+
if (destroyed) {
|
|
1810
|
+
throw new Error(DESTROYED_ERROR);
|
|
1811
|
+
}
|
|
1735
1812
|
if (animationId === null) {
|
|
1736
1813
|
return;
|
|
1737
1814
|
}
|
|
@@ -1741,29 +1818,46 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1741
1818
|
},
|
|
1742
1819
|
/** Resets the animation to the start of the curve and clears the grid. */
|
|
1743
1820
|
reset() {
|
|
1821
|
+
if (destroyed) {
|
|
1822
|
+
throw new Error(DESTROYED_ERROR);
|
|
1823
|
+
}
|
|
1744
1824
|
engine.reset();
|
|
1745
1825
|
grid.fill(0);
|
|
1746
1826
|
},
|
|
1747
|
-
/**
|
|
1827
|
+
/**
|
|
1828
|
+
* Permanently stops the animation and clears the visual output.
|
|
1829
|
+
* Calling any method on a destroyed instance throws an error.
|
|
1830
|
+
* `destroy()` is idempotent — calling it multiple times is safe.
|
|
1831
|
+
*/
|
|
1748
1832
|
destroy() {
|
|
1833
|
+
if (destroyed) {
|
|
1834
|
+
return;
|
|
1835
|
+
}
|
|
1836
|
+
destroyed = true;
|
|
1749
1837
|
if (animationId !== null) {
|
|
1750
1838
|
cancelAnimationFrame(animationId);
|
|
1751
1839
|
animationId = null;
|
|
1752
1840
|
}
|
|
1753
1841
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1842
|
+
engine.cancelSpeedTransition();
|
|
1754
1843
|
if (morphReject !== null) {
|
|
1755
1844
|
morphReject(new Error("[sarmal] Instance destroyed during morph"));
|
|
1756
1845
|
morphResolve = null;
|
|
1757
1846
|
morphReject = null;
|
|
1758
1847
|
}
|
|
1848
|
+
grid.fill(0);
|
|
1849
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1759
1850
|
},
|
|
1760
|
-
...enginePassthroughs(engine),
|
|
1851
|
+
...enginePassthroughs(engine, () => destroyed),
|
|
1761
1852
|
/**
|
|
1762
1853
|
* Smoothly transitions from the current curve to `target`.
|
|
1763
1854
|
* If a morph is already in progress, it is snapped to completion before the new one starts.
|
|
1764
1855
|
* @returns A Promise that resolves when the transition finishes.
|
|
1765
1856
|
*/
|
|
1766
1857
|
morphTo(target, opts) {
|
|
1858
|
+
if (destroyed) {
|
|
1859
|
+
throw new Error(DESTROYED_ERROR);
|
|
1860
|
+
}
|
|
1767
1861
|
if (morphResolve !== null) {
|
|
1768
1862
|
completeMorphNow();
|
|
1769
1863
|
}
|
|
@@ -1783,6 +1877,9 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1783
1877
|
* ! Validation fails the entire call if any field is invalid, leaving options unchanged.
|
|
1784
1878
|
*/
|
|
1785
1879
|
setRenderOptions(partial) {
|
|
1880
|
+
if (destroyed) {
|
|
1881
|
+
throw new Error(DESTROYED_ERROR);
|
|
1882
|
+
}
|
|
1786
1883
|
validateBaseRenderOptions(partial);
|
|
1787
1884
|
let needsRebuildBg = false;
|
|
1788
1885
|
if (partial.trailColor !== void 0) {
|