@sarmal/core 0.24.0 → 0.25.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.
Files changed (51) hide show
  1. package/dist/auto-init.cjs +113 -44
  2. package/dist/auto-init.cjs.map +1 -1
  3. package/dist/auto-init.js +113 -44
  4. package/dist/auto-init.js.map +1 -1
  5. package/dist/curves/artemis2.cjs +79 -11
  6. package/dist/curves/artemis2.cjs.map +1 -1
  7. package/dist/curves/artemis2.d.cts +1 -5
  8. package/dist/curves/artemis2.d.ts +1 -5
  9. package/dist/curves/artemis2.js +79 -11
  10. package/dist/curves/artemis2.js.map +1 -1
  11. package/dist/curves/astroid.d.cts +1 -1
  12. package/dist/curves/astroid.d.ts +1 -1
  13. package/dist/curves/deltoid.d.cts +1 -1
  14. package/dist/curves/deltoid.d.ts +1 -1
  15. package/dist/curves/epicycloid3.d.cts +1 -1
  16. package/dist/curves/epicycloid3.d.ts +1 -1
  17. package/dist/curves/epitrochoid7.d.cts +1 -1
  18. package/dist/curves/epitrochoid7.d.ts +1 -1
  19. package/dist/curves/index.cjs +103 -35
  20. package/dist/curves/index.cjs.map +1 -1
  21. package/dist/curves/index.d.cts +1 -1
  22. package/dist/curves/index.d.ts +1 -1
  23. package/dist/curves/index.js +103 -35
  24. package/dist/curves/index.js.map +1 -1
  25. package/dist/curves/lame.d.cts +1 -1
  26. package/dist/curves/lame.d.ts +1 -1
  27. package/dist/curves/lissajous32.d.cts +1 -1
  28. package/dist/curves/lissajous32.d.ts +1 -1
  29. package/dist/curves/lissajous43.d.cts +1 -1
  30. package/dist/curves/lissajous43.d.ts +1 -1
  31. package/dist/curves/rose3.d.cts +1 -1
  32. package/dist/curves/rose3.d.ts +1 -1
  33. package/dist/curves/rose5.d.cts +1 -1
  34. package/dist/curves/rose5.d.ts +1 -1
  35. package/dist/curves/rose52.d.cts +1 -1
  36. package/dist/curves/rose52.d.ts +1 -1
  37. package/dist/curves/star.d.cts +1 -1
  38. package/dist/curves/star.d.ts +1 -1
  39. package/dist/curves/star4.d.cts +1 -1
  40. package/dist/curves/star4.d.ts +1 -1
  41. package/dist/curves/star7.d.cts +1 -1
  42. package/dist/curves/star7.d.ts +1 -1
  43. package/dist/index.cjs +114 -87
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.d.cts +25 -7
  46. package/dist/index.d.ts +25 -7
  47. package/dist/index.js +114 -88
  48. package/dist/index.js.map +1 -1
  49. package/dist/{types-CknrlCAf.d.cts → types-BZpzgNau.d.cts} +19 -1
  50. package/dist/{types-CknrlCAf.d.ts → types-BZpzgNau.d.ts} +19 -1
  51. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { C as CurveDef } from '../types-CknrlCAf.js';
1
+ import { C as CurveDef } from '../types-BZpzgNau.js';
2
2
 
3
3
  /**
4
4
  * 7-pointed star based on Fourier harmonics.
package/dist/index.cjs CHANGED
@@ -198,25 +198,25 @@ function createEngine(curveDef, trailLength = 120) {
198
198
  },
199
199
  getSarmalSkeleton() {
200
200
  const steps = Math.ceil(curve.period * POINTS_PER_PERIOD_UNIT);
201
- const points = new Array(steps);
201
+ const points2 = new Array(steps);
202
202
  if (morphCurveB !== null && _morphAlpha !== null) {
203
203
  for (let i = 0; i < steps; i++) {
204
204
  const sampleT = i / (steps - 1) * curve.period;
205
205
  const a = sampleSkeleton(curve, sampleT);
206
206
  const tB = _morphStrategy === "normalized" ? sampleT / curve.period * morphCurveB.period : sampleT;
207
207
  const b = sampleSkeleton(morphCurveB, tB);
208
- points[i] = {
208
+ points2[i] = {
209
209
  x: a.x + (b.x - a.x) * _morphAlpha,
210
210
  y: a.y + (b.y - a.y) * _morphAlpha
211
211
  };
212
212
  }
213
- return points;
213
+ return points2;
214
214
  }
215
215
  for (let i = 0; i < steps; i++) {
216
216
  const sampleT = i / (steps - 1) * curve.period;
217
- points[i] = sampleSkeleton(curve, sampleT);
217
+ points2[i] = sampleSkeleton(curve, sampleT);
218
218
  }
219
- return points;
219
+ return points2;
220
220
  },
221
221
  setSpeed(speed) {
222
222
  if (!Number.isFinite(speed)) {
@@ -321,7 +321,7 @@ function computeTrailQuad(trail, i, trailCount, toX, toY, minWidth = TRAIL_MIN_W
321
321
  progress
322
322
  };
323
323
  }
324
- function computeBoundaries(pts, logicalWidth, logicalHeight) {
324
+ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_PADDING_MIN) {
325
325
  if (pts.length === 0) return null;
326
326
  const first = pts[0];
327
327
  let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
@@ -348,8 +348,8 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
348
348
  }
349
349
  const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
350
350
  const scaleYProportional = logicalHeight / (h * (1 + FIT_PADDING * 2));
351
- const scaleXMinPadding = (logicalWidth - FIT_PADDING_MIN * 2) / w;
352
- const scaleYMinPadding = (logicalHeight - FIT_PADDING_MIN * 2) / h;
351
+ const scaleXMinPadding = (logicalWidth - minPaddingPx * 2) / w;
352
+ const scaleYMinPadding = (logicalHeight - minPaddingPx * 2) / h;
353
353
  const scale = Math.min(
354
354
  scaleXProportional,
355
355
  scaleYProportional,
@@ -369,7 +369,8 @@ function enginePassthroughs(engine) {
369
369
  setSpeed: engine.setSpeed,
370
370
  getSpeed: engine.getSpeed,
371
371
  resetSpeed: engine.resetSpeed,
372
- setSpeedOver: engine.setSpeedOver
372
+ setSpeedOver: engine.setSpeedOver,
373
+ getSarmalSkeleton: engine.getSarmalSkeleton
373
374
  };
374
375
  }
375
376
  var palettes = {
@@ -1234,26 +1235,94 @@ function createSarmalSVG(container, curveDef, options) {
1234
1235
  return createSVGRenderer({ container, engine, ...rendererOpts });
1235
1236
  }
1236
1237
 
1237
- // src/curves/artemis2.ts
1238
- var TWO_PI2 = Math.PI * 2;
1239
- function artemis2Fn(t, _time, _params) {
1240
- const a = 0.35, b = 0.15, ox = 0.175;
1241
- const s = Math.sin(t), c = Math.cos(t);
1242
- const denom = 1 + s * s;
1238
+ // src/catmull-rom.ts
1239
+ var PERIOD = 2 * Math.PI;
1240
+ function catmullRom1D(p0, p1, p2, p3, u) {
1241
+ const u2 = u * u;
1242
+ const u3 = u2 * u;
1243
+ return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);
1244
+ }
1245
+ function evaluateCatmullRom(points2, t) {
1246
+ const N = points2.length;
1247
+ if (N === 0) {
1248
+ return { x: 0, y: 0 };
1249
+ }
1250
+ if (N === 1) {
1251
+ return { x: points2[0][0], y: points2[0][1] };
1252
+ }
1253
+ t = (t % PERIOD + PERIOD) % PERIOD;
1254
+ const segmentSize = PERIOD / N;
1255
+ let i = Math.floor(t / segmentSize);
1256
+ if (i >= N) {
1257
+ i = N - 1;
1258
+ }
1259
+ let u = (t - i * segmentSize) / segmentSize;
1260
+ u = Math.max(0, Math.min(1, u));
1261
+ const p0 = points2[(i - 1 + N) % N];
1262
+ const p1 = points2[i];
1263
+ const p2 = points2[(i + 1) % N];
1264
+ const p3 = points2[(i + 2) % N];
1243
1265
  return {
1244
- x: c * (1 + a * c) / denom - ox,
1245
- y: s * c * (1 + b * c) / denom
1266
+ x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),
1267
+ y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u)
1246
1268
  };
1247
1269
  }
1270
+ function drawCurve(points2, opts) {
1271
+ if (points2.length < 3) {
1272
+ throw new Error(`drawCurve requires at least 3 points, received ${points2.length}.`);
1273
+ }
1274
+ const first = points2[0];
1275
+ if (points2.every((p) => p[0] === first[0] && p[1] === first[1])) {
1276
+ console.warn(
1277
+ "[sarmal].drawCurve: all control points are identical. The curve will be a single point."
1278
+ );
1279
+ }
1280
+ const maxAbs = points2.reduce((m, p) => Math.max(m, Math.abs(p[0]), Math.abs(p[1])), 0);
1281
+ if (maxAbs > 2) {
1282
+ console.warn(
1283
+ `[sarmal].drawCurve: control points extend to \xB1${maxAbs.toFixed(1)}, which may render off-screen. Coordinates should be in [-1, 1].`
1284
+ );
1285
+ }
1286
+ const pts = points2.map(([x, y]) => [x, y]);
1287
+ return {
1288
+ name: opts?.name ?? "drawn",
1289
+ fn: (t) => evaluateCatmullRom(pts, t),
1290
+ period: PERIOD,
1291
+ kind: "drawn"
1292
+ };
1293
+ }
1294
+
1295
+ // src/curves/artemis2.ts
1296
+ var points = [
1297
+ [-0.44, -0.45],
1298
+ [-0.53, -0.77],
1299
+ [-0.82, -0.66],
1300
+ [-0.82, -0.18],
1301
+ [-0.25, -0.04],
1302
+ [0.16, -0.49],
1303
+ [-0.03, -0.87],
1304
+ [-0.68, -0.94],
1305
+ [-0.95, -0.61],
1306
+ [-0.87, -0],
1307
+ [-0.34, 0.21],
1308
+ [0.27, -0.04],
1309
+ [0.87, 0.06],
1310
+ [0.87, 0.57],
1311
+ [0.32, 0.66],
1312
+ [-0.21, -0.43],
1313
+ [-0.43, -0.81],
1314
+ [-0.69, -0.84],
1315
+ [-0.87, -0.66],
1316
+ [-0.9, -0.47],
1317
+ [-0.76, -0.35]
1318
+ ];
1248
1319
  var artemis2 = {
1249
- name: "Artemis II",
1250
- fn: artemis2Fn,
1251
- period: TWO_PI2,
1320
+ ...drawCurve(points, { name: "Artemis II" }),
1252
1321
  speed: 0.7
1253
1322
  };
1254
1323
 
1255
1324
  // src/curves/astroid.ts
1256
- var TWO_PI3 = Math.PI * 2;
1325
+ var TWO_PI2 = Math.PI * 2;
1257
1326
  function astroidFn(t, _time, _params) {
1258
1327
  const c = Math.cos(t);
1259
1328
  const s = Math.sin(t);
@@ -1265,12 +1334,12 @@ function astroidFn(t, _time, _params) {
1265
1334
  var astroid = {
1266
1335
  name: "Astroid",
1267
1336
  fn: astroidFn,
1268
- period: TWO_PI3,
1337
+ period: TWO_PI2,
1269
1338
  speed: 1.1
1270
1339
  };
1271
1340
 
1272
1341
  // src/curves/deltoid.ts
1273
- var TWO_PI4 = Math.PI * 2;
1342
+ var TWO_PI3 = Math.PI * 2;
1274
1343
  function deltoidFn(t, _time, _params) {
1275
1344
  return {
1276
1345
  x: 2 * Math.cos(t) + Math.cos(2 * t),
@@ -1280,12 +1349,12 @@ function deltoidFn(t, _time, _params) {
1280
1349
  var deltoid = {
1281
1350
  name: "Deltoid",
1282
1351
  fn: deltoidFn,
1283
- period: TWO_PI4,
1352
+ period: TWO_PI3,
1284
1353
  speed: 0.9
1285
1354
  };
1286
1355
 
1287
1356
  // src/curves/epicycloid3.ts
1288
- var TWO_PI5 = Math.PI * 2;
1357
+ var TWO_PI4 = Math.PI * 2;
1289
1358
  function epicycloid3Fn(t, _time, _params) {
1290
1359
  return {
1291
1360
  x: 4 * Math.cos(t) - Math.cos(4 * t),
@@ -1295,12 +1364,12 @@ function epicycloid3Fn(t, _time, _params) {
1295
1364
  var epicycloid3 = {
1296
1365
  name: "Epicycloid (n=3)",
1297
1366
  fn: epicycloid3Fn,
1298
- period: TWO_PI5,
1367
+ period: TWO_PI4,
1299
1368
  speed: 0.75
1300
1369
  };
1301
1370
 
1302
1371
  // src/curves/epitrochoid7.ts
1303
- var TWO_PI6 = Math.PI * 2;
1372
+ var TWO_PI5 = Math.PI * 2;
1304
1373
  function epitrochoid7Fn(t, _time, _params) {
1305
1374
  const d = 1 + 0.55 * Math.sin(t * 0.5);
1306
1375
  return {
@@ -1318,13 +1387,13 @@ function epitrochoid7SkeletonFn(t) {
1318
1387
  var epitrochoid7 = {
1319
1388
  name: "Epitrochoid",
1320
1389
  fn: epitrochoid7Fn,
1321
- period: TWO_PI6,
1390
+ period: TWO_PI5,
1322
1391
  speed: 1.4,
1323
1392
  skeletonFn: epitrochoid7SkeletonFn
1324
1393
  };
1325
1394
 
1326
1395
  // src/curves/lissajous32.ts
1327
- var TWO_PI7 = Math.PI * 2;
1396
+ var TWO_PI6 = Math.PI * 2;
1328
1397
  function lissajous32Fn(t, time, _params) {
1329
1398
  const phi = time * 0.45;
1330
1399
  return {
@@ -1335,13 +1404,13 @@ function lissajous32Fn(t, time, _params) {
1335
1404
  var lissajous32 = {
1336
1405
  name: "Lissajous 3:2",
1337
1406
  fn: lissajous32Fn,
1338
- period: TWO_PI7,
1407
+ period: TWO_PI6,
1339
1408
  speed: 2,
1340
1409
  skeleton: "live"
1341
1410
  };
1342
1411
 
1343
1412
  // src/curves/lissajous43.ts
1344
- var TWO_PI8 = Math.PI * 2;
1413
+ var TWO_PI7 = Math.PI * 2;
1345
1414
  function lissajous43Fn(t, time, _params) {
1346
1415
  const phi = time * 0.38;
1347
1416
  return {
@@ -1352,13 +1421,13 @@ function lissajous43Fn(t, time, _params) {
1352
1421
  var lissajous43 = {
1353
1422
  name: "Lissajous 4:3",
1354
1423
  fn: lissajous43Fn,
1355
- period: TWO_PI8,
1424
+ period: TWO_PI7,
1356
1425
  speed: 1.8,
1357
1426
  skeleton: "live"
1358
1427
  };
1359
1428
 
1360
1429
  // src/curves/lame.ts
1361
- var TWO_PI9 = Math.PI * 2;
1430
+ var TWO_PI8 = Math.PI * 2;
1362
1431
  function lameFn(t, time, _params) {
1363
1432
  const p = 1.75 + 1.25 * Math.sin(time * 0.48);
1364
1433
  const c = Math.cos(t), s = Math.sin(t);
@@ -1370,13 +1439,13 @@ function lameFn(t, time, _params) {
1370
1439
  var lame = {
1371
1440
  name: "Lam\xE9 Curve",
1372
1441
  fn: lameFn,
1373
- period: TWO_PI9,
1442
+ period: TWO_PI8,
1374
1443
  speed: 1,
1375
1444
  skeleton: "live"
1376
1445
  };
1377
1446
 
1378
1447
  // src/curves/rose3.ts
1379
- var TWO_PI10 = Math.PI * 2;
1448
+ var TWO_PI9 = Math.PI * 2;
1380
1449
  function rose3Fn(t, _time, _params) {
1381
1450
  const r = Math.cos(3 * t);
1382
1451
  return {
@@ -1387,12 +1456,12 @@ function rose3Fn(t, _time, _params) {
1387
1456
  var rose3 = {
1388
1457
  name: "Rose (n=3)",
1389
1458
  fn: rose3Fn,
1390
- period: TWO_PI10,
1459
+ period: TWO_PI9,
1391
1460
  speed: 1.15
1392
1461
  };
1393
1462
 
1394
1463
  // src/curves/rose5.ts
1395
- var TWO_PI11 = Math.PI * 2;
1464
+ var TWO_PI10 = Math.PI * 2;
1396
1465
  function rose5Fn(t, _time, _params) {
1397
1466
  const r = Math.cos(5 * t);
1398
1467
  return {
@@ -1403,7 +1472,7 @@ function rose5Fn(t, _time, _params) {
1403
1472
  var rose5 = {
1404
1473
  name: "Rose (n=5)",
1405
1474
  fn: rose5Fn,
1406
- period: TWO_PI11,
1475
+ period: TWO_PI10,
1407
1476
  speed: 1
1408
1477
  };
1409
1478
 
@@ -1424,7 +1493,7 @@ var rose52 = {
1424
1493
  };
1425
1494
 
1426
1495
  // src/curves/star.ts
1427
- var TWO_PI12 = Math.PI * 2;
1496
+ var TWO_PI11 = Math.PI * 2;
1428
1497
  function starFn(t, _time, _params) {
1429
1498
  const r = Math.abs(Math.cos(5 / 2 * t)) + 0.35 * Math.abs(Math.cos(15 / 2 * t)) + 0.15 * Math.abs(Math.cos(25 / 2 * t));
1430
1499
  return {
@@ -1435,12 +1504,12 @@ function starFn(t, _time, _params) {
1435
1504
  var star = {
1436
1505
  name: "Star",
1437
1506
  fn: starFn,
1438
- period: TWO_PI12,
1507
+ period: TWO_PI11,
1439
1508
  speed: 1
1440
1509
  };
1441
1510
 
1442
1511
  // src/curves/star4.ts
1443
- var TWO_PI13 = Math.PI * 2;
1512
+ var TWO_PI12 = Math.PI * 2;
1444
1513
  function star4Fn(t, _time, _params) {
1445
1514
  const r = Math.abs(Math.cos(2 * t)) + 0.35 * Math.abs(Math.cos(6 * t)) + 0.15 * Math.abs(Math.cos(10 * t));
1446
1515
  return {
@@ -1451,12 +1520,12 @@ function star4Fn(t, _time, _params) {
1451
1520
  var star4 = {
1452
1521
  name: "Star (4-arm)",
1453
1522
  fn: star4Fn,
1454
- period: TWO_PI13,
1523
+ period: TWO_PI12,
1455
1524
  speed: 1
1456
1525
  };
1457
1526
 
1458
1527
  // src/curves/star7.ts
1459
- var TWO_PI14 = Math.PI * 2;
1528
+ var TWO_PI13 = Math.PI * 2;
1460
1529
  function star7Fn(t, _time, _params) {
1461
1530
  const r = Math.abs(Math.cos(7 / 2 * t)) + 0.35 * Math.abs(Math.cos(21 / 2 * t)) + 0.15 * Math.abs(Math.cos(35 / 2 * t));
1462
1531
  return {
@@ -1467,7 +1536,7 @@ function star7Fn(t, _time, _params) {
1467
1536
  var star7 = {
1468
1537
  name: "Star (7-arm)",
1469
1538
  fn: star7Fn,
1470
- period: TWO_PI14,
1539
+ period: TWO_PI13,
1471
1540
  speed: 1
1472
1541
  };
1473
1542
 
@@ -1489,49 +1558,6 @@ var curves = {
1489
1558
  lame
1490
1559
  };
1491
1560
 
1492
- // src/catmull-rom.ts
1493
- var PERIOD = 2 * Math.PI;
1494
- function catmullRom1D(p0, p1, p2, p3, u) {
1495
- const u2 = u * u;
1496
- const u3 = u2 * u;
1497
- return 0.5 * (2 * p1 + (-p0 + p2) * u + (2 * p0 - 5 * p1 + 4 * p2 - p3) * u2 + (-p0 + 3 * p1 - 3 * p2 + p3) * u3);
1498
- }
1499
- function evaluateCatmullRom(points, t) {
1500
- const N = points.length;
1501
- if (N === 0) {
1502
- return { x: 0, y: 0 };
1503
- }
1504
- if (N === 1) {
1505
- return { x: points[0][0], y: points[0][1] };
1506
- }
1507
- t = (t % PERIOD + PERIOD) % PERIOD;
1508
- const segmentSize = PERIOD / N;
1509
- let i = Math.floor(t / segmentSize);
1510
- if (i >= N) {
1511
- i = N - 1;
1512
- }
1513
- let u = (t - i * segmentSize) / segmentSize;
1514
- u = Math.max(0, Math.min(1, u));
1515
- const p0 = points[(i - 1 + N) % N];
1516
- const p1 = points[i];
1517
- const p2 = points[(i + 1) % N];
1518
- const p3 = points[(i + 2) % N];
1519
- return {
1520
- x: catmullRom1D(p0[0], p1[0], p2[0], p3[0], u),
1521
- y: catmullRom1D(p0[1], p1[1], p2[1], p3[1], u)
1522
- };
1523
- }
1524
- function drawCurve(points) {
1525
- if (points.length < 3) {
1526
- throw new Error(`drawCurve requires at least 3 points, received ${points.length}.`);
1527
- }
1528
- return {
1529
- name: "custom",
1530
- fn: (t) => evaluateCatmullRom(points, t),
1531
- period: PERIOD
1532
- };
1533
- }
1534
-
1535
1561
  // src/index.ts
1536
1562
  function createSarmal(canvas, curveDef, options) {
1537
1563
  const { trailLength, ...rendererOpts } = options ?? {};
@@ -1541,6 +1567,7 @@ function createSarmal(canvas, curveDef, options) {
1541
1567
 
1542
1568
  exports.artemis2 = artemis2;
1543
1569
  exports.astroid = astroid;
1570
+ exports.computeBoundaries = computeBoundaries;
1544
1571
  exports.createEngine = createEngine;
1545
1572
  exports.createRenderer = createRenderer;
1546
1573
  exports.createSVGRenderer = createSVGRenderer;