@sarmal/core 0.12.0 → 0.13.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 +114 -82
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.d.cts +1 -2
- package/dist/auto-init.d.ts +1 -2
- package/dist/auto-init.js +113 -81
- 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 +32 -28
- package/dist/curves/index.d.cts +21 -21
- package/dist/curves/index.d.ts +21 -21
- package/dist/curves/index.js +44 -28
- 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/index.cjs +135 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -34
- package/dist/index.d.ts +69 -34
- package/dist/index.js +152 -87
- package/dist/index.js.map +1 -1
- package/dist/types-BW0bpL1Z.d.cts +290 -0
- package/dist/types-BW0bpL1Z.d.ts +290 -0
- package/package.json +1 -1
- package/dist/types-BzgdhxE0.d.cts +0 -260
- package/dist/types-BzgdhxE0.d.ts +0 -260
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
3
|
// src/engine.ts
|
|
4
4
|
var TWO_PI = Math.PI * 2;
|
|
@@ -63,13 +63,13 @@ function resolveCurve(curveDef) {
|
|
|
63
63
|
period,
|
|
64
64
|
speed,
|
|
65
65
|
skeleton: curveDef.skeleton,
|
|
66
|
-
skeletonFn: curveDef.skeletonFn
|
|
66
|
+
skeletonFn: curveDef.skeletonFn,
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
function createEngine(curveDef, trailLength = 120) {
|
|
70
70
|
if (!Number.isFinite(trailLength) || trailLength <= 0) {
|
|
71
71
|
throw new RangeError(
|
|
72
|
-
`[sarmal] trailLength must be a positive finite number, got ${trailLength}
|
|
72
|
+
`[sarmal] trailLength must be a positive finite number, got ${trailLength}`,
|
|
73
73
|
);
|
|
74
74
|
}
|
|
75
75
|
let curve = resolveCurve(curveDef);
|
|
@@ -110,7 +110,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
110
110
|
actualTime += deltaTime;
|
|
111
111
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
112
112
|
const a = curve.fn(t, actualTime, EMPTY_PARAMS);
|
|
113
|
-
const tB = _morphStrategy === "normalized" ? t / curve.period * morphCurveB.period : t;
|
|
113
|
+
const tB = _morphStrategy === "normalized" ? (t / curve.period) * morphCurveB.period : t;
|
|
114
114
|
const b = morphCurveB.fn(tB, actualTime, EMPTY_PARAMS);
|
|
115
115
|
trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
|
|
116
116
|
} else {
|
|
@@ -134,14 +134,14 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
134
134
|
trail.clear();
|
|
135
135
|
},
|
|
136
136
|
jump(newT, { clearTrail = false } = {}) {
|
|
137
|
-
t = (newT % curve.period + curve.period) % curve.period;
|
|
137
|
+
t = ((newT % curve.period) + curve.period) % curve.period;
|
|
138
138
|
if (clearTrail) {
|
|
139
139
|
trail.clear();
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
142
|
seek(targetT, { wrap = false, step = curve.period / trailLength } = {}) {
|
|
143
143
|
const advance = curve.speed * step;
|
|
144
|
-
const target = (targetT % curve.period + curve.period) % curve.period;
|
|
144
|
+
const target = ((targetT % curve.period) + curve.period) % curve.period;
|
|
145
145
|
const targetTime = target / curve.speed;
|
|
146
146
|
t = target;
|
|
147
147
|
actualTime = targetTime;
|
|
@@ -150,7 +150,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
150
150
|
const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
|
|
151
151
|
for (let i = count - 1; i >= 0; i--) {
|
|
152
152
|
const sampleT = target - i * advance;
|
|
153
|
-
const wrappedT = (sampleT % curve.period + curve.period) % curve.period;
|
|
153
|
+
const wrappedT = ((sampleT % curve.period) + curve.period) % curve.period;
|
|
154
154
|
const time = targetTime - i * step;
|
|
155
155
|
const point = curve.fn(wrappedT, time, EMPTY_PARAMS);
|
|
156
156
|
trail.push(point.x, point.y);
|
|
@@ -167,13 +167,16 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
167
167
|
...frozenB,
|
|
168
168
|
fn: (sampleT, time, params) => {
|
|
169
169
|
const a = frozenA.fn(sampleT, time, params);
|
|
170
|
-
const tB =
|
|
170
|
+
const tB =
|
|
171
|
+
frozenStrategy === "normalized"
|
|
172
|
+
? (sampleT / frozenA.period) * frozenB.period
|
|
173
|
+
: sampleT;
|
|
171
174
|
const b = frozenB.fn(tB, time, params);
|
|
172
175
|
return {
|
|
173
176
|
x: a.x + (b.x - a.x) * frozenAlpha,
|
|
174
|
-
y: a.y + (b.y - a.y) * frozenAlpha
|
|
177
|
+
y: a.y + (b.y - a.y) * frozenAlpha,
|
|
175
178
|
};
|
|
176
|
-
}
|
|
179
|
+
},
|
|
177
180
|
};
|
|
178
181
|
}
|
|
179
182
|
_morphStrategy = strategy;
|
|
@@ -186,7 +189,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
186
189
|
completeMorph() {
|
|
187
190
|
if (morphCurveB !== null) {
|
|
188
191
|
if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
|
|
189
|
-
t = t / curve.period * morphCurveB.period;
|
|
192
|
+
t = (t / curve.period) * morphCurveB.period;
|
|
190
193
|
}
|
|
191
194
|
curve = morphCurveB;
|
|
192
195
|
}
|
|
@@ -198,19 +201,22 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
198
201
|
const points = new Array(steps);
|
|
199
202
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
200
203
|
for (let i = 0; i < steps; i++) {
|
|
201
|
-
const sampleT = i / (steps - 1) * curve.period;
|
|
204
|
+
const sampleT = (i / (steps - 1)) * curve.period;
|
|
202
205
|
const a = sampleSkeleton(curve, sampleT);
|
|
203
|
-
const tB =
|
|
206
|
+
const tB =
|
|
207
|
+
_morphStrategy === "normalized"
|
|
208
|
+
? (sampleT / curve.period) * morphCurveB.period
|
|
209
|
+
: sampleT;
|
|
204
210
|
const b = sampleSkeleton(morphCurveB, tB);
|
|
205
211
|
points[i] = {
|
|
206
212
|
x: a.x + (b.x - a.x) * _morphAlpha,
|
|
207
|
-
y: a.y + (b.y - a.y) * _morphAlpha
|
|
213
|
+
y: a.y + (b.y - a.y) * _morphAlpha,
|
|
208
214
|
};
|
|
209
215
|
}
|
|
210
216
|
return points;
|
|
211
217
|
}
|
|
212
218
|
for (let i = 0; i < steps; i++) {
|
|
213
|
-
const sampleT = i / (steps - 1) * curve.period;
|
|
219
|
+
const sampleT = (i / (steps - 1)) * curve.period;
|
|
214
220
|
points[i] = sampleSkeleton(curve, sampleT);
|
|
215
221
|
}
|
|
216
222
|
return points;
|
|
@@ -252,7 +258,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
252
258
|
_speedTransition.reject(new Error("Speed transition cancelled"));
|
|
253
259
|
_speedTransition = null;
|
|
254
260
|
}
|
|
255
|
-
}
|
|
261
|
+
},
|
|
256
262
|
};
|
|
257
263
|
}
|
|
258
264
|
|
|
@@ -260,6 +266,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
260
266
|
var DEFAULT_MORPH_DURATION_MS = 300;
|
|
261
267
|
var DEFAULT_SKELETON_OPACITY = 0.15;
|
|
262
268
|
var FIT_PADDING = 0.1;
|
|
269
|
+
var FIT_PADDING_MIN = 4;
|
|
263
270
|
var TRAIL_FADE_CURVE = 1.5;
|
|
264
271
|
var TRAIL_MAX_OPACITY = 0.88;
|
|
265
272
|
var TRAIL_MIN_WIDTH = 0.5;
|
|
@@ -314,13 +321,16 @@ function computeTrailQuad(trail, i, trailCount, toX, toY) {
|
|
|
314
321
|
r1x: nx - n1.x * w1,
|
|
315
322
|
r1y: ny - n1.y * w1,
|
|
316
323
|
opacity,
|
|
317
|
-
progress
|
|
324
|
+
progress,
|
|
318
325
|
};
|
|
319
326
|
}
|
|
320
327
|
function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
321
328
|
if (pts.length === 0) return null;
|
|
322
329
|
const first = pts[0];
|
|
323
|
-
let minX = first.x,
|
|
330
|
+
let minX = first.x,
|
|
331
|
+
maxX = first.x,
|
|
332
|
+
minY = first.y,
|
|
333
|
+
maxY = first.y;
|
|
324
334
|
for (const p of pts) {
|
|
325
335
|
if (p.x < minX) {
|
|
326
336
|
minX = p.x;
|
|
@@ -339,16 +349,23 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
|
339
349
|
const h = maxY - minY;
|
|
340
350
|
if (w === 0 && h === 0) {
|
|
341
351
|
throw new Error(
|
|
342
|
-
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
|
|
352
|
+
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
|
|
343
353
|
);
|
|
344
354
|
}
|
|
345
|
-
const
|
|
346
|
-
const
|
|
347
|
-
const
|
|
355
|
+
const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
|
|
356
|
+
const scaleYProportional = logicalHeight / (h * (1 + FIT_PADDING * 2));
|
|
357
|
+
const scaleXMinPadding = (logicalWidth - FIT_PADDING_MIN * 2) / w;
|
|
358
|
+
const scaleYMinPadding = (logicalHeight - FIT_PADDING_MIN * 2) / h;
|
|
359
|
+
const scale = Math.min(
|
|
360
|
+
scaleXProportional,
|
|
361
|
+
scaleYProportional,
|
|
362
|
+
scaleXMinPadding,
|
|
363
|
+
scaleYMinPadding,
|
|
364
|
+
);
|
|
348
365
|
return {
|
|
349
366
|
scale,
|
|
350
367
|
offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
|
|
351
|
-
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
368
|
+
offsetY: (logicalHeight - h * scale) / 2 - minY * scale,
|
|
352
369
|
};
|
|
353
370
|
}
|
|
354
371
|
function enginePassthroughs(engine) {
|
|
@@ -358,7 +375,7 @@ function enginePassthroughs(engine) {
|
|
|
358
375
|
setSpeed: engine.setSpeed,
|
|
359
376
|
getSpeed: engine.getSpeed,
|
|
360
377
|
resetSpeed: engine.resetSpeed,
|
|
361
|
-
setSpeedOver: engine.setSpeedOver
|
|
378
|
+
setSpeedOver: engine.setSpeedOver,
|
|
362
379
|
};
|
|
363
380
|
}
|
|
364
381
|
|
|
@@ -370,7 +387,7 @@ var GRADIENT = {
|
|
|
370
387
|
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
371
388
|
ice: ["#1e3a8a", "#67e8f9"],
|
|
372
389
|
fire: ["#7f1d1d", "#fbbf24"],
|
|
373
|
-
forest: ["#14532d", "#86efac"]
|
|
390
|
+
forest: ["#14532d", "#86efac"],
|
|
374
391
|
};
|
|
375
392
|
var PRESETS = {
|
|
376
393
|
bard: GRADIENT.bard,
|
|
@@ -378,16 +395,16 @@ var PRESETS = {
|
|
|
378
395
|
ocean: GRADIENT.ocean,
|
|
379
396
|
ice: GRADIENT.ice,
|
|
380
397
|
fire: GRADIENT.fire,
|
|
381
|
-
forest: GRADIENT.forest
|
|
398
|
+
forest: GRADIENT.forest,
|
|
382
399
|
};
|
|
383
400
|
function hexToRgb(hex) {
|
|
384
401
|
const n = parseInt(hex.slice(1), 16);
|
|
385
|
-
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
402
|
+
return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
|
|
386
403
|
}
|
|
387
404
|
var lerpRgb = (a, b, t) => ({
|
|
388
405
|
r: Math.round(a.r + (b.r - a.r) * t),
|
|
389
406
|
g: Math.round(a.g + (b.g - a.g) * t),
|
|
390
|
-
b: Math.round(a.b + (b.b - a.b) * t)
|
|
407
|
+
b: Math.round(a.b + (b.b - a.b) * t),
|
|
391
408
|
});
|
|
392
409
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
393
410
|
if (palette.length === 0) return { r: 255, g: 255, b: 255 };
|
|
@@ -407,7 +424,7 @@ function resolvePalette(palette, trailStyle) {
|
|
|
407
424
|
}
|
|
408
425
|
function hexToRgbComponents(hex) {
|
|
409
426
|
const n = parseInt(hex.slice(1), 16);
|
|
410
|
-
return `${n >> 16},${n >> 8 & 255},${n & 255}`;
|
|
427
|
+
return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
|
|
411
428
|
}
|
|
412
429
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
413
430
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -435,7 +452,7 @@ function createRenderer(options) {
|
|
|
435
452
|
const opts = {
|
|
436
453
|
skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,
|
|
437
454
|
trailColor,
|
|
438
|
-
headColor: options.headColor ?? defaultHeadColor()
|
|
455
|
+
headColor: options.headColor ?? defaultHeadColor(),
|
|
439
456
|
};
|
|
440
457
|
const trailRgb = hexToRgbComponents(opts.trailColor);
|
|
441
458
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
@@ -536,7 +553,7 @@ function createRenderer(options) {
|
|
|
536
553
|
i,
|
|
537
554
|
trailCount,
|
|
538
555
|
toX,
|
|
539
|
-
toY
|
|
556
|
+
toY,
|
|
540
557
|
);
|
|
541
558
|
if (trailStyle === "default") {
|
|
542
559
|
ctx.fillStyle = `rgba(${trailRgb},${opacity})`;
|
|
@@ -560,16 +577,14 @@ function createRenderer(options) {
|
|
|
560
577
|
}
|
|
561
578
|
const x = head.x * scale + offsetX;
|
|
562
579
|
const y = head.y * scale + offsetY;
|
|
563
|
-
const r =
|
|
580
|
+
const r =
|
|
581
|
+
options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(logicalWidth, logicalHeight) / 160));
|
|
564
582
|
ctx.fillStyle = opts.headColor;
|
|
565
583
|
ctx.beginPath();
|
|
566
584
|
ctx.arc(x, y, r, 0, Math.PI * 2);
|
|
567
585
|
ctx.fill();
|
|
568
586
|
}
|
|
569
|
-
function
|
|
570
|
-
const now = performance.now();
|
|
571
|
-
const deltaTime = Math.min((now - lastTime) / 1e3, 1 / 30);
|
|
572
|
-
lastTime = now;
|
|
587
|
+
function renderFrame(deltaTime) {
|
|
573
588
|
if (trailStyle === "gradient-animated") {
|
|
574
589
|
gradientAnimTime += deltaTime * 1e3;
|
|
575
590
|
}
|
|
@@ -605,22 +620,33 @@ function createRenderer(options) {
|
|
|
605
620
|
drawSkeleton();
|
|
606
621
|
drawTrail();
|
|
607
622
|
drawHead();
|
|
608
|
-
|
|
623
|
+
}
|
|
624
|
+
function loop() {
|
|
625
|
+
const now = performance.now();
|
|
626
|
+
const deltaTime = Math.min((now - lastTime) / 1e3, 1 / 30);
|
|
627
|
+
lastTime = now;
|
|
628
|
+
renderFrame(deltaTime);
|
|
629
|
+
animationId = requestAnimationFrame(loop);
|
|
609
630
|
}
|
|
610
631
|
skeleton = engine.getSarmalSkeleton();
|
|
611
632
|
calculateBoundaries();
|
|
612
633
|
if (!engine.isLiveSkeleton) {
|
|
613
634
|
buildSkeletonCanvas();
|
|
614
635
|
}
|
|
615
|
-
|
|
616
|
-
|
|
636
|
+
if (options.initialT !== void 0) {
|
|
637
|
+
engine.seek(options.initialT);
|
|
638
|
+
}
|
|
639
|
+
renderFrame(0);
|
|
640
|
+
const shouldAutoStart = options.autoStart !== false;
|
|
641
|
+
const instance = {
|
|
642
|
+
play() {
|
|
617
643
|
if (animationId !== null) {
|
|
618
644
|
return;
|
|
619
645
|
}
|
|
620
646
|
lastTime = performance.now();
|
|
621
|
-
|
|
647
|
+
loop();
|
|
622
648
|
},
|
|
623
|
-
|
|
649
|
+
pause() {
|
|
624
650
|
if (animationId === null) {
|
|
625
651
|
return;
|
|
626
652
|
}
|
|
@@ -653,8 +679,12 @@ function createRenderer(options) {
|
|
|
653
679
|
return new Promise((resolve) => {
|
|
654
680
|
morphResolve = resolve;
|
|
655
681
|
});
|
|
656
|
-
}
|
|
682
|
+
},
|
|
657
683
|
};
|
|
684
|
+
if (shouldAutoStart) {
|
|
685
|
+
instance.play();
|
|
686
|
+
}
|
|
687
|
+
return instance;
|
|
658
688
|
}
|
|
659
689
|
|
|
660
690
|
// src/renderer-svg.ts
|
|
@@ -675,7 +705,7 @@ function sampleCurveSkeleton(curveDef) {
|
|
|
675
705
|
const samples = Math.ceil(period * 50);
|
|
676
706
|
const pts = Array.from({ length: samples });
|
|
677
707
|
for (let i = 0; i < samples; i++) {
|
|
678
|
-
const t = i / (samples - 1) * period;
|
|
708
|
+
const t = (i / (samples - 1)) * period;
|
|
679
709
|
pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(t) : curveDef.fn(t, 0, EMPTY_PARAMS2);
|
|
680
710
|
}
|
|
681
711
|
return pts;
|
|
@@ -690,12 +720,13 @@ function createSVGRenderer(options) {
|
|
|
690
720
|
skeletonColor: options.skeletonColor ?? "#ffffff",
|
|
691
721
|
trailColor,
|
|
692
722
|
headColor: options.headColor ?? trailColor,
|
|
693
|
-
ariaLabel: options.ariaLabel ?? "Loading"
|
|
723
|
+
ariaLabel: options.ariaLabel ?? "Loading",
|
|
694
724
|
};
|
|
695
725
|
const rect = container.getBoundingClientRect();
|
|
696
726
|
const width = rect.width || 200;
|
|
697
727
|
const height = rect.height || 200;
|
|
698
|
-
const headRadius =
|
|
728
|
+
const headRadius =
|
|
729
|
+
options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(width, height) / 160));
|
|
699
730
|
const svg = el("svg");
|
|
700
731
|
svg.setAttribute("width", String(width));
|
|
701
732
|
svg.setAttribute("height", String(height));
|
|
@@ -775,7 +806,7 @@ function createSVGRenderer(options) {
|
|
|
775
806
|
i,
|
|
776
807
|
trailCount,
|
|
777
808
|
px,
|
|
778
|
-
py
|
|
809
|
+
py,
|
|
779
810
|
);
|
|
780
811
|
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`;
|
|
781
812
|
trailPaths[i].setAttribute("d", d);
|
|
@@ -797,24 +828,22 @@ function createSVGRenderer(options) {
|
|
|
797
828
|
}
|
|
798
829
|
let animationId = null;
|
|
799
830
|
let lastTime = 0;
|
|
800
|
-
const prefersReducedMotion =
|
|
831
|
+
const prefersReducedMotion =
|
|
832
|
+
typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
801
833
|
let morphResolve = null;
|
|
802
834
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
803
835
|
let morphTarget = null;
|
|
804
836
|
let morphAlpha = 0;
|
|
805
|
-
function renderFrame() {
|
|
806
|
-
const now = performance.now();
|
|
807
|
-
const dt = Math.min((now - lastTime) / 1e3, 1 / 30);
|
|
808
|
-
lastTime = now;
|
|
837
|
+
function renderFrame(deltaTime) {
|
|
809
838
|
if (engine.morphAlpha !== null) {
|
|
810
|
-
morphAlpha = Math.min(1, morphAlpha +
|
|
839
|
+
morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1e3));
|
|
811
840
|
engine.setMorphAlpha(morphAlpha);
|
|
812
841
|
if (morphPathABuilt) {
|
|
813
842
|
skeletonPathA.setAttribute("d", morphPathABuilt);
|
|
814
843
|
skeletonPathA.setAttribute("visibility", "visible");
|
|
815
844
|
skeletonPathA.setAttribute(
|
|
816
845
|
"stroke-opacity",
|
|
817
|
-
String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY)
|
|
846
|
+
String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY),
|
|
818
847
|
);
|
|
819
848
|
}
|
|
820
849
|
if (morphPathBBuilt) {
|
|
@@ -837,7 +866,7 @@ function createSVGRenderer(options) {
|
|
|
837
866
|
updateSkeleton(newSkeleton);
|
|
838
867
|
}
|
|
839
868
|
}
|
|
840
|
-
const trail = engine.tick(
|
|
869
|
+
const trail = engine.tick(deltaTime);
|
|
841
870
|
const trailCount = engine.trailCount;
|
|
842
871
|
if (engine.isLiveSkeleton && engine.morphAlpha === null) {
|
|
843
872
|
const liveSkeleton = engine.getSarmalSkeleton();
|
|
@@ -846,19 +875,30 @@ function createSVGRenderer(options) {
|
|
|
846
875
|
}
|
|
847
876
|
updateTrail(trail, trailCount);
|
|
848
877
|
updateHead(trail, trailCount);
|
|
878
|
+
}
|
|
879
|
+
function loop() {
|
|
880
|
+
const now = performance.now();
|
|
881
|
+
const deltaTime = Math.min((now - lastTime) / 1e3, 1 / 30);
|
|
882
|
+
lastTime = now;
|
|
883
|
+
renderFrame(deltaTime);
|
|
849
884
|
if (!prefersReducedMotion) {
|
|
850
|
-
animationId = requestAnimationFrame(
|
|
885
|
+
animationId = requestAnimationFrame(loop);
|
|
851
886
|
}
|
|
852
887
|
}
|
|
853
|
-
|
|
854
|
-
|
|
888
|
+
if (options.initialT !== void 0) {
|
|
889
|
+
engine.seek(options.initialT);
|
|
890
|
+
}
|
|
891
|
+
renderFrame(0);
|
|
892
|
+
const shouldAutoStart = options.autoStart !== false;
|
|
893
|
+
const instance = {
|
|
894
|
+
play() {
|
|
855
895
|
if (animationId !== null) {
|
|
856
896
|
return;
|
|
857
897
|
}
|
|
858
898
|
lastTime = performance.now();
|
|
859
|
-
|
|
899
|
+
loop();
|
|
860
900
|
},
|
|
861
|
-
|
|
901
|
+
pause() {
|
|
862
902
|
if (animationId === null) {
|
|
863
903
|
return;
|
|
864
904
|
}
|
|
@@ -899,8 +939,12 @@ function createSVGRenderer(options) {
|
|
|
899
939
|
return new Promise((resolve) => {
|
|
900
940
|
morphResolve = resolve;
|
|
901
941
|
});
|
|
902
|
-
}
|
|
942
|
+
},
|
|
903
943
|
};
|
|
944
|
+
if (shouldAutoStart) {
|
|
945
|
+
instance.play();
|
|
946
|
+
}
|
|
947
|
+
return instance;
|
|
904
948
|
}
|
|
905
949
|
function createSarmalSVG(container, curveDef, options) {
|
|
906
950
|
const { trailLength, ...rendererOpts } = options ?? {};
|
|
@@ -911,19 +955,22 @@ function createSarmalSVG(container, curveDef, options) {
|
|
|
911
955
|
// src/curves/artemis2.ts
|
|
912
956
|
var TWO_PI2 = Math.PI * 2;
|
|
913
957
|
function artemis2Fn(t, _time, _params) {
|
|
914
|
-
const a = 0.35,
|
|
915
|
-
|
|
958
|
+
const a = 0.35,
|
|
959
|
+
b = 0.15,
|
|
960
|
+
ox = 0.175;
|
|
961
|
+
const s = Math.sin(t),
|
|
962
|
+
c = Math.cos(t);
|
|
916
963
|
const denom = 1 + s * s;
|
|
917
964
|
return {
|
|
918
|
-
x: c * (1 + a * c) / denom - ox,
|
|
919
|
-
y: s * c * (1 + b * c) / denom
|
|
965
|
+
x: (c * (1 + a * c)) / denom - ox,
|
|
966
|
+
y: (s * c * (1 + b * c)) / denom,
|
|
920
967
|
};
|
|
921
968
|
}
|
|
922
969
|
var artemis2 = {
|
|
923
970
|
name: "Artemis II",
|
|
924
971
|
fn: artemis2Fn,
|
|
925
972
|
period: TWO_PI2,
|
|
926
|
-
speed: 0.7
|
|
973
|
+
speed: 0.7,
|
|
927
974
|
};
|
|
928
975
|
|
|
929
976
|
// src/curves/astroid.ts
|
|
@@ -933,14 +980,14 @@ function astroidFn(t, _time, _params) {
|
|
|
933
980
|
const s = Math.sin(t);
|
|
934
981
|
return {
|
|
935
982
|
x: c * c * c,
|
|
936
|
-
y: s * s * s
|
|
983
|
+
y: s * s * s,
|
|
937
984
|
};
|
|
938
985
|
}
|
|
939
986
|
var astroid = {
|
|
940
987
|
name: "Astroid",
|
|
941
988
|
fn: astroidFn,
|
|
942
989
|
period: TWO_PI3,
|
|
943
|
-
speed: 1.1
|
|
990
|
+
speed: 1.1,
|
|
944
991
|
};
|
|
945
992
|
|
|
946
993
|
// src/curves/deltoid.ts
|
|
@@ -948,14 +995,14 @@ var TWO_PI4 = Math.PI * 2;
|
|
|
948
995
|
function deltoidFn(t, _time, _params) {
|
|
949
996
|
return {
|
|
950
997
|
x: 2 * Math.cos(t) + Math.cos(2 * t),
|
|
951
|
-
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
998
|
+
y: 2 * Math.sin(t) - Math.sin(2 * t),
|
|
952
999
|
};
|
|
953
1000
|
}
|
|
954
1001
|
var deltoid = {
|
|
955
1002
|
name: "Deltoid",
|
|
956
1003
|
fn: deltoidFn,
|
|
957
1004
|
period: TWO_PI4,
|
|
958
|
-
speed: 0.9
|
|
1005
|
+
speed: 0.9,
|
|
959
1006
|
};
|
|
960
1007
|
|
|
961
1008
|
// src/curves/epicycloid3.ts
|
|
@@ -963,14 +1010,14 @@ var TWO_PI5 = Math.PI * 2;
|
|
|
963
1010
|
function epicycloid3Fn(t, _time, _params) {
|
|
964
1011
|
return {
|
|
965
1012
|
x: 4 * Math.cos(t) - Math.cos(4 * t),
|
|
966
|
-
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
1013
|
+
y: 4 * Math.sin(t) - Math.sin(4 * t),
|
|
967
1014
|
};
|
|
968
1015
|
}
|
|
969
1016
|
var epicycloid3 = {
|
|
970
1017
|
name: "Epicycloid (n=3)",
|
|
971
1018
|
fn: epicycloid3Fn,
|
|
972
1019
|
period: TWO_PI5,
|
|
973
|
-
speed: 0.75
|
|
1020
|
+
speed: 0.75,
|
|
974
1021
|
};
|
|
975
1022
|
|
|
976
1023
|
// src/curves/epitrochoid7.ts
|
|
@@ -979,14 +1026,14 @@ function epitrochoid7Fn(t, _time, _params) {
|
|
|
979
1026
|
const d = 1 + 0.55 * Math.sin(t * 0.5);
|
|
980
1027
|
return {
|
|
981
1028
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
982
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
1029
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
983
1030
|
};
|
|
984
1031
|
}
|
|
985
1032
|
function epitrochoid7SkeletonFn(t) {
|
|
986
1033
|
const d = 1.275;
|
|
987
1034
|
return {
|
|
988
1035
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
989
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
1036
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
990
1037
|
};
|
|
991
1038
|
}
|
|
992
1039
|
var epitrochoid7 = {
|
|
@@ -994,7 +1041,7 @@ var epitrochoid7 = {
|
|
|
994
1041
|
fn: epitrochoid7Fn,
|
|
995
1042
|
period: TWO_PI6,
|
|
996
1043
|
speed: 1.4,
|
|
997
|
-
skeletonFn: epitrochoid7SkeletonFn
|
|
1044
|
+
skeletonFn: epitrochoid7SkeletonFn,
|
|
998
1045
|
};
|
|
999
1046
|
|
|
1000
1047
|
// src/curves/lissajous32.ts
|
|
@@ -1003,7 +1050,7 @@ function lissajous32Fn(t, time, _params) {
|
|
|
1003
1050
|
const phi = time * 0.45;
|
|
1004
1051
|
return {
|
|
1005
1052
|
x: Math.sin(3 * t + phi),
|
|
1006
|
-
y: Math.sin(2 * t)
|
|
1053
|
+
y: Math.sin(2 * t),
|
|
1007
1054
|
};
|
|
1008
1055
|
}
|
|
1009
1056
|
var lissajous32 = {
|
|
@@ -1011,7 +1058,7 @@ var lissajous32 = {
|
|
|
1011
1058
|
fn: lissajous32Fn,
|
|
1012
1059
|
period: TWO_PI7,
|
|
1013
1060
|
speed: 2,
|
|
1014
|
-
skeleton: "live"
|
|
1061
|
+
skeleton: "live",
|
|
1015
1062
|
};
|
|
1016
1063
|
|
|
1017
1064
|
// src/curves/lissajous43.ts
|
|
@@ -1020,7 +1067,7 @@ function lissajous43Fn(t, time, _params) {
|
|
|
1020
1067
|
const phi = time * 0.38;
|
|
1021
1068
|
return {
|
|
1022
1069
|
x: Math.sin(4 * t + phi),
|
|
1023
|
-
y: Math.sin(3 * t)
|
|
1070
|
+
y: Math.sin(3 * t),
|
|
1024
1071
|
};
|
|
1025
1072
|
}
|
|
1026
1073
|
var lissajous43 = {
|
|
@@ -1028,17 +1075,18 @@ var lissajous43 = {
|
|
|
1028
1075
|
fn: lissajous43Fn,
|
|
1029
1076
|
period: TWO_PI8,
|
|
1030
1077
|
speed: 1.8,
|
|
1031
|
-
skeleton: "live"
|
|
1078
|
+
skeleton: "live",
|
|
1032
1079
|
};
|
|
1033
1080
|
|
|
1034
1081
|
// src/curves/lame.ts
|
|
1035
1082
|
var TWO_PI9 = Math.PI * 2;
|
|
1036
1083
|
function lameFn(t, time, _params) {
|
|
1037
1084
|
const p = 1.75 + 1.25 * Math.sin(time * 0.48);
|
|
1038
|
-
const c = Math.cos(t),
|
|
1085
|
+
const c = Math.cos(t),
|
|
1086
|
+
s = Math.sin(t);
|
|
1039
1087
|
return {
|
|
1040
1088
|
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
1041
|
-
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
1089
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p),
|
|
1042
1090
|
};
|
|
1043
1091
|
}
|
|
1044
1092
|
var lame = {
|
|
@@ -1046,7 +1094,7 @@ var lame = {
|
|
|
1046
1094
|
fn: lameFn,
|
|
1047
1095
|
period: TWO_PI9,
|
|
1048
1096
|
speed: 1,
|
|
1049
|
-
skeleton: "live"
|
|
1097
|
+
skeleton: "live",
|
|
1050
1098
|
};
|
|
1051
1099
|
|
|
1052
1100
|
// src/curves/rose3.ts
|
|
@@ -1055,14 +1103,14 @@ function rose3Fn(t, _time, _params) {
|
|
|
1055
1103
|
const r = Math.cos(3 * t);
|
|
1056
1104
|
return {
|
|
1057
1105
|
x: r * Math.cos(t),
|
|
1058
|
-
y: r * Math.sin(t)
|
|
1106
|
+
y: r * Math.sin(t),
|
|
1059
1107
|
};
|
|
1060
1108
|
}
|
|
1061
1109
|
var rose3 = {
|
|
1062
1110
|
name: "Rose (n=3)",
|
|
1063
1111
|
fn: rose3Fn,
|
|
1064
1112
|
period: TWO_PI10,
|
|
1065
|
-
speed: 1.15
|
|
1113
|
+
speed: 1.15,
|
|
1066
1114
|
};
|
|
1067
1115
|
|
|
1068
1116
|
// src/curves/rose5.ts
|
|
@@ -1071,14 +1119,14 @@ function rose5Fn(t, _time, _params) {
|
|
|
1071
1119
|
const r = Math.cos(5 * t);
|
|
1072
1120
|
return {
|
|
1073
1121
|
x: r * Math.cos(t),
|
|
1074
|
-
y: r * Math.sin(t)
|
|
1122
|
+
y: r * Math.sin(t),
|
|
1075
1123
|
};
|
|
1076
1124
|
}
|
|
1077
1125
|
var rose5 = {
|
|
1078
1126
|
name: "Rose (n=5)",
|
|
1079
1127
|
fn: rose5Fn,
|
|
1080
1128
|
period: TWO_PI11,
|
|
1081
|
-
speed: 1
|
|
1129
|
+
speed: 1,
|
|
1082
1130
|
};
|
|
1083
1131
|
|
|
1084
1132
|
// src/curves/index.ts
|
|
@@ -1092,7 +1140,7 @@ var curves = {
|
|
|
1092
1140
|
lissajous32,
|
|
1093
1141
|
lissajous43,
|
|
1094
1142
|
epicycloid3,
|
|
1095
|
-
lame
|
|
1143
|
+
lame,
|
|
1096
1144
|
};
|
|
1097
1145
|
|
|
1098
1146
|
// src/index.ts
|
|
@@ -1119,4 +1167,4 @@ exports.lissajous43 = lissajous43;
|
|
|
1119
1167
|
exports.rose3 = rose3;
|
|
1120
1168
|
exports.rose5 = rose5;
|
|
1121
1169
|
//# sourceMappingURL=index.cjs.map
|
|
1122
|
-
//# sourceMappingURL=index.cjs.map
|
|
1170
|
+
//# sourceMappingURL=index.cjs.map
|