@sarmal/core 0.17.1 → 0.18.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 -89
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +112 -88
- package/dist/auto-init.js.map +1 -1
- package/dist/curves/artemis2.cjs +10 -7
- package/dist/curves/artemis2.d.cts +1 -1
- package/dist/curves/artemis2.d.ts +1 -1
- package/dist/curves/artemis2.js +9 -6
- package/dist/curves/astroid.cjs +4 -4
- package/dist/curves/astroid.d.cts +1 -1
- package/dist/curves/astroid.d.ts +1 -1
- package/dist/curves/astroid.js +3 -3
- package/dist/curves/deltoid.cjs +4 -4
- package/dist/curves/deltoid.d.cts +1 -1
- package/dist/curves/deltoid.d.ts +1 -1
- package/dist/curves/deltoid.js +3 -3
- package/dist/curves/epicycloid3.cjs +4 -4
- package/dist/curves/epicycloid3.d.cts +1 -1
- package/dist/curves/epicycloid3.d.ts +1 -1
- package/dist/curves/epicycloid3.js +3 -3
- package/dist/curves/epitrochoid7.cjs +5 -5
- package/dist/curves/epitrochoid7.d.cts +1 -1
- package/dist/curves/epitrochoid7.d.ts +1 -1
- package/dist/curves/epitrochoid7.js +4 -4
- package/dist/curves/index.cjs +53 -40
- package/dist/curves/index.d.cts +29 -29
- package/dist/curves/index.d.ts +29 -29
- package/dist/curves/index.js +69 -40
- package/dist/curves/lame.cjs +6 -5
- package/dist/curves/lame.d.cts +1 -1
- package/dist/curves/lame.d.ts +1 -1
- package/dist/curves/lame.js +5 -4
- package/dist/curves/lissajous32.cjs +4 -4
- package/dist/curves/lissajous32.d.cts +1 -1
- package/dist/curves/lissajous32.d.ts +1 -1
- package/dist/curves/lissajous32.js +3 -3
- package/dist/curves/lissajous43.cjs +4 -4
- package/dist/curves/lissajous43.d.cts +1 -1
- package/dist/curves/lissajous43.d.ts +1 -1
- package/dist/curves/lissajous43.js +3 -3
- package/dist/curves/rose3.cjs +4 -4
- package/dist/curves/rose3.d.cts +1 -1
- package/dist/curves/rose3.d.ts +1 -1
- package/dist/curves/rose3.js +3 -3
- package/dist/curves/rose5.cjs +4 -4
- package/dist/curves/rose5.d.cts +1 -1
- package/dist/curves/rose5.d.ts +1 -1
- package/dist/curves/rose5.js +3 -3
- package/dist/curves/rose52.cjs +5 -5
- package/dist/curves/rose52.d.cts +1 -1
- package/dist/curves/rose52.d.ts +1 -1
- package/dist/curves/rose52.js +4 -4
- package/dist/curves/star.cjs +8 -5
- package/dist/curves/star.d.cts +1 -1
- package/dist/curves/star.d.ts +1 -1
- package/dist/curves/star.js +7 -4
- package/dist/curves/star4.cjs +8 -5
- package/dist/curves/star4.d.cts +1 -1
- package/dist/curves/star4.d.ts +1 -1
- package/dist/curves/star4.js +7 -4
- package/dist/curves/star7.cjs +8 -5
- package/dist/curves/star7.d.cts +1 -1
- package/dist/curves/star7.d.ts +1 -1
- package/dist/curves/star7.js +7 -4
- package/dist/index.cjs +125 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -35
- package/dist/index.d.ts +74 -35
- package/dist/index.js +143 -93
- package/dist/index.js.map +1 -1
- package/dist/types-frtEoAq6.d.cts +317 -0
- package/dist/types-frtEoAq6.d.ts +317 -0
- package/package.json +1 -1
- package/dist/types-BL9HhEmk.d.cts +0 -299
- package/dist/types-BL9HhEmk.d.ts +0 -299
package/dist/index.js
CHANGED
|
@@ -61,13 +61,13 @@ function resolveCurve(curveDef) {
|
|
|
61
61
|
period,
|
|
62
62
|
speed,
|
|
63
63
|
skeleton: curveDef.skeleton,
|
|
64
|
-
skeletonFn: curveDef.skeletonFn
|
|
64
|
+
skeletonFn: curveDef.skeletonFn,
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
67
|
function createEngine(curveDef, trailLength = 120) {
|
|
68
68
|
if (!Number.isFinite(trailLength) || trailLength <= 0) {
|
|
69
69
|
throw new RangeError(
|
|
70
|
-
`[sarmal] trailLength must be a positive finite number, got ${trailLength}
|
|
70
|
+
`[sarmal] trailLength must be a positive finite number, got ${trailLength}`,
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
let curve = resolveCurve(curveDef);
|
|
@@ -108,7 +108,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
108
108
|
actualTime += deltaTime;
|
|
109
109
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
110
110
|
const a = curve.fn(t, actualTime, EMPTY_PARAMS);
|
|
111
|
-
const tB = _morphStrategy === "normalized" ? t / curve.period * morphCurveB.period : t;
|
|
111
|
+
const tB = _morphStrategy === "normalized" ? (t / curve.period) * morphCurveB.period : t;
|
|
112
112
|
const b = morphCurveB.fn(tB, actualTime, EMPTY_PARAMS);
|
|
113
113
|
trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
|
|
114
114
|
} else {
|
|
@@ -120,6 +120,9 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
120
120
|
get trailCount() {
|
|
121
121
|
return trail.length;
|
|
122
122
|
},
|
|
123
|
+
get trailLength() {
|
|
124
|
+
return trailLength;
|
|
125
|
+
},
|
|
123
126
|
get isLiveSkeleton() {
|
|
124
127
|
return curve.skeleton === "live";
|
|
125
128
|
},
|
|
@@ -132,14 +135,14 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
132
135
|
trail.clear();
|
|
133
136
|
},
|
|
134
137
|
jump(newT, { clearTrail = false } = {}) {
|
|
135
|
-
t = (newT % curve.period + curve.period) % curve.period;
|
|
138
|
+
t = ((newT % curve.period) + curve.period) % curve.period;
|
|
136
139
|
if (clearTrail) {
|
|
137
140
|
trail.clear();
|
|
138
141
|
}
|
|
139
142
|
},
|
|
140
143
|
seek(targetT, { wrap = false, step = curve.period / trailLength } = {}) {
|
|
141
144
|
const advance = curve.speed * step;
|
|
142
|
-
const target = (targetT % curve.period + curve.period) % curve.period;
|
|
145
|
+
const target = ((targetT % curve.period) + curve.period) % curve.period;
|
|
143
146
|
const targetTime = target / curve.speed;
|
|
144
147
|
t = target;
|
|
145
148
|
actualTime = targetTime;
|
|
@@ -148,7 +151,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
148
151
|
const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
|
|
149
152
|
for (let i = count - 1; i >= 0; i--) {
|
|
150
153
|
const sampleT = target - i * advance;
|
|
151
|
-
const wrappedT = (sampleT % curve.period + curve.period) % curve.period;
|
|
154
|
+
const wrappedT = ((sampleT % curve.period) + curve.period) % curve.period;
|
|
152
155
|
const time = targetTime - i * step;
|
|
153
156
|
const point = curve.fn(wrappedT, time, EMPTY_PARAMS);
|
|
154
157
|
trail.push(point.x, point.y);
|
|
@@ -165,13 +168,16 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
165
168
|
...frozenB,
|
|
166
169
|
fn: (sampleT, time, params) => {
|
|
167
170
|
const a = frozenA.fn(sampleT, time, params);
|
|
168
|
-
const tB =
|
|
171
|
+
const tB =
|
|
172
|
+
frozenStrategy === "normalized"
|
|
173
|
+
? (sampleT / frozenA.period) * frozenB.period
|
|
174
|
+
: sampleT;
|
|
169
175
|
const b = frozenB.fn(tB, time, params);
|
|
170
176
|
return {
|
|
171
177
|
x: a.x + (b.x - a.x) * frozenAlpha,
|
|
172
|
-
y: a.y + (b.y - a.y) * frozenAlpha
|
|
178
|
+
y: a.y + (b.y - a.y) * frozenAlpha,
|
|
173
179
|
};
|
|
174
|
-
}
|
|
180
|
+
},
|
|
175
181
|
};
|
|
176
182
|
}
|
|
177
183
|
_morphStrategy = strategy;
|
|
@@ -184,7 +190,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
184
190
|
completeMorph() {
|
|
185
191
|
if (morphCurveB !== null) {
|
|
186
192
|
if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
|
|
187
|
-
t = t / curve.period * morphCurveB.period;
|
|
193
|
+
t = (t / curve.period) * morphCurveB.period;
|
|
188
194
|
}
|
|
189
195
|
curve = morphCurveB;
|
|
190
196
|
}
|
|
@@ -196,19 +202,22 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
196
202
|
const points = new Array(steps);
|
|
197
203
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
198
204
|
for (let i = 0; i < steps; i++) {
|
|
199
|
-
const sampleT = i / (steps - 1) * curve.period;
|
|
205
|
+
const sampleT = (i / (steps - 1)) * curve.period;
|
|
200
206
|
const a = sampleSkeleton(curve, sampleT);
|
|
201
|
-
const tB =
|
|
207
|
+
const tB =
|
|
208
|
+
_morphStrategy === "normalized"
|
|
209
|
+
? (sampleT / curve.period) * morphCurveB.period
|
|
210
|
+
: sampleT;
|
|
202
211
|
const b = sampleSkeleton(morphCurveB, tB);
|
|
203
212
|
points[i] = {
|
|
204
213
|
x: a.x + (b.x - a.x) * _morphAlpha,
|
|
205
|
-
y: a.y + (b.y - a.y) * _morphAlpha
|
|
214
|
+
y: a.y + (b.y - a.y) * _morphAlpha,
|
|
206
215
|
};
|
|
207
216
|
}
|
|
208
217
|
return points;
|
|
209
218
|
}
|
|
210
219
|
for (let i = 0; i < steps; i++) {
|
|
211
|
-
const sampleT = i / (steps - 1) * curve.period;
|
|
220
|
+
const sampleT = (i / (steps - 1)) * curve.period;
|
|
212
221
|
points[i] = sampleSkeleton(curve, sampleT);
|
|
213
222
|
}
|
|
214
223
|
return points;
|
|
@@ -250,7 +259,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
250
259
|
_speedTransition.reject(new Error("Speed transition cancelled"));
|
|
251
260
|
_speedTransition = null;
|
|
252
261
|
}
|
|
253
|
-
}
|
|
262
|
+
},
|
|
254
263
|
};
|
|
255
264
|
}
|
|
256
265
|
|
|
@@ -313,13 +322,16 @@ function computeTrailQuad(trail, i, trailCount, toX, toY) {
|
|
|
313
322
|
r1x: nx - n1.x * w1,
|
|
314
323
|
r1y: ny - n1.y * w1,
|
|
315
324
|
opacity,
|
|
316
|
-
progress
|
|
325
|
+
progress,
|
|
317
326
|
};
|
|
318
327
|
}
|
|
319
328
|
function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
320
329
|
if (pts.length === 0) return null;
|
|
321
330
|
const first = pts[0];
|
|
322
|
-
let minX = first.x,
|
|
331
|
+
let minX = first.x,
|
|
332
|
+
maxX = first.x,
|
|
333
|
+
minY = first.y,
|
|
334
|
+
maxY = first.y;
|
|
323
335
|
for (const p of pts) {
|
|
324
336
|
if (p.x < minX) {
|
|
325
337
|
minX = p.x;
|
|
@@ -338,7 +350,7 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
|
338
350
|
const h = maxY - minY;
|
|
339
351
|
if (w === 0 && h === 0) {
|
|
340
352
|
throw new Error(
|
|
341
|
-
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
|
|
353
|
+
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
|
|
342
354
|
);
|
|
343
355
|
}
|
|
344
356
|
const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
|
|
@@ -349,12 +361,12 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
|
349
361
|
scaleXProportional,
|
|
350
362
|
scaleYProportional,
|
|
351
363
|
scaleXMinPadding,
|
|
352
|
-
scaleYMinPadding
|
|
364
|
+
scaleYMinPadding,
|
|
353
365
|
);
|
|
354
366
|
return {
|
|
355
367
|
scale,
|
|
356
368
|
offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
|
|
357
|
-
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
369
|
+
offsetY: (logicalHeight - h * scale) / 2 - minY * scale,
|
|
358
370
|
};
|
|
359
371
|
}
|
|
360
372
|
function enginePassthroughs(engine) {
|
|
@@ -364,7 +376,7 @@ function enginePassthroughs(engine) {
|
|
|
364
376
|
setSpeed: engine.setSpeed,
|
|
365
377
|
getSpeed: engine.getSpeed,
|
|
366
378
|
resetSpeed: engine.resetSpeed,
|
|
367
|
-
setSpeedOver: engine.setSpeedOver
|
|
379
|
+
setSpeedOver: engine.setSpeedOver,
|
|
368
380
|
};
|
|
369
381
|
}
|
|
370
382
|
var palettes = {
|
|
@@ -373,16 +385,16 @@ var palettes = {
|
|
|
373
385
|
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
374
386
|
ice: ["#1e3a8a", "#67e8f9"],
|
|
375
387
|
fire: ["#7f1d1d", "#fbbf24"],
|
|
376
|
-
forest: ["#14532d", "#86efac"]
|
|
388
|
+
forest: ["#14532d", "#86efac"],
|
|
377
389
|
};
|
|
378
390
|
function hexToRgb(hex) {
|
|
379
391
|
const n = parseInt(hex.slice(1), 16);
|
|
380
|
-
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
392
|
+
return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
|
|
381
393
|
}
|
|
382
394
|
var lerpRgb = (a, b, t) => ({
|
|
383
395
|
r: Math.round(a.r + (b.r - a.r) * t),
|
|
384
396
|
g: Math.round(a.g + (b.g - a.g) * t),
|
|
385
|
-
b: Math.round(a.b + (b.b - a.b) * t)
|
|
397
|
+
b: Math.round(a.b + (b.b - a.b) * t),
|
|
386
398
|
});
|
|
387
399
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
388
400
|
if (palette.length === 0) {
|
|
@@ -391,7 +403,7 @@ function getPaletteColor(palette, position, timeOffset = 0) {
|
|
|
391
403
|
if (palette.length === 1) {
|
|
392
404
|
return hexToRgb(palette[0]);
|
|
393
405
|
}
|
|
394
|
-
const cyclePos = (position + timeOffset) % 1;
|
|
406
|
+
const cyclePos = (((position + timeOffset) % 1) + 1) % 1;
|
|
395
407
|
const scaled = cyclePos * palette.length;
|
|
396
408
|
const idx = Math.floor(scaled);
|
|
397
409
|
const t = scaled - idx;
|
|
@@ -405,7 +417,7 @@ var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
|
405
417
|
"trailColor",
|
|
406
418
|
"headColor",
|
|
407
419
|
"skeletonColor",
|
|
408
|
-
"trailStyle"
|
|
420
|
+
"trailStyle",
|
|
409
421
|
]);
|
|
410
422
|
function validateRenderOptions(partial) {
|
|
411
423
|
for (const key of Object.keys(partial)) {
|
|
@@ -430,7 +442,7 @@ function assertTrailColor(value) {
|
|
|
430
442
|
if (typeof value === "string") {
|
|
431
443
|
if (!HEX_COLOR_RE.test(value)) {
|
|
432
444
|
throw new TypeError(
|
|
433
|
-
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"
|
|
445
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`,
|
|
434
446
|
);
|
|
435
447
|
}
|
|
436
448
|
return;
|
|
@@ -438,21 +450,21 @@ function assertTrailColor(value) {
|
|
|
438
450
|
if (Array.isArray(value)) {
|
|
439
451
|
if (value.length < 2) {
|
|
440
452
|
throw new RangeError(
|
|
441
|
-
`[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}
|
|
453
|
+
`[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,
|
|
442
454
|
);
|
|
443
455
|
}
|
|
444
456
|
for (let i = 0; i < value.length; i++) {
|
|
445
457
|
const entry = value[i];
|
|
446
458
|
if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
|
|
447
459
|
throw new TypeError(
|
|
448
|
-
`[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}
|
|
460
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,
|
|
449
461
|
);
|
|
450
462
|
}
|
|
451
463
|
}
|
|
452
464
|
return;
|
|
453
465
|
}
|
|
454
466
|
throw new TypeError(
|
|
455
|
-
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}
|
|
467
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`,
|
|
456
468
|
);
|
|
457
469
|
}
|
|
458
470
|
function assertHeadColor(value) {
|
|
@@ -461,7 +473,7 @@ function assertHeadColor(value) {
|
|
|
461
473
|
}
|
|
462
474
|
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
463
475
|
throw new TypeError(
|
|
464
|
-
`[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}
|
|
476
|
+
`[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`,
|
|
465
477
|
);
|
|
466
478
|
}
|
|
467
479
|
}
|
|
@@ -471,14 +483,14 @@ function assertSkeletonColor(value) {
|
|
|
471
483
|
}
|
|
472
484
|
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
473
485
|
throw new TypeError(
|
|
474
|
-
`[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}
|
|
486
|
+
`[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`,
|
|
475
487
|
);
|
|
476
488
|
}
|
|
477
489
|
}
|
|
478
490
|
function assertTrailStyle(value) {
|
|
479
491
|
if (!TRAIL_STYLES.includes(value)) {
|
|
480
492
|
throw new RangeError(
|
|
481
|
-
`[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}
|
|
493
|
+
`[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`,
|
|
482
494
|
);
|
|
483
495
|
}
|
|
484
496
|
}
|
|
@@ -500,13 +512,13 @@ function resolveHeadColor(trailColor, trailStyle) {
|
|
|
500
512
|
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
501
513
|
if (trailStyle === "default" && Array.isArray(trailColor)) {
|
|
502
514
|
console.warn(
|
|
503
|
-
'[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.'
|
|
515
|
+
'[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.',
|
|
504
516
|
);
|
|
505
517
|
return;
|
|
506
518
|
}
|
|
507
519
|
if (trailStyle !== "default" && typeof trailColor === "string") {
|
|
508
520
|
console.warn(
|
|
509
|
-
`[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
|
|
521
|
+
`[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.`,
|
|
510
522
|
);
|
|
511
523
|
}
|
|
512
524
|
}
|
|
@@ -516,7 +528,7 @@ var getHeadDotRadius = (w, h) => Math.max(1, 3 * Math.sqrt(Math.min(w, h) / 160)
|
|
|
516
528
|
var WHITE_HEX = "#ffffff";
|
|
517
529
|
function hexToRgbComponents(hex) {
|
|
518
530
|
const n = parseInt(hex.slice(1), 16);
|
|
519
|
-
return `${n >> 16},${n >> 8 & 255},${n & 255}`;
|
|
531
|
+
return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
|
|
520
532
|
}
|
|
521
533
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
522
534
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -641,7 +653,7 @@ function createRenderer(options) {
|
|
|
641
653
|
i,
|
|
642
654
|
trailCount,
|
|
643
655
|
toX,
|
|
644
|
-
toY
|
|
656
|
+
toY,
|
|
645
657
|
);
|
|
646
658
|
if (trailStyle === "default") {
|
|
647
659
|
ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
|
|
@@ -802,7 +814,7 @@ function createRenderer(options) {
|
|
|
802
814
|
if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
|
|
803
815
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
804
816
|
}
|
|
805
|
-
}
|
|
817
|
+
},
|
|
806
818
|
};
|
|
807
819
|
if (shouldAutoStart) {
|
|
808
820
|
instance.play();
|
|
@@ -811,10 +823,12 @@ function createRenderer(options) {
|
|
|
811
823
|
}
|
|
812
824
|
|
|
813
825
|
// src/renderer-svg.ts
|
|
814
|
-
var MAX_TRAIL_SEGMENTS = 200;
|
|
815
826
|
var EMPTY_PARAMS2 = {};
|
|
827
|
+
var HIGH_TRAIL_LENGTH_THRESHOLD = 5e3;
|
|
816
828
|
function pointsToPathString(pts, scale, offsetX, offsetY) {
|
|
817
|
-
if (pts.length < 2)
|
|
829
|
+
if (pts.length < 2) {
|
|
830
|
+
return "";
|
|
831
|
+
}
|
|
818
832
|
const px = (p) => (p.x * scale + offsetX).toFixed(2);
|
|
819
833
|
const py = (p) => (p.y * scale + offsetY).toFixed(2);
|
|
820
834
|
let d = `M${px(pts[0])} ${py(pts[0])}`;
|
|
@@ -828,7 +842,7 @@ function sampleCurveSkeleton(curveDef) {
|
|
|
828
842
|
const samples = Math.ceil(period * 50);
|
|
829
843
|
const pts = Array.from({ length: samples });
|
|
830
844
|
for (let i = 0; i < samples; i++) {
|
|
831
|
-
const t = i / (samples - 1) * period;
|
|
845
|
+
const t = (i / (samples - 1)) * period;
|
|
832
846
|
pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(t) : curveDef.fn(t, 0, EMPTY_PARAMS2);
|
|
833
847
|
}
|
|
834
848
|
return pts;
|
|
@@ -838,6 +852,12 @@ function el(tag) {
|
|
|
838
852
|
}
|
|
839
853
|
function createSVGRenderer(options) {
|
|
840
854
|
const { container, engine } = options;
|
|
855
|
+
const poolSize = engine.trailLength;
|
|
856
|
+
if (poolSize > HIGH_TRAIL_LENGTH_THRESHOLD) {
|
|
857
|
+
console.warn(
|
|
858
|
+
`[sarmal] High trailLength in SVG renderer (${poolSize}). Consider using the canvas renderer for long trails.`,
|
|
859
|
+
);
|
|
860
|
+
}
|
|
841
861
|
let trailStyle = options.trailStyle ?? "default";
|
|
842
862
|
let trailColor = options.trailColor ?? "#ffffff";
|
|
843
863
|
let skeletonColor = options.skeletonColor ?? "#ffffff";
|
|
@@ -885,7 +905,7 @@ function createSVGRenderer(options) {
|
|
|
885
905
|
let morphPathABuilt = "";
|
|
886
906
|
let morphPathBBuilt = "";
|
|
887
907
|
const trailPaths = [];
|
|
888
|
-
for (let i = 0; i <
|
|
908
|
+
for (let i = 0; i < poolSize; i++) {
|
|
889
909
|
const path = el("path");
|
|
890
910
|
path.setAttribute("fill", trailSolid);
|
|
891
911
|
svg.appendChild(path);
|
|
@@ -930,24 +950,22 @@ function createSVGRenderer(options) {
|
|
|
930
950
|
}
|
|
931
951
|
return;
|
|
932
952
|
}
|
|
933
|
-
const
|
|
934
|
-
|
|
935
|
-
for (let i = startIdx; i < trailCount - 1; i++) {
|
|
936
|
-
const j = i - startIdx;
|
|
953
|
+
const drawnCount = trailCount - 1;
|
|
954
|
+
for (let i = 0; i < drawnCount; i++) {
|
|
937
955
|
const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(
|
|
938
956
|
trail,
|
|
939
957
|
i,
|
|
940
958
|
trailCount,
|
|
941
959
|
px,
|
|
942
|
-
py
|
|
960
|
+
py,
|
|
943
961
|
);
|
|
944
962
|
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`;
|
|
945
|
-
trailPaths[
|
|
946
|
-
trailPaths[
|
|
963
|
+
trailPaths[i].setAttribute("d", d);
|
|
964
|
+
trailPaths[i].setAttribute("fill-opacity", opacity.toFixed(3));
|
|
947
965
|
if (trailStyle !== "default") {
|
|
948
966
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
949
967
|
const { r, g, b } = getPaletteColor(trailPalette, progress, timeOffset);
|
|
950
|
-
trailPaths[
|
|
968
|
+
trailPaths[i].setAttribute("fill", `rgb(${r},${g},${b})`);
|
|
951
969
|
}
|
|
952
970
|
}
|
|
953
971
|
for (let i = drawnCount; i < trailPaths.length; i++) {
|
|
@@ -966,7 +984,8 @@ function createSVGRenderer(options) {
|
|
|
966
984
|
}
|
|
967
985
|
let animationId = null;
|
|
968
986
|
let lastTime = 0;
|
|
969
|
-
const prefersReducedMotion =
|
|
987
|
+
const prefersReducedMotion =
|
|
988
|
+
typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
970
989
|
let morphResolve = null;
|
|
971
990
|
let morphReject = null;
|
|
972
991
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
@@ -984,7 +1003,7 @@ function createSVGRenderer(options) {
|
|
|
984
1003
|
skeletonPathA.setAttribute("visibility", "visible");
|
|
985
1004
|
skeletonPathA.setAttribute(
|
|
986
1005
|
"stroke-opacity",
|
|
987
|
-
String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY)
|
|
1006
|
+
String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),
|
|
988
1007
|
);
|
|
989
1008
|
}
|
|
990
1009
|
if (morphPathBBuilt) {
|
|
@@ -1133,7 +1152,7 @@ function createSVGRenderer(options) {
|
|
|
1133
1152
|
if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
|
|
1134
1153
|
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
1135
1154
|
}
|
|
1136
|
-
}
|
|
1155
|
+
},
|
|
1137
1156
|
};
|
|
1138
1157
|
if (shouldAutoStart) {
|
|
1139
1158
|
instance.play();
|
|
@@ -1149,19 +1168,22 @@ function createSarmalSVG(container, curveDef, options) {
|
|
|
1149
1168
|
// src/curves/artemis2.ts
|
|
1150
1169
|
var TWO_PI2 = Math.PI * 2;
|
|
1151
1170
|
function artemis2Fn(t, _time, _params) {
|
|
1152
|
-
const a = 0.35,
|
|
1153
|
-
|
|
1171
|
+
const a = 0.35,
|
|
1172
|
+
b = 0.15,
|
|
1173
|
+
ox = 0.175;
|
|
1174
|
+
const s = Math.sin(t),
|
|
1175
|
+
c = Math.cos(t);
|
|
1154
1176
|
const denom = 1 + s * s;
|
|
1155
1177
|
return {
|
|
1156
|
-
x: c * (1 + a * c) / denom - ox,
|
|
1157
|
-
y: s * c * (1 + b * c) / denom
|
|
1178
|
+
x: (c * (1 + a * c)) / denom - ox,
|
|
1179
|
+
y: (s * c * (1 + b * c)) / denom,
|
|
1158
1180
|
};
|
|
1159
1181
|
}
|
|
1160
1182
|
var artemis2 = {
|
|
1161
1183
|
name: "Artemis II",
|
|
1162
1184
|
fn: artemis2Fn,
|
|
1163
1185
|
period: TWO_PI2,
|
|
1164
|
-
speed: 0.7
|
|
1186
|
+
speed: 0.7,
|
|
1165
1187
|
};
|
|
1166
1188
|
|
|
1167
1189
|
// src/curves/astroid.ts
|
|
@@ -1171,14 +1193,14 @@ function astroidFn(t, _time, _params) {
|
|
|
1171
1193
|
const s = Math.sin(t);
|
|
1172
1194
|
return {
|
|
1173
1195
|
x: c * c * c,
|
|
1174
|
-
y: s * s * s
|
|
1196
|
+
y: s * s * s,
|
|
1175
1197
|
};
|
|
1176
1198
|
}
|
|
1177
1199
|
var astroid = {
|
|
1178
1200
|
name: "Astroid",
|
|
1179
1201
|
fn: astroidFn,
|
|
1180
1202
|
period: TWO_PI3,
|
|
1181
|
-
speed: 1.1
|
|
1203
|
+
speed: 1.1,
|
|
1182
1204
|
};
|
|
1183
1205
|
|
|
1184
1206
|
// src/curves/deltoid.ts
|
|
@@ -1186,14 +1208,14 @@ var TWO_PI4 = Math.PI * 2;
|
|
|
1186
1208
|
function deltoidFn(t, _time, _params) {
|
|
1187
1209
|
return {
|
|
1188
1210
|
x: 2 * Math.cos(t) + Math.cos(2 * t),
|
|
1189
|
-
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
1211
|
+
y: 2 * Math.sin(t) - Math.sin(2 * t),
|
|
1190
1212
|
};
|
|
1191
1213
|
}
|
|
1192
1214
|
var deltoid = {
|
|
1193
1215
|
name: "Deltoid",
|
|
1194
1216
|
fn: deltoidFn,
|
|
1195
1217
|
period: TWO_PI4,
|
|
1196
|
-
speed: 0.9
|
|
1218
|
+
speed: 0.9,
|
|
1197
1219
|
};
|
|
1198
1220
|
|
|
1199
1221
|
// src/curves/epicycloid3.ts
|
|
@@ -1201,14 +1223,14 @@ var TWO_PI5 = Math.PI * 2;
|
|
|
1201
1223
|
function epicycloid3Fn(t, _time, _params) {
|
|
1202
1224
|
return {
|
|
1203
1225
|
x: 4 * Math.cos(t) - Math.cos(4 * t),
|
|
1204
|
-
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
1226
|
+
y: 4 * Math.sin(t) - Math.sin(4 * t),
|
|
1205
1227
|
};
|
|
1206
1228
|
}
|
|
1207
1229
|
var epicycloid3 = {
|
|
1208
1230
|
name: "Epicycloid (n=3)",
|
|
1209
1231
|
fn: epicycloid3Fn,
|
|
1210
1232
|
period: TWO_PI5,
|
|
1211
|
-
speed: 0.75
|
|
1233
|
+
speed: 0.75,
|
|
1212
1234
|
};
|
|
1213
1235
|
|
|
1214
1236
|
// src/curves/epitrochoid7.ts
|
|
@@ -1217,14 +1239,14 @@ function epitrochoid7Fn(t, _time, _params) {
|
|
|
1217
1239
|
const d = 1 + 0.55 * Math.sin(t * 0.5);
|
|
1218
1240
|
return {
|
|
1219
1241
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
1220
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
1242
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
1221
1243
|
};
|
|
1222
1244
|
}
|
|
1223
1245
|
function epitrochoid7SkeletonFn(t) {
|
|
1224
1246
|
const d = 1.275;
|
|
1225
1247
|
return {
|
|
1226
1248
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
1227
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
1249
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
1228
1250
|
};
|
|
1229
1251
|
}
|
|
1230
1252
|
var epitrochoid7 = {
|
|
@@ -1232,7 +1254,7 @@ var epitrochoid7 = {
|
|
|
1232
1254
|
fn: epitrochoid7Fn,
|
|
1233
1255
|
period: TWO_PI6,
|
|
1234
1256
|
speed: 1.4,
|
|
1235
|
-
skeletonFn: epitrochoid7SkeletonFn
|
|
1257
|
+
skeletonFn: epitrochoid7SkeletonFn,
|
|
1236
1258
|
};
|
|
1237
1259
|
|
|
1238
1260
|
// src/curves/lissajous32.ts
|
|
@@ -1241,7 +1263,7 @@ function lissajous32Fn(t, time, _params) {
|
|
|
1241
1263
|
const phi = time * 0.45;
|
|
1242
1264
|
return {
|
|
1243
1265
|
x: Math.sin(3 * t + phi),
|
|
1244
|
-
y: Math.sin(2 * t)
|
|
1266
|
+
y: Math.sin(2 * t),
|
|
1245
1267
|
};
|
|
1246
1268
|
}
|
|
1247
1269
|
var lissajous32 = {
|
|
@@ -1249,7 +1271,7 @@ var lissajous32 = {
|
|
|
1249
1271
|
fn: lissajous32Fn,
|
|
1250
1272
|
period: TWO_PI7,
|
|
1251
1273
|
speed: 2,
|
|
1252
|
-
skeleton: "live"
|
|
1274
|
+
skeleton: "live",
|
|
1253
1275
|
};
|
|
1254
1276
|
|
|
1255
1277
|
// src/curves/lissajous43.ts
|
|
@@ -1258,7 +1280,7 @@ function lissajous43Fn(t, time, _params) {
|
|
|
1258
1280
|
const phi = time * 0.38;
|
|
1259
1281
|
return {
|
|
1260
1282
|
x: Math.sin(4 * t + phi),
|
|
1261
|
-
y: Math.sin(3 * t)
|
|
1283
|
+
y: Math.sin(3 * t),
|
|
1262
1284
|
};
|
|
1263
1285
|
}
|
|
1264
1286
|
var lissajous43 = {
|
|
@@ -1266,17 +1288,18 @@ var lissajous43 = {
|
|
|
1266
1288
|
fn: lissajous43Fn,
|
|
1267
1289
|
period: TWO_PI8,
|
|
1268
1290
|
speed: 1.8,
|
|
1269
|
-
skeleton: "live"
|
|
1291
|
+
skeleton: "live",
|
|
1270
1292
|
};
|
|
1271
1293
|
|
|
1272
1294
|
// src/curves/lame.ts
|
|
1273
1295
|
var TWO_PI9 = Math.PI * 2;
|
|
1274
1296
|
function lameFn(t, time, _params) {
|
|
1275
1297
|
const p = 1.75 + 1.25 * Math.sin(time * 0.48);
|
|
1276
|
-
const c = Math.cos(t),
|
|
1298
|
+
const c = Math.cos(t),
|
|
1299
|
+
s = Math.sin(t);
|
|
1277
1300
|
return {
|
|
1278
1301
|
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
1279
|
-
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
1302
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p),
|
|
1280
1303
|
};
|
|
1281
1304
|
}
|
|
1282
1305
|
var lame = {
|
|
@@ -1284,7 +1307,7 @@ var lame = {
|
|
|
1284
1307
|
fn: lameFn,
|
|
1285
1308
|
period: TWO_PI9,
|
|
1286
1309
|
speed: 1,
|
|
1287
|
-
skeleton: "live"
|
|
1310
|
+
skeleton: "live",
|
|
1288
1311
|
};
|
|
1289
1312
|
|
|
1290
1313
|
// src/curves/rose3.ts
|
|
@@ -1293,14 +1316,14 @@ function rose3Fn(t, _time, _params) {
|
|
|
1293
1316
|
const r = Math.cos(3 * t);
|
|
1294
1317
|
return {
|
|
1295
1318
|
x: r * Math.cos(t),
|
|
1296
|
-
y: r * Math.sin(t)
|
|
1319
|
+
y: r * Math.sin(t),
|
|
1297
1320
|
};
|
|
1298
1321
|
}
|
|
1299
1322
|
var rose3 = {
|
|
1300
1323
|
name: "Rose (n=3)",
|
|
1301
1324
|
fn: rose3Fn,
|
|
1302
1325
|
period: TWO_PI10,
|
|
1303
|
-
speed: 1.15
|
|
1326
|
+
speed: 1.15,
|
|
1304
1327
|
};
|
|
1305
1328
|
|
|
1306
1329
|
// src/curves/rose5.ts
|
|
@@ -1309,78 +1332,87 @@ function rose5Fn(t, _time, _params) {
|
|
|
1309
1332
|
const r = Math.cos(5 * t);
|
|
1310
1333
|
return {
|
|
1311
1334
|
x: r * Math.cos(t),
|
|
1312
|
-
y: r * Math.sin(t)
|
|
1335
|
+
y: r * Math.sin(t),
|
|
1313
1336
|
};
|
|
1314
1337
|
}
|
|
1315
1338
|
var rose5 = {
|
|
1316
1339
|
name: "Rose (n=5)",
|
|
1317
1340
|
fn: rose5Fn,
|
|
1318
1341
|
period: TWO_PI11,
|
|
1319
|
-
speed: 1
|
|
1342
|
+
speed: 1,
|
|
1320
1343
|
};
|
|
1321
1344
|
|
|
1322
1345
|
// src/curves/rose52.ts
|
|
1323
1346
|
var FOUR_PI = Math.PI * 4;
|
|
1324
1347
|
function rose52Fn(t, _time, _params) {
|
|
1325
|
-
const r = Math.cos(5 / 2 * t);
|
|
1348
|
+
const r = Math.cos((5 / 2) * t);
|
|
1326
1349
|
return {
|
|
1327
1350
|
x: r * Math.cos(t),
|
|
1328
|
-
y: r * Math.sin(t)
|
|
1351
|
+
y: r * Math.sin(t),
|
|
1329
1352
|
};
|
|
1330
1353
|
}
|
|
1331
1354
|
var rose52 = {
|
|
1332
1355
|
name: "Rose (n=5/2)",
|
|
1333
1356
|
fn: rose52Fn,
|
|
1334
1357
|
period: FOUR_PI,
|
|
1335
|
-
speed: 0.8
|
|
1358
|
+
speed: 0.8,
|
|
1336
1359
|
};
|
|
1337
1360
|
|
|
1338
1361
|
// src/curves/star.ts
|
|
1339
1362
|
var TWO_PI12 = Math.PI * 2;
|
|
1340
1363
|
function starFn(t, _time, _params) {
|
|
1341
|
-
const r =
|
|
1364
|
+
const r =
|
|
1365
|
+
Math.abs(Math.cos((5 / 2) * t)) +
|
|
1366
|
+
0.35 * Math.abs(Math.cos((15 / 2) * t)) +
|
|
1367
|
+
0.15 * Math.abs(Math.cos((25 / 2) * t));
|
|
1342
1368
|
return {
|
|
1343
1369
|
x: r * Math.cos(t),
|
|
1344
|
-
y: r * Math.sin(t)
|
|
1370
|
+
y: r * Math.sin(t),
|
|
1345
1371
|
};
|
|
1346
1372
|
}
|
|
1347
1373
|
var star = {
|
|
1348
1374
|
name: "Star",
|
|
1349
1375
|
fn: starFn,
|
|
1350
1376
|
period: TWO_PI12,
|
|
1351
|
-
speed: 1
|
|
1377
|
+
speed: 1,
|
|
1352
1378
|
};
|
|
1353
1379
|
|
|
1354
1380
|
// src/curves/star4.ts
|
|
1355
1381
|
var TWO_PI13 = Math.PI * 2;
|
|
1356
1382
|
function star4Fn(t, _time, _params) {
|
|
1357
|
-
const r =
|
|
1383
|
+
const r =
|
|
1384
|
+
Math.abs(Math.cos(2 * t)) +
|
|
1385
|
+
0.35 * Math.abs(Math.cos(6 * t)) +
|
|
1386
|
+
0.15 * Math.abs(Math.cos(10 * t));
|
|
1358
1387
|
return {
|
|
1359
1388
|
x: r * Math.cos(t),
|
|
1360
|
-
y: r * Math.sin(t)
|
|
1389
|
+
y: r * Math.sin(t),
|
|
1361
1390
|
};
|
|
1362
1391
|
}
|
|
1363
1392
|
var star4 = {
|
|
1364
1393
|
name: "Star (4-arm)",
|
|
1365
1394
|
fn: star4Fn,
|
|
1366
1395
|
period: TWO_PI13,
|
|
1367
|
-
speed: 1
|
|
1396
|
+
speed: 1,
|
|
1368
1397
|
};
|
|
1369
1398
|
|
|
1370
1399
|
// src/curves/star7.ts
|
|
1371
1400
|
var TWO_PI14 = Math.PI * 2;
|
|
1372
1401
|
function star7Fn(t, _time, _params) {
|
|
1373
|
-
const r =
|
|
1402
|
+
const r =
|
|
1403
|
+
Math.abs(Math.cos((7 / 2) * t)) +
|
|
1404
|
+
0.35 * Math.abs(Math.cos((21 / 2) * t)) +
|
|
1405
|
+
0.15 * Math.abs(Math.cos((35 / 2) * t));
|
|
1374
1406
|
return {
|
|
1375
1407
|
x: r * Math.cos(t),
|
|
1376
|
-
y: r * Math.sin(t)
|
|
1408
|
+
y: r * Math.sin(t),
|
|
1377
1409
|
};
|
|
1378
1410
|
}
|
|
1379
1411
|
var star7 = {
|
|
1380
1412
|
name: "Star (7-arm)",
|
|
1381
1413
|
fn: star7Fn,
|
|
1382
1414
|
period: TWO_PI14,
|
|
1383
|
-
speed: 1
|
|
1415
|
+
speed: 1,
|
|
1384
1416
|
};
|
|
1385
1417
|
|
|
1386
1418
|
// src/curves/index.ts
|
|
@@ -1398,7 +1430,7 @@ var curves = {
|
|
|
1398
1430
|
lissajous32,
|
|
1399
1431
|
lissajous43,
|
|
1400
1432
|
epicycloid3,
|
|
1401
|
-
lame
|
|
1433
|
+
lame,
|
|
1402
1434
|
};
|
|
1403
1435
|
|
|
1404
1436
|
// src/index.ts
|
|
@@ -1408,6 +1440,24 @@ function createSarmal(canvas, curveDef, options) {
|
|
|
1408
1440
|
return createRenderer({ canvas, engine, ...rendererOpts });
|
|
1409
1441
|
}
|
|
1410
1442
|
|
|
1411
|
-
export {
|
|
1443
|
+
export {
|
|
1444
|
+
artemis2,
|
|
1445
|
+
astroid,
|
|
1446
|
+
createEngine,
|
|
1447
|
+
createRenderer,
|
|
1448
|
+
createSVGRenderer,
|
|
1449
|
+
createSarmal,
|
|
1450
|
+
createSarmalSVG,
|
|
1451
|
+
curves,
|
|
1452
|
+
deltoid,
|
|
1453
|
+
epicycloid3,
|
|
1454
|
+
epitrochoid7,
|
|
1455
|
+
lame,
|
|
1456
|
+
lissajous32,
|
|
1457
|
+
lissajous43,
|
|
1458
|
+
palettes,
|
|
1459
|
+
rose3,
|
|
1460
|
+
rose5,
|
|
1461
|
+
};
|
|
1462
|
+
//# sourceMappingURL=index.js.map
|
|
1412
1463
|
//# sourceMappingURL=index.js.map
|
|
1413
|
-
//# sourceMappingURL=index.js.map
|