@sarmal/core 0.6.0 → 0.7.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 +117 -139
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.d.cts +2 -1
- package/dist/auto-init.d.ts +2 -1
- package/dist/auto-init.js +116 -138
- package/dist/auto-init.js.map +1 -1
- package/dist/index.cjs +122 -153
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +200 -225
- package/dist/index.d.ts +200 -225
- package/dist/index.js +121 -152
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -49,7 +49,7 @@ function resolveCurve(curveDef) {
|
|
|
49
49
|
period: curveDef.period ?? TWO_PI,
|
|
50
50
|
speed: curveDef.speed ?? 1,
|
|
51
51
|
skeleton: curveDef.skeleton,
|
|
52
|
-
skeletonFn: curveDef.skeletonFn
|
|
52
|
+
skeletonFn: curveDef.skeletonFn
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
function createEngine(curveDef, trailLength = 120) {
|
|
@@ -75,7 +75,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
75
75
|
actualTime += deltaTime;
|
|
76
76
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
77
77
|
const a = curve.fn(t, actualTime, {});
|
|
78
|
-
const tB = _morphStrategy === "normalized" ?
|
|
78
|
+
const tB = _morphStrategy === "normalized" ? t / curve.period * morphCurveB.period : t;
|
|
79
79
|
const b = morphCurveB.fn(tB, actualTime, {});
|
|
80
80
|
trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
|
|
81
81
|
} else {
|
|
@@ -99,14 +99,14 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
99
99
|
trail.clear();
|
|
100
100
|
},
|
|
101
101
|
seek(newT, { clearTrail = false } = {}) {
|
|
102
|
-
t = (
|
|
102
|
+
t = (newT % curve.period + curve.period) % curve.period;
|
|
103
103
|
if (clearTrail) {
|
|
104
104
|
trail.clear();
|
|
105
105
|
}
|
|
106
106
|
},
|
|
107
107
|
seekWithTrail(targetT, { wrap = false, step = curve.period / trailLength } = {}) {
|
|
108
108
|
const advance = curve.speed * step;
|
|
109
|
-
const target = (
|
|
109
|
+
const target = (targetT % curve.period + curve.period) % curve.period;
|
|
110
110
|
const targetTime = target / curve.speed;
|
|
111
111
|
t = target;
|
|
112
112
|
actualTime = targetTime;
|
|
@@ -132,16 +132,13 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
132
132
|
...frozenB,
|
|
133
133
|
fn: (sampleT, time, params) => {
|
|
134
134
|
const a = frozenA.fn(sampleT, time, params);
|
|
135
|
-
const tB =
|
|
136
|
-
frozenStrategy === "normalized"
|
|
137
|
-
? (sampleT / frozenA.period) * frozenB.period
|
|
138
|
-
: sampleT;
|
|
135
|
+
const tB = frozenStrategy === "normalized" ? sampleT / frozenA.period * frozenB.period : sampleT;
|
|
139
136
|
const b = frozenB.fn(tB, time, params);
|
|
140
137
|
return {
|
|
141
138
|
x: a.x + (b.x - a.x) * frozenAlpha,
|
|
142
|
-
y: a.y + (b.y - a.y) * frozenAlpha
|
|
139
|
+
y: a.y + (b.y - a.y) * frozenAlpha
|
|
143
140
|
};
|
|
144
|
-
}
|
|
141
|
+
}
|
|
145
142
|
};
|
|
146
143
|
}
|
|
147
144
|
_morphStrategy = strategy;
|
|
@@ -153,6 +150,9 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
153
150
|
},
|
|
154
151
|
completeMorph() {
|
|
155
152
|
if (morphCurveB !== null) {
|
|
153
|
+
if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
|
|
154
|
+
t = t / curve.period * morphCurveB.period;
|
|
155
|
+
}
|
|
156
156
|
curve = morphCurveB;
|
|
157
157
|
}
|
|
158
158
|
morphCurveB = null;
|
|
@@ -163,26 +163,23 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
163
163
|
const points = new Array(steps);
|
|
164
164
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
165
165
|
for (let i = 0; i < steps; i++) {
|
|
166
|
-
const sampleT =
|
|
166
|
+
const sampleT = i / (steps - 1) * curve.period;
|
|
167
167
|
const a = sampleSkeleton(curve, sampleT);
|
|
168
|
-
const tB =
|
|
169
|
-
_morphStrategy === "normalized"
|
|
170
|
-
? (sampleT / curve.period) * morphCurveB.period
|
|
171
|
-
: sampleT;
|
|
168
|
+
const tB = _morphStrategy === "normalized" ? sampleT / curve.period * morphCurveB.period : sampleT;
|
|
172
169
|
const b = sampleSkeleton(morphCurveB, tB);
|
|
173
170
|
points[i] = {
|
|
174
171
|
x: a.x + (b.x - a.x) * _morphAlpha,
|
|
175
|
-
y: a.y + (b.y - a.y) * _morphAlpha
|
|
172
|
+
y: a.y + (b.y - a.y) * _morphAlpha
|
|
176
173
|
};
|
|
177
174
|
}
|
|
178
175
|
return points;
|
|
179
176
|
}
|
|
180
177
|
for (let i = 0; i < steps; i++) {
|
|
181
|
-
const sampleT =
|
|
178
|
+
const sampleT = i / (steps - 1) * curve.period;
|
|
182
179
|
points[i] = sampleSkeleton(curve, sampleT);
|
|
183
180
|
}
|
|
184
181
|
return points;
|
|
185
|
-
}
|
|
182
|
+
}
|
|
186
183
|
};
|
|
187
184
|
}
|
|
188
185
|
|
|
@@ -202,7 +199,7 @@ var GLOW_INNER_EDGE = 0.4;
|
|
|
202
199
|
var GLOW_FALLOFF_OPACITY = 0.53;
|
|
203
200
|
function hexToRgbComponents(hex) {
|
|
204
201
|
const n = parseInt(hex.slice(1), 16);
|
|
205
|
-
return `${n >> 16},${
|
|
202
|
+
return `${n >> 16},${n >> 8 & 255},${n & 255}`;
|
|
206
203
|
}
|
|
207
204
|
function createRenderer(options) {
|
|
208
205
|
const canvas = options.canvas;
|
|
@@ -216,7 +213,7 @@ function createRenderer(options) {
|
|
|
216
213
|
trailColor: options.trailColor ?? "#ffffff",
|
|
217
214
|
headColor: options.headColor ?? "#ffffff",
|
|
218
215
|
headRadius: options.headRadius ?? DEFAULT_HEAD_RADIUS,
|
|
219
|
-
glowSize: options.glowSize ?? DEFAULT_GLOW_SIZE
|
|
216
|
+
glowSize: options.glowSize ?? DEFAULT_GLOW_SIZE
|
|
220
217
|
};
|
|
221
218
|
const trailRgb = hexToRgbComponents(opts.trailColor);
|
|
222
219
|
const headRgbFalloff = `rgba(${hexToRgbComponents(opts.headColor)},${GLOW_FALLOFF_OPACITY})`;
|
|
@@ -232,32 +229,18 @@ function createRenderer(options) {
|
|
|
232
229
|
let lastTime = 0;
|
|
233
230
|
let morphResolve = null;
|
|
234
231
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
235
|
-
let morphTarget = null;
|
|
236
232
|
let morphAlpha = 0;
|
|
237
|
-
let
|
|
238
|
-
let
|
|
239
|
-
function
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
maxX =
|
|
246
|
-
minY =
|
|
247
|
-
maxY =
|
|
248
|
-
for (const p of skeleton) {
|
|
249
|
-
if (p.x < minX) {
|
|
250
|
-
minX = p.x;
|
|
251
|
-
}
|
|
252
|
-
if (p.x > maxX) {
|
|
253
|
-
maxX = p.x;
|
|
254
|
-
}
|
|
255
|
-
if (p.y < minY) {
|
|
256
|
-
minY = p.y;
|
|
257
|
-
}
|
|
258
|
-
if (p.y > maxY) {
|
|
259
|
-
maxY = p.y;
|
|
260
|
-
}
|
|
233
|
+
let morphBoundsA = null;
|
|
234
|
+
let morphBoundsB = null;
|
|
235
|
+
function computeBoundaries(pts) {
|
|
236
|
+
if (pts.length === 0) return null;
|
|
237
|
+
const first = pts[0];
|
|
238
|
+
let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
|
|
239
|
+
for (const p of pts) {
|
|
240
|
+
if (p.x < minX) minX = p.x;
|
|
241
|
+
if (p.x > maxX) maxX = p.x;
|
|
242
|
+
if (p.y < minY) minY = p.y;
|
|
243
|
+
if (p.y > maxY) maxY = p.y;
|
|
261
244
|
}
|
|
262
245
|
const width = maxX - minX;
|
|
263
246
|
const height = maxY - minY;
|
|
@@ -265,11 +248,22 @@ function createRenderer(options) {
|
|
|
265
248
|
const canvasHeight = canvas.height;
|
|
266
249
|
const scaleX = canvasWidth / (width * (1 + FIT_PADDING * 2));
|
|
267
250
|
const scaleY = canvasHeight / (height * (1 + FIT_PADDING * 2));
|
|
268
|
-
|
|
269
|
-
const boundsWidth = width *
|
|
270
|
-
const boundsHeight = height *
|
|
271
|
-
|
|
272
|
-
|
|
251
|
+
const s = Math.min(scaleX, scaleY);
|
|
252
|
+
const boundsWidth = width * s;
|
|
253
|
+
const boundsHeight = height * s;
|
|
254
|
+
return {
|
|
255
|
+
scale: s,
|
|
256
|
+
offsetX: (canvasWidth - boundsWidth) / 2 - minX * s,
|
|
257
|
+
offsetY: (canvasHeight - boundsHeight) / 2 - minY * s
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function calculateBoundaries() {
|
|
261
|
+
const b = computeBoundaries(skeleton);
|
|
262
|
+
if (b) {
|
|
263
|
+
scale = b.scale;
|
|
264
|
+
offsetX = b.offsetX;
|
|
265
|
+
offsetY = b.offsetY;
|
|
266
|
+
}
|
|
273
267
|
}
|
|
274
268
|
function buildSkeletonCanvas() {
|
|
275
269
|
if (skeleton.length < 2) return;
|
|
@@ -286,20 +280,23 @@ function createRenderer(options) {
|
|
|
286
280
|
}
|
|
287
281
|
skeletonCtx.stroke();
|
|
288
282
|
}
|
|
283
|
+
function drawSkeletonPath(pts, opacity) {
|
|
284
|
+
if (pts.length < 2) return;
|
|
285
|
+
ctx.strokeStyle = `rgba(${hexToRgbComponents(opts.skeletonColor)},${opacity})`;
|
|
286
|
+
ctx.lineWidth = 1.5;
|
|
287
|
+
ctx.beginPath();
|
|
288
|
+
ctx.moveTo(pts[0].x * scale + offsetX, pts[0].y * scale + offsetY);
|
|
289
|
+
for (let i = 1; i < pts.length; i++) {
|
|
290
|
+
ctx.lineTo(pts[i].x * scale + offsetX, pts[i].y * scale + offsetY);
|
|
291
|
+
}
|
|
292
|
+
ctx.stroke();
|
|
293
|
+
}
|
|
289
294
|
function drawSkeleton() {
|
|
290
295
|
if (opts.skeletonColor === "transparent") {
|
|
291
296
|
return;
|
|
292
297
|
}
|
|
293
298
|
if (engine.morphAlpha !== null) {
|
|
294
|
-
|
|
295
|
-
ctx.globalAlpha = (1 - morphAlpha) * DEFAULT_SKELETON_OPACITY;
|
|
296
|
-
ctx.drawImage(skeletonCanvasA, 0, 0);
|
|
297
|
-
}
|
|
298
|
-
if (skeletonCanvasB) {
|
|
299
|
-
ctx.globalAlpha = morphAlpha * DEFAULT_SKELETON_OPACITY;
|
|
300
|
-
ctx.drawImage(skeletonCanvasB, 0, 0);
|
|
301
|
-
}
|
|
302
|
-
ctx.globalAlpha = 1;
|
|
299
|
+
drawSkeletonPath(engine.getSarmalSkeleton(), DEFAULT_SKELETON_OPACITY);
|
|
303
300
|
return;
|
|
304
301
|
}
|
|
305
302
|
if (engine.isLiveSkeleton) {
|
|
@@ -371,23 +368,31 @@ function createRenderer(options) {
|
|
|
371
368
|
if (engine.morphAlpha !== null) {
|
|
372
369
|
morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1e3));
|
|
373
370
|
engine.setMorphAlpha(morphAlpha);
|
|
374
|
-
|
|
375
|
-
|
|
371
|
+
if (morphBoundsA && morphBoundsB) {
|
|
372
|
+
const a = morphBoundsA;
|
|
373
|
+
const b = morphBoundsB;
|
|
374
|
+
scale = a.scale + (b.scale - a.scale) * morphAlpha;
|
|
375
|
+
offsetX = a.offsetX + (b.offsetX - a.offsetX) * morphAlpha;
|
|
376
|
+
offsetY = a.offsetY + (b.offsetY - a.offsetY) * morphAlpha;
|
|
377
|
+
}
|
|
376
378
|
if (morphAlpha >= 1) {
|
|
377
379
|
engine.completeMorph();
|
|
378
380
|
morphResolve?.();
|
|
379
381
|
morphResolve = null;
|
|
380
|
-
morphTarget = null;
|
|
381
382
|
morphAlpha = 0;
|
|
382
|
-
|
|
383
|
-
|
|
383
|
+
morphBoundsA = null;
|
|
384
|
+
morphBoundsB = null;
|
|
385
|
+
skeleton = engine.getSarmalSkeleton();
|
|
386
|
+
if (!engine.isLiveSkeleton) {
|
|
387
|
+
buildSkeletonCanvas();
|
|
388
|
+
}
|
|
384
389
|
}
|
|
385
390
|
}
|
|
386
391
|
trail = engine.tick(deltaTime);
|
|
387
392
|
trailCount = engine.trailCount;
|
|
388
393
|
head = trailCount > 0 ? trail[trailCount - 1] : null;
|
|
389
394
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
390
|
-
if (engine.isLiveSkeleton
|
|
395
|
+
if (engine.isLiveSkeleton && engine.morphAlpha === null) {
|
|
391
396
|
skeleton = engine.getSarmalSkeleton();
|
|
392
397
|
calculateBoundaries();
|
|
393
398
|
}
|
|
@@ -434,54 +439,31 @@ function createRenderer(options) {
|
|
|
434
439
|
engine.seekWithTrail(t);
|
|
435
440
|
},
|
|
436
441
|
morphTo(target, options2) {
|
|
442
|
+
const interruptBounds = morphResolve !== null ? { scale, offsetX, offsetY } : null;
|
|
437
443
|
if (morphResolve !== null) {
|
|
438
444
|
engine.completeMorph();
|
|
439
445
|
morphResolve();
|
|
440
446
|
morphResolve = null;
|
|
441
447
|
morphAlpha = 0;
|
|
442
|
-
|
|
443
|
-
|
|
448
|
+
morphBoundsA = null;
|
|
449
|
+
morphBoundsB = null;
|
|
444
450
|
}
|
|
445
451
|
morphDurationMs = options2?.duration ?? DEFAULT_MORPH_DURATION_MS;
|
|
446
|
-
morphTarget = target;
|
|
447
452
|
morphAlpha = 0;
|
|
448
|
-
|
|
449
|
-
if (currentSkeleton.length >= 2) {
|
|
450
|
-
skeletonCanvasA = new OffscreenCanvas(canvas.width, canvas.height);
|
|
451
|
-
const ctxA = skeletonCanvasA.getContext("2d");
|
|
452
|
-
ctxA.strokeStyle = `rgba(${hexToRgbComponents(opts.skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
453
|
-
ctxA.lineWidth = 1.5;
|
|
454
|
-
ctxA.beginPath();
|
|
455
|
-
const first = currentSkeleton[0];
|
|
456
|
-
ctxA.moveTo(first.x * scale + offsetX, first.y * scale + offsetY);
|
|
457
|
-
for (let i = 1; i < currentSkeleton.length; i++) {
|
|
458
|
-
const p = currentSkeleton[i];
|
|
459
|
-
ctxA.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);
|
|
460
|
-
}
|
|
461
|
-
ctxA.stroke();
|
|
462
|
-
}
|
|
453
|
+
morphBoundsA = interruptBounds ?? computeBoundaries(engine.getSarmalSkeleton()) ?? { scale, offsetX, offsetY };
|
|
463
454
|
engine.startMorph(target, options2?.morphStrategy);
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
const firstB = morphTarget.fn(0, 0, {});
|
|
473
|
-
skeletonCtx.moveTo(firstB.x * scale + offsetX, firstB.y * scale + offsetY);
|
|
474
|
-
for (let i = 1; i <= samples; i++) {
|
|
475
|
-
const t = (i / samples) * period;
|
|
476
|
-
const p = morphTarget.fn(t, 0, {});
|
|
477
|
-
skeletonCtx.lineTo(p.x * scale + offsetX, p.y * scale + offsetY);
|
|
478
|
-
}
|
|
479
|
-
skeletonCtx.stroke();
|
|
480
|
-
}
|
|
455
|
+
const period = target.period ?? Math.PI * 2;
|
|
456
|
+
const samples = Math.max(50, Math.round(period * 20));
|
|
457
|
+
const skeletonFn = target.skeletonFn ?? ((t) => target.fn(t, 0, {}));
|
|
458
|
+
const skeletonB = Array.from(
|
|
459
|
+
{ length: samples + 1 },
|
|
460
|
+
(_, i) => skeletonFn(i / samples * period)
|
|
461
|
+
);
|
|
462
|
+
morphBoundsB = computeBoundaries(skeletonB) ?? { scale, offsetX, offsetY };
|
|
481
463
|
return new Promise((resolve) => {
|
|
482
464
|
morphResolve = resolve;
|
|
483
465
|
});
|
|
484
|
-
}
|
|
466
|
+
}
|
|
485
467
|
};
|
|
486
468
|
}
|
|
487
469
|
|
|
@@ -508,7 +490,7 @@ function createSVGRenderer(options) {
|
|
|
508
490
|
headColor: options.headColor ?? "#ffffff",
|
|
509
491
|
headRadius: options.headRadius ?? 4,
|
|
510
492
|
glowSize: options.glowSize ?? 20,
|
|
511
|
-
ariaLabel: options.ariaLabel ?? "Loading"
|
|
493
|
+
ariaLabel: options.ariaLabel ?? "Loading"
|
|
512
494
|
};
|
|
513
495
|
const uid = ++instanceCount;
|
|
514
496
|
const gradientId = `sarmal-glow-${uid}`;
|
|
@@ -592,10 +574,7 @@ function createSVGRenderer(options) {
|
|
|
592
574
|
return;
|
|
593
575
|
}
|
|
594
576
|
const first = skeleton2[0];
|
|
595
|
-
let minX = first.x,
|
|
596
|
-
maxX = first.x,
|
|
597
|
-
minY = first.y,
|
|
598
|
-
maxY = first.y;
|
|
577
|
+
let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
|
|
599
578
|
for (const p of skeleton2) {
|
|
600
579
|
if (p.x < minX) {
|
|
601
580
|
minX = p.x;
|
|
@@ -682,8 +661,7 @@ function createSVGRenderer(options) {
|
|
|
682
661
|
}
|
|
683
662
|
let animationId = null;
|
|
684
663
|
let lastTime = 0;
|
|
685
|
-
const prefersReducedMotion =
|
|
686
|
-
typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
664
|
+
const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
687
665
|
let morphResolve = null;
|
|
688
666
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS2;
|
|
689
667
|
let morphTarget = null;
|
|
@@ -693,7 +671,7 @@ function createSVGRenderer(options) {
|
|
|
693
671
|
const samples = Math.max(50, Math.round(period * 20));
|
|
694
672
|
const points = [];
|
|
695
673
|
for (let i = 0; i <= samples; i++) {
|
|
696
|
-
const t =
|
|
674
|
+
const t = i / samples * period;
|
|
697
675
|
const p = target.fn(t, 0, {});
|
|
698
676
|
points.push(p);
|
|
699
677
|
}
|
|
@@ -716,26 +694,18 @@ function createSVGRenderer(options) {
|
|
|
716
694
|
if (engine.morphAlpha !== null) {
|
|
717
695
|
morphAlpha = Math.min(1, morphAlpha + dt / (morphDurationMs / 1e3));
|
|
718
696
|
engine.setMorphAlpha(morphAlpha);
|
|
719
|
-
const morphSkeleton = engine.getSarmalSkeleton();
|
|
720
|
-
calculateBoundaries(morphSkeleton);
|
|
721
|
-
if (!engine.isLiveSkeleton) {
|
|
722
|
-
updateSkeleton(morphSkeleton);
|
|
723
|
-
}
|
|
724
697
|
if (morphPathABuilt) {
|
|
725
698
|
skeletonPathA.setAttribute("d", morphPathABuilt);
|
|
726
699
|
skeletonPathA.setAttribute("visibility", "visible");
|
|
727
700
|
skeletonPathA.setAttribute(
|
|
728
701
|
"stroke-opacity",
|
|
729
|
-
String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY2)
|
|
702
|
+
String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY2)
|
|
730
703
|
);
|
|
731
704
|
}
|
|
732
705
|
if (morphPathBBuilt) {
|
|
733
706
|
skeletonPathB.setAttribute("d", morphPathBBuilt);
|
|
734
707
|
skeletonPathB.setAttribute("visibility", "visible");
|
|
735
|
-
skeletonPathB.setAttribute(
|
|
736
|
-
"stroke-opacity",
|
|
737
|
-
String(morphAlpha * DEFAULT_SKELETON_OPACITY2),
|
|
738
|
-
);
|
|
708
|
+
skeletonPathB.setAttribute("stroke-opacity", String(morphAlpha * DEFAULT_SKELETON_OPACITY2));
|
|
739
709
|
}
|
|
740
710
|
if (morphAlpha >= 1) {
|
|
741
711
|
engine.completeMorph();
|
|
@@ -747,11 +717,14 @@ function createSVGRenderer(options) {
|
|
|
747
717
|
morphPathBBuilt = "";
|
|
748
718
|
skeletonPathA.setAttribute("visibility", "hidden");
|
|
749
719
|
skeletonPathB.setAttribute("visibility", "hidden");
|
|
720
|
+
const newSkeleton = engine.getSarmalSkeleton();
|
|
721
|
+
calculateBoundaries(newSkeleton);
|
|
722
|
+
updateSkeleton(newSkeleton);
|
|
750
723
|
}
|
|
751
724
|
}
|
|
752
725
|
const trail = engine.tick(dt);
|
|
753
726
|
const trailCount = engine.trailCount;
|
|
754
|
-
if (engine.isLiveSkeleton) {
|
|
727
|
+
if (engine.isLiveSkeleton && engine.morphAlpha === null) {
|
|
755
728
|
const liveSkeleton = engine.getSarmalSkeleton();
|
|
756
729
|
calculateBoundaries(liveSkeleton);
|
|
757
730
|
updateSkeleton(liveSkeleton);
|
|
@@ -824,7 +797,7 @@ function createSVGRenderer(options) {
|
|
|
824
797
|
return new Promise((resolve) => {
|
|
825
798
|
morphResolve = resolve;
|
|
826
799
|
});
|
|
827
|
-
}
|
|
800
|
+
}
|
|
828
801
|
};
|
|
829
802
|
}
|
|
830
803
|
function createSarmalSVG(container, curveDef, options) {
|
|
@@ -836,29 +809,26 @@ function createSarmalSVG(container, curveDef, options) {
|
|
|
836
809
|
// src/curves.ts
|
|
837
810
|
var TWO_PI2 = Math.PI * 2;
|
|
838
811
|
function artemis2(t, _time, _params) {
|
|
839
|
-
const a = 0.35,
|
|
840
|
-
|
|
841
|
-
ox = 0.175;
|
|
842
|
-
const s = Math.sin(t),
|
|
843
|
-
c = Math.cos(t);
|
|
812
|
+
const a = 0.35, b = 0.15, ox = 0.175;
|
|
813
|
+
const s = Math.sin(t), c = Math.cos(t);
|
|
844
814
|
const denom = 1 + s * s;
|
|
845
815
|
return {
|
|
846
|
-
x:
|
|
847
|
-
y:
|
|
816
|
+
x: c * (1 + a * c) / denom - ox,
|
|
817
|
+
y: s * c * (1 + b * c) / denom
|
|
848
818
|
};
|
|
849
819
|
}
|
|
850
820
|
function epitrochoid7(t, _time, _params) {
|
|
851
821
|
const d = 1 + 0.55 * Math.sin(t * 0.5);
|
|
852
822
|
return {
|
|
853
823
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
854
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
824
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
855
825
|
};
|
|
856
826
|
}
|
|
857
827
|
function epitrochoid7Skeleton(t) {
|
|
858
828
|
const d = 1.275;
|
|
859
829
|
return {
|
|
860
830
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
861
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
831
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
862
832
|
};
|
|
863
833
|
}
|
|
864
834
|
function astroid(t, _time, _params) {
|
|
@@ -866,56 +836,55 @@ function astroid(t, _time, _params) {
|
|
|
866
836
|
const s = Math.sin(t);
|
|
867
837
|
return {
|
|
868
838
|
x: c * c * c,
|
|
869
|
-
y: s * s * s
|
|
839
|
+
y: s * s * s
|
|
870
840
|
};
|
|
871
841
|
}
|
|
872
842
|
function deltoid(t, _time, _params) {
|
|
873
843
|
return {
|
|
874
844
|
x: 2 * Math.cos(t) + Math.cos(2 * t),
|
|
875
|
-
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
845
|
+
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
876
846
|
};
|
|
877
847
|
}
|
|
878
848
|
function rose5(t, _time, _params) {
|
|
879
849
|
const r = Math.cos(5 * t);
|
|
880
850
|
return {
|
|
881
851
|
x: r * Math.cos(t),
|
|
882
|
-
y: r * Math.sin(t)
|
|
852
|
+
y: r * Math.sin(t)
|
|
883
853
|
};
|
|
884
854
|
}
|
|
885
855
|
function rose3(t, _time, _params) {
|
|
886
856
|
const r = Math.cos(3 * t);
|
|
887
857
|
return {
|
|
888
858
|
x: r * Math.cos(t),
|
|
889
|
-
y: r * Math.sin(t)
|
|
859
|
+
y: r * Math.sin(t)
|
|
890
860
|
};
|
|
891
861
|
}
|
|
892
862
|
function lissajous32(t, time, _params) {
|
|
893
863
|
const phi = time * 0.45;
|
|
894
864
|
return {
|
|
895
865
|
x: Math.sin(3 * t + phi),
|
|
896
|
-
y: Math.sin(2 * t)
|
|
866
|
+
y: Math.sin(2 * t)
|
|
897
867
|
};
|
|
898
868
|
}
|
|
899
869
|
function lissajous43(t, time, _params) {
|
|
900
870
|
const phi = time * 0.38;
|
|
901
871
|
return {
|
|
902
872
|
x: Math.sin(4 * t + phi),
|
|
903
|
-
y: Math.sin(3 * t)
|
|
873
|
+
y: Math.sin(3 * t)
|
|
904
874
|
};
|
|
905
875
|
}
|
|
906
876
|
function epicycloid3(t, _time, _params) {
|
|
907
877
|
return {
|
|
908
878
|
x: 4 * Math.cos(t) - Math.cos(4 * t),
|
|
909
|
-
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
879
|
+
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
910
880
|
};
|
|
911
881
|
}
|
|
912
882
|
function lame(t, time, _params) {
|
|
913
883
|
const p = 1.75 + 1.25 * Math.sin(time * 0.48);
|
|
914
|
-
const c = Math.cos(t),
|
|
915
|
-
s = Math.sin(t);
|
|
884
|
+
const c = Math.cos(t), s = Math.sin(t);
|
|
916
885
|
return {
|
|
917
886
|
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
918
|
-
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
887
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
919
888
|
};
|
|
920
889
|
}
|
|
921
890
|
var curves = {
|
|
@@ -923,66 +892,66 @@ var curves = {
|
|
|
923
892
|
name: "Artemis II",
|
|
924
893
|
fn: artemis2,
|
|
925
894
|
period: TWO_PI2,
|
|
926
|
-
speed: 0.7
|
|
895
|
+
speed: 0.7
|
|
927
896
|
},
|
|
928
897
|
epitrochoid7: {
|
|
929
898
|
name: "Epitrochoid",
|
|
930
899
|
fn: epitrochoid7,
|
|
931
900
|
period: TWO_PI2,
|
|
932
901
|
speed: 1.4,
|
|
933
|
-
skeletonFn: epitrochoid7Skeleton
|
|
902
|
+
skeletonFn: epitrochoid7Skeleton
|
|
934
903
|
},
|
|
935
904
|
astroid: {
|
|
936
905
|
name: "Astroid",
|
|
937
906
|
fn: astroid,
|
|
938
907
|
period: TWO_PI2,
|
|
939
|
-
speed: 1.1
|
|
908
|
+
speed: 1.1
|
|
940
909
|
},
|
|
941
910
|
deltoid: {
|
|
942
911
|
name: "Deltoid",
|
|
943
912
|
fn: deltoid,
|
|
944
913
|
period: TWO_PI2,
|
|
945
|
-
speed: 0.9
|
|
914
|
+
speed: 0.9
|
|
946
915
|
},
|
|
947
916
|
rose5: {
|
|
948
917
|
name: "Rose (n=5)",
|
|
949
918
|
fn: rose5,
|
|
950
919
|
period: TWO_PI2,
|
|
951
|
-
speed: 1
|
|
920
|
+
speed: 1
|
|
952
921
|
},
|
|
953
922
|
rose3: {
|
|
954
923
|
name: "Rose (n=3)",
|
|
955
924
|
fn: rose3,
|
|
956
925
|
period: TWO_PI2,
|
|
957
|
-
speed: 1.15
|
|
926
|
+
speed: 1.15
|
|
958
927
|
},
|
|
959
928
|
lissajous32: {
|
|
960
929
|
name: "Lissajous 3:2",
|
|
961
930
|
fn: lissajous32,
|
|
962
931
|
period: TWO_PI2,
|
|
963
932
|
speed: 2,
|
|
964
|
-
skeleton: "live"
|
|
933
|
+
skeleton: "live"
|
|
965
934
|
},
|
|
966
935
|
lissajous43: {
|
|
967
936
|
name: "Lissajous 4:3",
|
|
968
937
|
fn: lissajous43,
|
|
969
938
|
period: TWO_PI2,
|
|
970
939
|
speed: 1.8,
|
|
971
|
-
skeleton: "live"
|
|
940
|
+
skeleton: "live"
|
|
972
941
|
},
|
|
973
942
|
epicycloid3: {
|
|
974
943
|
name: "Epicycloid (n=3)",
|
|
975
944
|
fn: epicycloid3,
|
|
976
945
|
period: TWO_PI2,
|
|
977
|
-
speed: 0.75
|
|
946
|
+
speed: 0.75
|
|
978
947
|
},
|
|
979
948
|
lame: {
|
|
980
949
|
name: "Lam\xE9 Curve",
|
|
981
950
|
fn: lame,
|
|
982
951
|
period: TWO_PI2,
|
|
983
952
|
speed: 1,
|
|
984
|
-
skeleton: "live"
|
|
985
|
-
}
|
|
953
|
+
skeleton: "live"
|
|
954
|
+
}
|
|
986
955
|
};
|
|
987
956
|
|
|
988
957
|
// src/index.ts
|
|
@@ -994,4 +963,4 @@ function createSarmal(canvas, curveDef, options) {
|
|
|
994
963
|
|
|
995
964
|
export { createEngine, createRenderer, createSVGRenderer, createSarmal, createSarmalSVG, curves };
|
|
996
965
|
//# sourceMappingURL=index.js.map
|
|
997
|
-
//# sourceMappingURL=index.js.map
|
|
966
|
+
//# sourceMappingURL=index.js.map
|