@sarmal/core 0.14.0 → 0.15.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 +239 -115
- 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 +238 -114
- 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 +303 -123
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +73 -23
- package/dist/index.d.ts +73 -23
- package/dist/index.js +320 -123
- package/dist/index.js.map +1 -1
- package/dist/types-BL9HhEmk.d.cts +312 -0
- package/dist/types-BL9HhEmk.d.ts +312 -0
- package/package.json +1 -1
- package/dist/types-BQosOzlf.d.cts +0 -276
- package/dist/types-BQosOzlf.d.ts +0 -276
package/dist/auto-init.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
|
|
|
@@ -315,13 +321,16 @@ function computeTrailQuad(trail, i, trailCount, toX, toY) {
|
|
|
315
321
|
r1x: nx - n1.x * w1,
|
|
316
322
|
r1y: ny - n1.y * w1,
|
|
317
323
|
opacity,
|
|
318
|
-
progress
|
|
324
|
+
progress,
|
|
319
325
|
};
|
|
320
326
|
}
|
|
321
327
|
function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
322
328
|
if (pts.length === 0) return null;
|
|
323
329
|
const first = pts[0];
|
|
324
|
-
let minX = first.x,
|
|
330
|
+
let minX = first.x,
|
|
331
|
+
maxX = first.x,
|
|
332
|
+
minY = first.y,
|
|
333
|
+
maxY = first.y;
|
|
325
334
|
for (const p of pts) {
|
|
326
335
|
if (p.x < minX) {
|
|
327
336
|
minX = p.x;
|
|
@@ -340,7 +349,7 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
|
340
349
|
const h = maxY - minY;
|
|
341
350
|
if (w === 0 && h === 0) {
|
|
342
351
|
throw new Error(
|
|
343
|
-
"[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.",
|
|
344
353
|
);
|
|
345
354
|
}
|
|
346
355
|
const scaleXProportional = logicalWidth / (w * (1 + FIT_PADDING * 2));
|
|
@@ -351,12 +360,12 @@ function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
|
351
360
|
scaleXProportional,
|
|
352
361
|
scaleYProportional,
|
|
353
362
|
scaleXMinPadding,
|
|
354
|
-
scaleYMinPadding
|
|
363
|
+
scaleYMinPadding,
|
|
355
364
|
);
|
|
356
365
|
return {
|
|
357
366
|
scale,
|
|
358
367
|
offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
|
|
359
|
-
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
368
|
+
offsetY: (logicalHeight - h * scale) / 2 - minY * scale,
|
|
360
369
|
};
|
|
361
370
|
}
|
|
362
371
|
function enginePassthroughs(engine) {
|
|
@@ -366,33 +375,17 @@ function enginePassthroughs(engine) {
|
|
|
366
375
|
setSpeed: engine.setSpeed,
|
|
367
376
|
getSpeed: engine.getSpeed,
|
|
368
377
|
resetSpeed: engine.resetSpeed,
|
|
369
|
-
setSpeedOver: engine.setSpeedOver
|
|
378
|
+
setSpeedOver: engine.setSpeedOver,
|
|
370
379
|
};
|
|
371
380
|
}
|
|
372
|
-
var GRADIENT = {
|
|
373
|
-
bard: ["#a855f7", "#3b82f6", "#14b8a6", "#ec4899"],
|
|
374
|
-
sunset: ["#f97316", "#dc2626", "#9333ea", "#f472b6"],
|
|
375
|
-
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
376
|
-
ice: ["#1e3a8a", "#67e8f9"],
|
|
377
|
-
fire: ["#7f1d1d", "#fbbf24"],
|
|
378
|
-
forest: ["#14532d", "#86efac"]
|
|
379
|
-
};
|
|
380
|
-
var PRESETS = {
|
|
381
|
-
bard: GRADIENT.bard,
|
|
382
|
-
sunset: GRADIENT.sunset,
|
|
383
|
-
ocean: GRADIENT.ocean,
|
|
384
|
-
ice: GRADIENT.ice,
|
|
385
|
-
fire: GRADIENT.fire,
|
|
386
|
-
forest: GRADIENT.forest
|
|
387
|
-
};
|
|
388
381
|
function hexToRgb(hex) {
|
|
389
382
|
const n = parseInt(hex.slice(1), 16);
|
|
390
|
-
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
383
|
+
return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
|
|
391
384
|
}
|
|
392
385
|
var lerpRgb = (a, b, t) => ({
|
|
393
386
|
r: Math.round(a.r + (b.r - a.r) * t),
|
|
394
387
|
g: Math.round(a.g + (b.g - a.g) * t),
|
|
395
|
-
b: Math.round(a.b + (b.b - a.b) * t)
|
|
388
|
+
b: Math.round(a.b + (b.b - a.b) * t),
|
|
396
389
|
});
|
|
397
390
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
398
391
|
if (palette.length === 0) {
|
|
@@ -409,21 +402,123 @@ function getPaletteColor(palette, position, timeOffset = 0) {
|
|
|
409
402
|
const c2 = hexToRgb(palette[(idx + 1) % palette.length]);
|
|
410
403
|
return lerpRgb(c1, c2, t);
|
|
411
404
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
405
|
+
var HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;
|
|
406
|
+
var TRAIL_STYLES = ["default", "gradient-static", "gradient-animated"];
|
|
407
|
+
var RENDER_OPTION_KEYS = /* @__PURE__ */ new Set([
|
|
408
|
+
"trailColor",
|
|
409
|
+
"headColor",
|
|
410
|
+
"skeletonColor",
|
|
411
|
+
"trailStyle",
|
|
412
|
+
]);
|
|
413
|
+
function validateRenderOptions(partial) {
|
|
414
|
+
for (const key of Object.keys(partial)) {
|
|
415
|
+
if (!RENDER_OPTION_KEYS.has(key)) {
|
|
416
|
+
throw new TypeError(`[sarmal] setRenderOptions: unknown key "${key}"`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
if (partial.trailColor !== void 0) {
|
|
420
|
+
assertTrailColor(partial.trailColor);
|
|
421
|
+
}
|
|
422
|
+
if (partial.headColor !== void 0) {
|
|
423
|
+
assertHeadColor(partial.headColor);
|
|
424
|
+
}
|
|
425
|
+
if (partial.skeletonColor !== void 0) {
|
|
426
|
+
assertSkeletonColor(partial.skeletonColor);
|
|
415
427
|
}
|
|
416
|
-
if (
|
|
417
|
-
|
|
428
|
+
if (partial.trailStyle !== void 0) {
|
|
429
|
+
assertTrailStyle(partial.trailStyle);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function assertTrailColor(value) {
|
|
433
|
+
if (typeof value === "string") {
|
|
434
|
+
if (!HEX_COLOR_RE.test(value)) {
|
|
435
|
+
throw new TypeError(
|
|
436
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string, got "${value}"`,
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
if (Array.isArray(value)) {
|
|
442
|
+
if (value.length < 2) {
|
|
443
|
+
throw new RangeError(
|
|
444
|
+
`[sarmal] setRenderOptions: trailColor array must have at least 2 entries, got ${value.length}`,
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
for (let i = 0; i < value.length; i++) {
|
|
448
|
+
const entry = value[i];
|
|
449
|
+
if (typeof entry !== "string" || !HEX_COLOR_RE.test(entry)) {
|
|
450
|
+
throw new TypeError(
|
|
451
|
+
`[sarmal] setRenderOptions: trailColor[${i}] must be a 6-digit hex string, got ${JSON.stringify(entry)}`,
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
throw new TypeError(
|
|
458
|
+
`[sarmal] setRenderOptions: trailColor must be a 6-digit hex string or an array of hex strings, got ${JSON.stringify(value)}`,
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
function assertHeadColor(value) {
|
|
462
|
+
if (value === null) {
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
466
|
+
throw new TypeError(
|
|
467
|
+
`[sarmal] setRenderOptions: headColor must be a 6-digit hex string or null, got ${JSON.stringify(value)}`,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
function assertSkeletonColor(value) {
|
|
472
|
+
if (value === "transparent") {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (typeof value !== "string" || !HEX_COLOR_RE.test(value)) {
|
|
476
|
+
throw new TypeError(
|
|
477
|
+
`[sarmal] setRenderOptions: skeletonColor must be a 6-digit hex string or "transparent", got ${JSON.stringify(value)}`,
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
function assertTrailStyle(value) {
|
|
482
|
+
if (!TRAIL_STYLES.includes(value)) {
|
|
483
|
+
throw new RangeError(
|
|
484
|
+
`[sarmal] setRenderOptions: trailStyle must be one of "default", "gradient-static", "gradient-animated", got ${JSON.stringify(value)}`,
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function resolveTrailMainColor(trailColor) {
|
|
489
|
+
return typeof trailColor === "string" ? trailColor : trailColor[0];
|
|
490
|
+
}
|
|
491
|
+
function resolveTrailPalette(trailColor) {
|
|
492
|
+
return typeof trailColor === "string" ? [trailColor] : trailColor;
|
|
493
|
+
}
|
|
494
|
+
function resolveHeadColor(trailColor, trailStyle) {
|
|
495
|
+
if (trailStyle === "default") {
|
|
496
|
+
return resolveTrailMainColor(trailColor);
|
|
497
|
+
}
|
|
498
|
+
const palette = resolveTrailPalette(trailColor);
|
|
499
|
+
const last = palette[palette.length - 1];
|
|
500
|
+
const { r, g, b } = hexToRgb(last);
|
|
501
|
+
return `rgb(${r},${g},${b})`;
|
|
502
|
+
}
|
|
503
|
+
function warnIfTrailColorMismatch(trailColor, trailStyle) {
|
|
504
|
+
if (trailStyle === "default" && Array.isArray(trailColor)) {
|
|
505
|
+
console.warn(
|
|
506
|
+
'[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.',
|
|
507
|
+
);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
if (trailStyle !== "default" && typeof trailColor === "string") {
|
|
511
|
+
console.warn(
|
|
512
|
+
`[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.`,
|
|
513
|
+
);
|
|
418
514
|
}
|
|
419
|
-
return trailStyle === "gradient-animated" ? GRADIENT.bard : GRADIENT.ice;
|
|
420
515
|
}
|
|
421
516
|
|
|
422
517
|
// src/renderer.ts
|
|
423
|
-
var
|
|
518
|
+
var WHITE_HEX = "#ffffff";
|
|
424
519
|
function hexToRgbComponents(hex) {
|
|
425
520
|
const n = parseInt(hex.slice(1), 16);
|
|
426
|
-
return `${n >> 16},${n >> 8 & 255},${n & 255}`;
|
|
521
|
+
return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
|
|
427
522
|
}
|
|
428
523
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
429
524
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -438,22 +533,14 @@ function createRenderer(options) {
|
|
|
438
533
|
}
|
|
439
534
|
const ctx = canvas.getContext("2d");
|
|
440
535
|
const engine = options.engine;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
return trailColor;
|
|
450
|
-
}
|
|
451
|
-
const opts = {
|
|
452
|
-
skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,
|
|
453
|
-
trailColor,
|
|
454
|
-
headColor: options.headColor ?? defaultHeadColor()
|
|
455
|
-
};
|
|
456
|
-
const trailRgb = hexToRgbComponents(opts.trailColor);
|
|
536
|
+
let trailStyle = options.trailStyle ?? "default";
|
|
537
|
+
let trailColor = options.trailColor ?? WHITE_HEX;
|
|
538
|
+
let skeletonColor = options.skeletonColor ?? WHITE_HEX;
|
|
539
|
+
let userHeadColor = options.headColor ?? null;
|
|
540
|
+
let headColor = userHeadColor ?? resolveHeadColor(trailColor, trailStyle);
|
|
541
|
+
let trailSolidRgb = hexToRgbComponents(resolveTrailMainColor(trailColor));
|
|
542
|
+
let trailPalette = resolveTrailPalette(trailColor);
|
|
543
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
457
544
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
458
545
|
function setupCanvas() {
|
|
459
546
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -488,11 +575,13 @@ function createRenderer(options) {
|
|
|
488
575
|
}
|
|
489
576
|
}
|
|
490
577
|
function buildSkeletonCanvas() {
|
|
491
|
-
if (skeleton.length < 2)
|
|
578
|
+
if (skeleton.length < 2) {
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
492
581
|
skeletonCanvas = new OffscreenCanvas(canvas.width, canvas.height);
|
|
493
582
|
const skeletonCtx = skeletonCanvas.getContext("2d");
|
|
494
583
|
skeletonCtx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
495
|
-
skeletonCtx.strokeStyle = `rgba(${hexToRgbComponents(
|
|
584
|
+
skeletonCtx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
496
585
|
skeletonCtx.lineWidth = 1.5;
|
|
497
586
|
skeletonCtx.beginPath();
|
|
498
587
|
const first = skeleton[0];
|
|
@@ -504,8 +593,10 @@ function createRenderer(options) {
|
|
|
504
593
|
skeletonCtx.stroke();
|
|
505
594
|
}
|
|
506
595
|
function drawSkeletonPath(pts, opacity) {
|
|
507
|
-
if (pts.length < 2)
|
|
508
|
-
|
|
596
|
+
if (pts.length < 2) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
ctx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${opacity})`;
|
|
509
600
|
ctx.lineWidth = 1.5;
|
|
510
601
|
ctx.beginPath();
|
|
511
602
|
ctx.moveTo(pts[0].x * scale + offsetX, pts[0].y * scale + offsetY);
|
|
@@ -515,7 +606,7 @@ function createRenderer(options) {
|
|
|
515
606
|
ctx.stroke();
|
|
516
607
|
}
|
|
517
608
|
function drawSkeleton() {
|
|
518
|
-
if (
|
|
609
|
+
if (skeletonColor === "transparent") {
|
|
519
610
|
return;
|
|
520
611
|
}
|
|
521
612
|
if (engine.morphAlpha !== null) {
|
|
@@ -526,7 +617,7 @@ function createRenderer(options) {
|
|
|
526
617
|
if (skeleton.length < 2) {
|
|
527
618
|
return;
|
|
528
619
|
}
|
|
529
|
-
ctx.strokeStyle = `rgba(${hexToRgbComponents(
|
|
620
|
+
ctx.strokeStyle = `rgba(${hexToRgbComponents(skeletonColor)},${DEFAULT_SKELETON_OPACITY})`;
|
|
530
621
|
ctx.lineWidth = 1.5;
|
|
531
622
|
ctx.beginPath();
|
|
532
623
|
const first = skeleton[0];
|
|
@@ -552,13 +643,13 @@ function createRenderer(options) {
|
|
|
552
643
|
i,
|
|
553
644
|
trailCount,
|
|
554
645
|
toX,
|
|
555
|
-
toY
|
|
646
|
+
toY,
|
|
556
647
|
);
|
|
557
648
|
if (trailStyle === "default") {
|
|
558
|
-
ctx.fillStyle = `rgba(${
|
|
649
|
+
ctx.fillStyle = `rgba(${trailSolidRgb},${opacity})`;
|
|
559
650
|
} else {
|
|
560
651
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
561
|
-
const color = getPaletteColor(
|
|
652
|
+
const color = getPaletteColor(trailPalette, progress, timeOffset);
|
|
562
653
|
ctx.fillStyle = `rgba(${color.r},${color.g},${color.b},${opacity})`;
|
|
563
654
|
}
|
|
564
655
|
ctx.beginPath();
|
|
@@ -576,8 +667,9 @@ function createRenderer(options) {
|
|
|
576
667
|
}
|
|
577
668
|
const x = head.x * scale + offsetX;
|
|
578
669
|
const y = head.y * scale + offsetY;
|
|
579
|
-
const r =
|
|
580
|
-
|
|
670
|
+
const r =
|
|
671
|
+
options.headRadius ?? Math.max(2, 3 * Math.sqrt(Math.min(logicalWidth, logicalHeight) / 160));
|
|
672
|
+
ctx.fillStyle = headColor;
|
|
581
673
|
ctx.beginPath();
|
|
582
674
|
ctx.arc(x, y, r, 0, Math.PI * 2);
|
|
583
675
|
ctx.fill();
|
|
@@ -677,7 +769,35 @@ function createRenderer(options) {
|
|
|
677
769
|
return new Promise((resolve) => {
|
|
678
770
|
morphResolve = resolve;
|
|
679
771
|
});
|
|
680
|
-
}
|
|
772
|
+
},
|
|
773
|
+
setRenderOptions(partial) {
|
|
774
|
+
validateRenderOptions(partial);
|
|
775
|
+
if (partial.trailColor !== void 0) {
|
|
776
|
+
trailColor = partial.trailColor;
|
|
777
|
+
trailSolidRgb = hexToRgbComponents(resolveTrailMainColor(trailColor));
|
|
778
|
+
trailPalette = resolveTrailPalette(trailColor);
|
|
779
|
+
}
|
|
780
|
+
if (partial.skeletonColor !== void 0) {
|
|
781
|
+
skeletonColor = partial.skeletonColor;
|
|
782
|
+
if (skeletonColor !== "transparent" && !engine.isLiveSkeleton) {
|
|
783
|
+
buildSkeletonCanvas();
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (partial.trailStyle !== void 0) {
|
|
787
|
+
trailStyle = partial.trailStyle;
|
|
788
|
+
}
|
|
789
|
+
if (partial.headColor !== void 0) {
|
|
790
|
+
userHeadColor = partial.headColor;
|
|
791
|
+
}
|
|
792
|
+
if (userHeadColor === null) {
|
|
793
|
+
headColor = resolveHeadColor(trailColor, trailStyle);
|
|
794
|
+
} else {
|
|
795
|
+
headColor = userHeadColor;
|
|
796
|
+
}
|
|
797
|
+
if (partial.trailColor !== void 0 || partial.trailStyle !== void 0) {
|
|
798
|
+
warnIfTrailColorMismatch(trailColor, trailStyle);
|
|
799
|
+
}
|
|
800
|
+
},
|
|
681
801
|
};
|
|
682
802
|
if (shouldAutoStart) {
|
|
683
803
|
instance.play();
|
|
@@ -688,19 +808,22 @@ function createRenderer(options) {
|
|
|
688
808
|
// src/curves/artemis2.ts
|
|
689
809
|
var TWO_PI2 = Math.PI * 2;
|
|
690
810
|
function artemis2Fn(t, _time, _params) {
|
|
691
|
-
const a = 0.35,
|
|
692
|
-
|
|
811
|
+
const a = 0.35,
|
|
812
|
+
b = 0.15,
|
|
813
|
+
ox = 0.175;
|
|
814
|
+
const s = Math.sin(t),
|
|
815
|
+
c = Math.cos(t);
|
|
693
816
|
const denom = 1 + s * s;
|
|
694
817
|
return {
|
|
695
|
-
x: c * (1 + a * c) / denom - ox,
|
|
696
|
-
y: s * c * (1 + b * c) / denom
|
|
818
|
+
x: (c * (1 + a * c)) / denom - ox,
|
|
819
|
+
y: (s * c * (1 + b * c)) / denom,
|
|
697
820
|
};
|
|
698
821
|
}
|
|
699
822
|
var artemis2 = {
|
|
700
823
|
name: "Artemis II",
|
|
701
824
|
fn: artemis2Fn,
|
|
702
825
|
period: TWO_PI2,
|
|
703
|
-
speed: 0.7
|
|
826
|
+
speed: 0.7,
|
|
704
827
|
};
|
|
705
828
|
|
|
706
829
|
// src/curves/astroid.ts
|
|
@@ -710,14 +833,14 @@ function astroidFn(t, _time, _params) {
|
|
|
710
833
|
const s = Math.sin(t);
|
|
711
834
|
return {
|
|
712
835
|
x: c * c * c,
|
|
713
|
-
y: s * s * s
|
|
836
|
+
y: s * s * s,
|
|
714
837
|
};
|
|
715
838
|
}
|
|
716
839
|
var astroid = {
|
|
717
840
|
name: "Astroid",
|
|
718
841
|
fn: astroidFn,
|
|
719
842
|
period: TWO_PI3,
|
|
720
|
-
speed: 1.1
|
|
843
|
+
speed: 1.1,
|
|
721
844
|
};
|
|
722
845
|
|
|
723
846
|
// src/curves/deltoid.ts
|
|
@@ -725,14 +848,14 @@ var TWO_PI4 = Math.PI * 2;
|
|
|
725
848
|
function deltoidFn(t, _time, _params) {
|
|
726
849
|
return {
|
|
727
850
|
x: 2 * Math.cos(t) + Math.cos(2 * t),
|
|
728
|
-
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
851
|
+
y: 2 * Math.sin(t) - Math.sin(2 * t),
|
|
729
852
|
};
|
|
730
853
|
}
|
|
731
854
|
var deltoid = {
|
|
732
855
|
name: "Deltoid",
|
|
733
856
|
fn: deltoidFn,
|
|
734
857
|
period: TWO_PI4,
|
|
735
|
-
speed: 0.9
|
|
858
|
+
speed: 0.9,
|
|
736
859
|
};
|
|
737
860
|
|
|
738
861
|
// src/curves/epicycloid3.ts
|
|
@@ -740,14 +863,14 @@ var TWO_PI5 = Math.PI * 2;
|
|
|
740
863
|
function epicycloid3Fn(t, _time, _params) {
|
|
741
864
|
return {
|
|
742
865
|
x: 4 * Math.cos(t) - Math.cos(4 * t),
|
|
743
|
-
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
866
|
+
y: 4 * Math.sin(t) - Math.sin(4 * t),
|
|
744
867
|
};
|
|
745
868
|
}
|
|
746
869
|
var epicycloid3 = {
|
|
747
870
|
name: "Epicycloid (n=3)",
|
|
748
871
|
fn: epicycloid3Fn,
|
|
749
872
|
period: TWO_PI5,
|
|
750
|
-
speed: 0.75
|
|
873
|
+
speed: 0.75,
|
|
751
874
|
};
|
|
752
875
|
|
|
753
876
|
// src/curves/epitrochoid7.ts
|
|
@@ -756,14 +879,14 @@ function epitrochoid7Fn(t, _time, _params) {
|
|
|
756
879
|
const d = 1 + 0.55 * Math.sin(t * 0.5);
|
|
757
880
|
return {
|
|
758
881
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
759
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
882
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
760
883
|
};
|
|
761
884
|
}
|
|
762
885
|
function epitrochoid7SkeletonFn(t) {
|
|
763
886
|
const d = 1.275;
|
|
764
887
|
return {
|
|
765
888
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
766
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
889
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
767
890
|
};
|
|
768
891
|
}
|
|
769
892
|
var epitrochoid7 = {
|
|
@@ -771,7 +894,7 @@ var epitrochoid7 = {
|
|
|
771
894
|
fn: epitrochoid7Fn,
|
|
772
895
|
period: TWO_PI6,
|
|
773
896
|
speed: 1.4,
|
|
774
|
-
skeletonFn: epitrochoid7SkeletonFn
|
|
897
|
+
skeletonFn: epitrochoid7SkeletonFn,
|
|
775
898
|
};
|
|
776
899
|
|
|
777
900
|
// src/curves/lissajous32.ts
|
|
@@ -780,7 +903,7 @@ function lissajous32Fn(t, time, _params) {
|
|
|
780
903
|
const phi = time * 0.45;
|
|
781
904
|
return {
|
|
782
905
|
x: Math.sin(3 * t + phi),
|
|
783
|
-
y: Math.sin(2 * t)
|
|
906
|
+
y: Math.sin(2 * t),
|
|
784
907
|
};
|
|
785
908
|
}
|
|
786
909
|
var lissajous32 = {
|
|
@@ -788,7 +911,7 @@ var lissajous32 = {
|
|
|
788
911
|
fn: lissajous32Fn,
|
|
789
912
|
period: TWO_PI7,
|
|
790
913
|
speed: 2,
|
|
791
|
-
skeleton: "live"
|
|
914
|
+
skeleton: "live",
|
|
792
915
|
};
|
|
793
916
|
|
|
794
917
|
// src/curves/lissajous43.ts
|
|
@@ -797,7 +920,7 @@ function lissajous43Fn(t, time, _params) {
|
|
|
797
920
|
const phi = time * 0.38;
|
|
798
921
|
return {
|
|
799
922
|
x: Math.sin(4 * t + phi),
|
|
800
|
-
y: Math.sin(3 * t)
|
|
923
|
+
y: Math.sin(3 * t),
|
|
801
924
|
};
|
|
802
925
|
}
|
|
803
926
|
var lissajous43 = {
|
|
@@ -805,17 +928,18 @@ var lissajous43 = {
|
|
|
805
928
|
fn: lissajous43Fn,
|
|
806
929
|
period: TWO_PI8,
|
|
807
930
|
speed: 1.8,
|
|
808
|
-
skeleton: "live"
|
|
931
|
+
skeleton: "live",
|
|
809
932
|
};
|
|
810
933
|
|
|
811
934
|
// src/curves/lame.ts
|
|
812
935
|
var TWO_PI9 = Math.PI * 2;
|
|
813
936
|
function lameFn(t, time, _params) {
|
|
814
937
|
const p = 1.75 + 1.25 * Math.sin(time * 0.48);
|
|
815
|
-
const c = Math.cos(t),
|
|
938
|
+
const c = Math.cos(t),
|
|
939
|
+
s = Math.sin(t);
|
|
816
940
|
return {
|
|
817
941
|
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
818
|
-
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
942
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p),
|
|
819
943
|
};
|
|
820
944
|
}
|
|
821
945
|
var lame = {
|
|
@@ -823,7 +947,7 @@ var lame = {
|
|
|
823
947
|
fn: lameFn,
|
|
824
948
|
period: TWO_PI9,
|
|
825
949
|
speed: 1,
|
|
826
|
-
skeleton: "live"
|
|
950
|
+
skeleton: "live",
|
|
827
951
|
};
|
|
828
952
|
|
|
829
953
|
// src/curves/rose3.ts
|
|
@@ -832,14 +956,14 @@ function rose3Fn(t, _time, _params) {
|
|
|
832
956
|
const r = Math.cos(3 * t);
|
|
833
957
|
return {
|
|
834
958
|
x: r * Math.cos(t),
|
|
835
|
-
y: r * Math.sin(t)
|
|
959
|
+
y: r * Math.sin(t),
|
|
836
960
|
};
|
|
837
961
|
}
|
|
838
962
|
var rose3 = {
|
|
839
963
|
name: "Rose (n=3)",
|
|
840
964
|
fn: rose3Fn,
|
|
841
965
|
period: TWO_PI10,
|
|
842
|
-
speed: 1.15
|
|
966
|
+
speed: 1.15,
|
|
843
967
|
};
|
|
844
968
|
|
|
845
969
|
// src/curves/rose5.ts
|
|
@@ -848,14 +972,14 @@ function rose5Fn(t, _time, _params) {
|
|
|
848
972
|
const r = Math.cos(5 * t);
|
|
849
973
|
return {
|
|
850
974
|
x: r * Math.cos(t),
|
|
851
|
-
y: r * Math.sin(t)
|
|
975
|
+
y: r * Math.sin(t),
|
|
852
976
|
};
|
|
853
977
|
}
|
|
854
978
|
var rose5 = {
|
|
855
979
|
name: "Rose (n=5)",
|
|
856
980
|
fn: rose5Fn,
|
|
857
981
|
period: TWO_PI11,
|
|
858
|
-
speed: 1
|
|
982
|
+
speed: 1,
|
|
859
983
|
};
|
|
860
984
|
|
|
861
985
|
// src/curves/index.ts
|
|
@@ -869,7 +993,7 @@ var curves = {
|
|
|
869
993
|
lissajous32,
|
|
870
994
|
lissajous43,
|
|
871
995
|
epicycloid3,
|
|
872
|
-
lame
|
|
996
|
+
lame,
|
|
873
997
|
};
|
|
874
998
|
|
|
875
999
|
// src/index.ts
|
|
@@ -880,14 +1004,13 @@ function createSarmal(canvas, curveDef, options) {
|
|
|
880
1004
|
}
|
|
881
1005
|
|
|
882
1006
|
// src/auto-init.ts
|
|
883
|
-
function
|
|
1007
|
+
function parseTrailColor(value) {
|
|
884
1008
|
try {
|
|
885
1009
|
const parsed = JSON.parse(value);
|
|
886
1010
|
if (Array.isArray(parsed)) {
|
|
887
1011
|
return parsed;
|
|
888
1012
|
}
|
|
889
|
-
} catch {
|
|
890
|
-
}
|
|
1013
|
+
} catch {}
|
|
891
1014
|
return value;
|
|
892
1015
|
}
|
|
893
1016
|
function init() {
|
|
@@ -902,15 +1025,16 @@ function init() {
|
|
|
902
1025
|
return console.error(`[sarmal] "${curveName}" is not a valid curve name`);
|
|
903
1026
|
}
|
|
904
1027
|
createSarmal(canvas, curveDef, {
|
|
905
|
-
...canvas.dataset.trailColor && {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
...canvas.dataset.
|
|
909
|
-
...canvas.dataset.
|
|
910
|
-
...canvas.dataset.
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1028
|
+
...(canvas.dataset.trailColor && {
|
|
1029
|
+
trailColor: parseTrailColor(canvas.dataset.trailColor),
|
|
1030
|
+
}),
|
|
1031
|
+
...(canvas.dataset.skeletonColor && { skeletonColor: canvas.dataset.skeletonColor }),
|
|
1032
|
+
...(canvas.dataset.headColor && { headColor: canvas.dataset.headColor }),
|
|
1033
|
+
...(canvas.dataset.headRadius && { headRadius: parseFloat(canvas.dataset.headRadius) }),
|
|
1034
|
+
...(canvas.dataset.trailLength && { trailLength: parseInt(canvas.dataset.trailLength, 10) }),
|
|
1035
|
+
...(canvas.dataset.trailStyle && {
|
|
1036
|
+
trailStyle: canvas.dataset.trailStyle,
|
|
1037
|
+
}),
|
|
914
1038
|
});
|
|
915
1039
|
});
|
|
916
1040
|
}
|
|
@@ -922,4 +1046,4 @@ if (document.readyState === "loading") {
|
|
|
922
1046
|
requestAnimationFrame(init);
|
|
923
1047
|
}
|
|
924
1048
|
//# sourceMappingURL=auto-init.cjs.map
|
|
925
|
-
//# sourceMappingURL=auto-init.cjs.map
|
|
1049
|
+
//# sourceMappingURL=auto-init.cjs.map
|