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