@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.
- package/dist/auto-init.cjs +113 -44
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +113 -44
- package/dist/auto-init.js.map +1 -1
- package/dist/curves/artemis2.cjs +79 -11
- package/dist/curves/artemis2.cjs.map +1 -1
- package/dist/curves/artemis2.d.cts +1 -5
- package/dist/curves/artemis2.d.ts +1 -5
- package/dist/curves/artemis2.js +79 -11
- package/dist/curves/artemis2.js.map +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.cjs +103 -35
- package/dist/curves/index.cjs.map +1 -1
- package/dist/curves/index.d.cts +1 -1
- package/dist/curves/index.d.ts +1 -1
- package/dist/curves/index.js +103 -35
- package/dist/curves/index.js.map +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 +114 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -7
- package/dist/index.d.ts +25 -7
- package/dist/index.js +114 -88
- package/dist/index.js.map +1 -1
- package/dist/{types-CknrlCAf.d.cts → types-BZpzgNau.d.cts} +19 -1
- package/dist/{types-CknrlCAf.d.ts → types-BZpzgNau.d.ts} +19 -1
- package/package.json +1 -1
package/dist/curves/star7.d.ts
CHANGED
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
|
|
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
|
-
|
|
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
|
|
213
|
+
return points2;
|
|
214
214
|
}
|
|
215
215
|
for (let i = 0; i < steps; i++) {
|
|
216
216
|
const sampleT = i / (steps - 1) * curve.period;
|
|
217
|
-
|
|
217
|
+
points2[i] = sampleSkeleton(curve, sampleT);
|
|
218
218
|
}
|
|
219
|
-
return
|
|
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 -
|
|
352
|
-
const scaleYMinPadding = (logicalHeight -
|
|
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/
|
|
1238
|
-
var
|
|
1239
|
-
function
|
|
1240
|
-
const
|
|
1241
|
-
const
|
|
1242
|
-
|
|
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:
|
|
1245
|
-
y:
|
|
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
|
|
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:
|
|
1337
|
+
period: TWO_PI2,
|
|
1269
1338
|
speed: 1.1
|
|
1270
1339
|
};
|
|
1271
1340
|
|
|
1272
1341
|
// src/curves/deltoid.ts
|
|
1273
|
-
var
|
|
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:
|
|
1352
|
+
period: TWO_PI3,
|
|
1284
1353
|
speed: 0.9
|
|
1285
1354
|
};
|
|
1286
1355
|
|
|
1287
1356
|
// src/curves/epicycloid3.ts
|
|
1288
|
-
var
|
|
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:
|
|
1367
|
+
period: TWO_PI4,
|
|
1299
1368
|
speed: 0.75
|
|
1300
1369
|
};
|
|
1301
1370
|
|
|
1302
1371
|
// src/curves/epitrochoid7.ts
|
|
1303
|
-
var
|
|
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:
|
|
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
|
|
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:
|
|
1407
|
+
period: TWO_PI6,
|
|
1339
1408
|
speed: 2,
|
|
1340
1409
|
skeleton: "live"
|
|
1341
1410
|
};
|
|
1342
1411
|
|
|
1343
1412
|
// src/curves/lissajous43.ts
|
|
1344
|
-
var
|
|
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:
|
|
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
|
|
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:
|
|
1442
|
+
period: TWO_PI8,
|
|
1374
1443
|
speed: 1,
|
|
1375
1444
|
skeleton: "live"
|
|
1376
1445
|
};
|
|
1377
1446
|
|
|
1378
1447
|
// src/curves/rose3.ts
|
|
1379
|
-
var
|
|
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:
|
|
1459
|
+
period: TWO_PI9,
|
|
1391
1460
|
speed: 1.15
|
|
1392
1461
|
};
|
|
1393
1462
|
|
|
1394
1463
|
// src/curves/rose5.ts
|
|
1395
|
-
var
|
|
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:
|
|
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
|
|
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:
|
|
1507
|
+
period: TWO_PI11,
|
|
1439
1508
|
speed: 1
|
|
1440
1509
|
};
|
|
1441
1510
|
|
|
1442
1511
|
// src/curves/star4.ts
|
|
1443
|
-
var
|
|
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:
|
|
1523
|
+
period: TWO_PI12,
|
|
1455
1524
|
speed: 1
|
|
1456
1525
|
};
|
|
1457
1526
|
|
|
1458
1527
|
// src/curves/star7.ts
|
|
1459
|
-
var
|
|
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:
|
|
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;
|