@sarmal/core 0.9.0 → 0.9.7
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 +255 -154
- 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 +254 -153
- package/dist/auto-init.js.map +1 -1
- package/dist/curves/artemis2.cjs +26 -0
- package/dist/curves/artemis2.cjs.map +1 -0
- package/dist/curves/artemis2.d.cts +9 -0
- package/dist/curves/artemis2.d.ts +9 -0
- package/dist/curves/artemis2.js +24 -0
- package/dist/curves/artemis2.js.map +1 -0
- package/dist/curves/astroid.cjs +22 -0
- package/dist/curves/astroid.cjs.map +1 -0
- package/dist/curves/astroid.d.cts +9 -0
- package/dist/curves/astroid.d.ts +9 -0
- package/dist/curves/astroid.js +20 -0
- package/dist/curves/astroid.js.map +1 -0
- package/dist/curves/deltoid.cjs +20 -0
- package/dist/curves/deltoid.cjs.map +1 -0
- package/dist/curves/deltoid.d.cts +9 -0
- package/dist/curves/deltoid.d.ts +9 -0
- package/dist/curves/deltoid.js +18 -0
- package/dist/curves/deltoid.js.map +1 -0
- package/dist/curves/epicycloid3.cjs +20 -0
- package/dist/curves/epicycloid3.cjs.map +1 -0
- package/dist/curves/epicycloid3.d.cts +9 -0
- package/dist/curves/epicycloid3.d.ts +9 -0
- package/dist/curves/epicycloid3.js +18 -0
- package/dist/curves/epicycloid3.js.map +1 -0
- package/dist/curves/epitrochoid7.cjs +29 -0
- package/dist/curves/epitrochoid7.cjs.map +1 -0
- package/dist/curves/epitrochoid7.d.cts +9 -0
- package/dist/curves/epitrochoid7.d.ts +9 -0
- package/dist/curves/epitrochoid7.js +27 -0
- package/dist/curves/epitrochoid7.js.map +1 -0
- package/dist/curves/index.cjs +206 -0
- package/dist/curves/index.cjs.map +1 -0
- package/dist/curves/index.d.cts +19 -0
- package/dist/curves/index.d.ts +19 -0
- package/dist/curves/index.js +206 -0
- package/dist/curves/index.js.map +1 -0
- package/dist/curves/lame.cjs +24 -0
- package/dist/curves/lame.cjs.map +1 -0
- package/dist/curves/lame.d.cts +9 -0
- package/dist/curves/lame.d.ts +9 -0
- package/dist/curves/lame.js +22 -0
- package/dist/curves/lame.js.map +1 -0
- package/dist/curves/lissajous32.cjs +22 -0
- package/dist/curves/lissajous32.cjs.map +1 -0
- package/dist/curves/lissajous32.d.cts +9 -0
- package/dist/curves/lissajous32.d.ts +9 -0
- package/dist/curves/lissajous32.js +20 -0
- package/dist/curves/lissajous32.js.map +1 -0
- package/dist/curves/lissajous43.cjs +22 -0
- package/dist/curves/lissajous43.cjs.map +1 -0
- package/dist/curves/lissajous43.d.cts +9 -0
- package/dist/curves/lissajous43.d.ts +9 -0
- package/dist/curves/lissajous43.js +20 -0
- package/dist/curves/lissajous43.js.map +1 -0
- package/dist/curves/rose3.cjs +21 -0
- package/dist/curves/rose3.cjs.map +1 -0
- package/dist/curves/rose3.d.cts +9 -0
- package/dist/curves/rose3.d.ts +9 -0
- package/dist/curves/rose3.js +19 -0
- package/dist/curves/rose3.js.map +1 -0
- package/dist/curves/rose5.cjs +21 -0
- package/dist/curves/rose5.cjs.map +1 -0
- package/dist/curves/rose5.d.cts +9 -0
- package/dist/curves/rose5.d.ts +9 -0
- package/dist/curves/rose5.js +19 -0
- package/dist/curves/rose5.js.map +1 -0
- package/dist/index.cjs +263 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -233
- package/dist/index.d.ts +64 -233
- package/dist/index.js +270 -154
- package/dist/index.js.map +1 -1
- package/dist/types-cR2xOewv.d.cts +234 -0
- package/dist/types-cR2xOewv.d.ts +234 -0
- package/package.json +14 -3
package/dist/auto-init.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// src/engine.ts
|
|
2
2
|
var TWO_PI = Math.PI * 2;
|
|
3
3
|
var POINTS_PER_PERIOD_UNIT = 50;
|
|
4
|
+
function lerp(start, end, t) {
|
|
5
|
+
return start + (end - start) * t;
|
|
6
|
+
}
|
|
7
|
+
var EMPTY_PARAMS = {};
|
|
4
8
|
var CircularBuffer = class {
|
|
5
9
|
constructor(capacity) {
|
|
6
10
|
this.head = 0;
|
|
@@ -43,16 +47,29 @@ var CircularBuffer = class {
|
|
|
43
47
|
}
|
|
44
48
|
};
|
|
45
49
|
function resolveCurve(curveDef) {
|
|
50
|
+
const period = curveDef.period ?? TWO_PI;
|
|
51
|
+
if (!Number.isFinite(period) || period <= 0) {
|
|
52
|
+
throw new RangeError(`[sarmal] period must be a positive finite number, got ${period}`);
|
|
53
|
+
}
|
|
54
|
+
const speed = curveDef.speed ?? 1;
|
|
55
|
+
if (!Number.isFinite(speed)) {
|
|
56
|
+
throw new RangeError(`[sarmal] speed must be a finite number, got ${speed}`);
|
|
57
|
+
}
|
|
46
58
|
return {
|
|
47
59
|
name: curveDef.name,
|
|
48
60
|
fn: curveDef.fn,
|
|
49
|
-
period
|
|
50
|
-
speed
|
|
61
|
+
period,
|
|
62
|
+
speed,
|
|
51
63
|
skeleton: curveDef.skeleton,
|
|
52
|
-
skeletonFn: curveDef.skeletonFn
|
|
64
|
+
skeletonFn: curveDef.skeletonFn,
|
|
53
65
|
};
|
|
54
66
|
}
|
|
55
67
|
function createEngine(curveDef, trailLength = 120) {
|
|
68
|
+
if (!Number.isFinite(trailLength) || trailLength <= 0) {
|
|
69
|
+
throw new RangeError(
|
|
70
|
+
`[sarmal] trailLength must be a positive finite number, got ${trailLength}`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
56
73
|
let curve = resolveCurve(curveDef);
|
|
57
74
|
const trail = new CircularBuffer(trailLength);
|
|
58
75
|
let t = 0;
|
|
@@ -65,21 +82,25 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
65
82
|
return c.skeletonFn(sampleT);
|
|
66
83
|
}
|
|
67
84
|
if (c.skeleton === "live") {
|
|
68
|
-
return c.fn(sampleT, actualTime,
|
|
85
|
+
return c.fn(sampleT, actualTime, EMPTY_PARAMS);
|
|
69
86
|
}
|
|
70
|
-
return c.fn(sampleT, 0,
|
|
87
|
+
return c.fn(sampleT, 0, EMPTY_PARAMS);
|
|
71
88
|
}
|
|
72
89
|
return {
|
|
73
90
|
tick(deltaTime) {
|
|
74
|
-
|
|
91
|
+
let effectiveSpeed = curve.speed;
|
|
92
|
+
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
93
|
+
effectiveSpeed = lerp(curve.speed, morphCurveB.speed, _morphAlpha);
|
|
94
|
+
}
|
|
95
|
+
t = (t + effectiveSpeed * deltaTime) % curve.period;
|
|
75
96
|
actualTime += deltaTime;
|
|
76
97
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
77
|
-
const a = curve.fn(t, actualTime,
|
|
78
|
-
const tB = _morphStrategy === "normalized" ? t / curve.period * morphCurveB.period : t;
|
|
79
|
-
const b = morphCurveB.fn(tB, actualTime,
|
|
98
|
+
const a = curve.fn(t, actualTime, EMPTY_PARAMS);
|
|
99
|
+
const tB = _morphStrategy === "normalized" ? (t / curve.period) * morphCurveB.period : t;
|
|
100
|
+
const b = morphCurveB.fn(tB, actualTime, EMPTY_PARAMS);
|
|
80
101
|
trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
|
|
81
102
|
} else {
|
|
82
|
-
const point = curve.fn(t, actualTime,
|
|
103
|
+
const point = curve.fn(t, actualTime, EMPTY_PARAMS);
|
|
83
104
|
trail.push(point.x, point.y);
|
|
84
105
|
}
|
|
85
106
|
return trail.toArray();
|
|
@@ -99,14 +120,14 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
99
120
|
trail.clear();
|
|
100
121
|
},
|
|
101
122
|
seek(newT, { clearTrail = false } = {}) {
|
|
102
|
-
t = (newT % curve.period + curve.period) % curve.period;
|
|
123
|
+
t = ((newT % curve.period) + curve.period) % curve.period;
|
|
103
124
|
if (clearTrail) {
|
|
104
125
|
trail.clear();
|
|
105
126
|
}
|
|
106
127
|
},
|
|
107
128
|
seekWithTrail(targetT, { wrap = false, step = curve.period / trailLength } = {}) {
|
|
108
129
|
const advance = curve.speed * step;
|
|
109
|
-
const target = (targetT % curve.period + curve.period) % curve.period;
|
|
130
|
+
const target = ((targetT % curve.period) + curve.period) % curve.period;
|
|
110
131
|
const targetTime = target / curve.speed;
|
|
111
132
|
t = target;
|
|
112
133
|
actualTime = targetTime;
|
|
@@ -115,9 +136,9 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
115
136
|
const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
|
|
116
137
|
for (let i = count - 1; i >= 0; i--) {
|
|
117
138
|
const sampleT = target - i * advance;
|
|
118
|
-
const wrappedT = sampleT
|
|
139
|
+
const wrappedT = ((sampleT % curve.period) + curve.period) % curve.period;
|
|
119
140
|
const time = targetTime - i * step;
|
|
120
|
-
const point = curve.fn(wrappedT, time,
|
|
141
|
+
const point = curve.fn(wrappedT, time, EMPTY_PARAMS);
|
|
121
142
|
trail.push(point.x, point.y);
|
|
122
143
|
}
|
|
123
144
|
},
|
|
@@ -132,13 +153,16 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
132
153
|
...frozenB,
|
|
133
154
|
fn: (sampleT, time, params) => {
|
|
134
155
|
const a = frozenA.fn(sampleT, time, params);
|
|
135
|
-
const tB =
|
|
156
|
+
const tB =
|
|
157
|
+
frozenStrategy === "normalized"
|
|
158
|
+
? (sampleT / frozenA.period) * frozenB.period
|
|
159
|
+
: sampleT;
|
|
136
160
|
const b = frozenB.fn(tB, time, params);
|
|
137
161
|
return {
|
|
138
162
|
x: a.x + (b.x - a.x) * frozenAlpha,
|
|
139
|
-
y: a.y + (b.y - a.y) * frozenAlpha
|
|
163
|
+
y: a.y + (b.y - a.y) * frozenAlpha,
|
|
140
164
|
};
|
|
141
|
-
}
|
|
165
|
+
},
|
|
142
166
|
};
|
|
143
167
|
}
|
|
144
168
|
_morphStrategy = strategy;
|
|
@@ -151,7 +175,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
151
175
|
completeMorph() {
|
|
152
176
|
if (morphCurveB !== null) {
|
|
153
177
|
if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
|
|
154
|
-
t = t / curve.period * morphCurveB.period;
|
|
178
|
+
t = (t / curve.period) * morphCurveB.period;
|
|
155
179
|
}
|
|
156
180
|
curve = morphCurveB;
|
|
157
181
|
}
|
|
@@ -163,23 +187,26 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
163
187
|
const points = new Array(steps);
|
|
164
188
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
165
189
|
for (let i = 0; i < steps; i++) {
|
|
166
|
-
const sampleT = i / (steps - 1) * curve.period;
|
|
190
|
+
const sampleT = (i / (steps - 1)) * curve.period;
|
|
167
191
|
const a = sampleSkeleton(curve, sampleT);
|
|
168
|
-
const tB =
|
|
192
|
+
const tB =
|
|
193
|
+
_morphStrategy === "normalized"
|
|
194
|
+
? (sampleT / curve.period) * morphCurveB.period
|
|
195
|
+
: sampleT;
|
|
169
196
|
const b = sampleSkeleton(morphCurveB, tB);
|
|
170
197
|
points[i] = {
|
|
171
198
|
x: a.x + (b.x - a.x) * _morphAlpha,
|
|
172
|
-
y: a.y + (b.y - a.y) * _morphAlpha
|
|
199
|
+
y: a.y + (b.y - a.y) * _morphAlpha,
|
|
173
200
|
};
|
|
174
201
|
}
|
|
175
202
|
return points;
|
|
176
203
|
}
|
|
177
204
|
for (let i = 0; i < steps; i++) {
|
|
178
|
-
const sampleT = i / (steps - 1) * curve.period;
|
|
205
|
+
const sampleT = (i / (steps - 1)) * curve.period;
|
|
179
206
|
points[i] = sampleSkeleton(curve, sampleT);
|
|
180
207
|
}
|
|
181
208
|
return points;
|
|
182
|
-
}
|
|
209
|
+
},
|
|
183
210
|
};
|
|
184
211
|
}
|
|
185
212
|
|
|
@@ -199,7 +226,7 @@ var GRADIENT = {
|
|
|
199
226
|
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
200
227
|
ice: ["#1e3a8a", "#67e8f9"],
|
|
201
228
|
fire: ["#7f1d1d", "#fbbf24"],
|
|
202
|
-
forest: ["#14532d", "#86efac"]
|
|
229
|
+
forest: ["#14532d", "#86efac"],
|
|
203
230
|
};
|
|
204
231
|
var PRESETS = {
|
|
205
232
|
bard: GRADIENT.bard,
|
|
@@ -207,16 +234,16 @@ var PRESETS = {
|
|
|
207
234
|
ocean: GRADIENT.ocean,
|
|
208
235
|
ice: GRADIENT.ice,
|
|
209
236
|
fire: GRADIENT.fire,
|
|
210
|
-
forest: GRADIENT.forest
|
|
237
|
+
forest: GRADIENT.forest,
|
|
211
238
|
};
|
|
212
239
|
function hexToRgb(hex) {
|
|
213
240
|
const n = parseInt(hex.slice(1), 16);
|
|
214
|
-
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
241
|
+
return { r: n >> 16, g: (n >> 8) & 255, b: n & 255 };
|
|
215
242
|
}
|
|
216
243
|
var lerpRgb = (a, b, t) => ({
|
|
217
244
|
r: Math.round(a.r + (b.r - a.r) * t),
|
|
218
245
|
g: Math.round(a.g + (b.g - a.g) * t),
|
|
219
|
-
b: Math.round(a.b + (b.b - a.b) * t)
|
|
246
|
+
b: Math.round(a.b + (b.b - a.b) * t),
|
|
220
247
|
});
|
|
221
248
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
222
249
|
if (palette.length === 0) return { r: 255, g: 255, b: 255 };
|
|
@@ -236,7 +263,7 @@ function resolvePalette(palette, trailStyle) {
|
|
|
236
263
|
}
|
|
237
264
|
function hexToRgbComponents(hex) {
|
|
238
265
|
const n = parseInt(hex.slice(1), 16);
|
|
239
|
-
return `${n >> 16},${n >> 8 & 255},${n & 255}`;
|
|
266
|
+
return `${n >> 16},${(n >> 8) & 255},${n & 255}`;
|
|
240
267
|
}
|
|
241
268
|
function computeTangent(trail, i) {
|
|
242
269
|
const count = trail.length;
|
|
@@ -281,7 +308,7 @@ function createRenderer(options) {
|
|
|
281
308
|
skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,
|
|
282
309
|
trailColor: options.trailColor ?? "#ffffff",
|
|
283
310
|
headColor: options.headColor ?? "#ffffff",
|
|
284
|
-
headRadius: options.headRadius ?? DEFAULT_HEAD_RADIUS
|
|
311
|
+
headRadius: options.headRadius ?? DEFAULT_HEAD_RADIUS,
|
|
285
312
|
};
|
|
286
313
|
const trailStyle = options.trailStyle ?? "default";
|
|
287
314
|
const palette = resolvePalette(options.palette, trailStyle);
|
|
@@ -314,15 +341,31 @@ function createRenderer(options) {
|
|
|
314
341
|
function computeBoundaries(pts) {
|
|
315
342
|
if (pts.length === 0) return null;
|
|
316
343
|
const first = pts[0];
|
|
317
|
-
let minX = first.x,
|
|
344
|
+
let minX = first.x,
|
|
345
|
+
maxX = first.x,
|
|
346
|
+
minY = first.y,
|
|
347
|
+
maxY = first.y;
|
|
318
348
|
for (const p of pts) {
|
|
319
|
-
if (p.x < minX)
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if (p.
|
|
349
|
+
if (p.x < minX) {
|
|
350
|
+
minX = p.x;
|
|
351
|
+
}
|
|
352
|
+
if (p.x > maxX) {
|
|
353
|
+
maxX = p.x;
|
|
354
|
+
}
|
|
355
|
+
if (p.y < minY) {
|
|
356
|
+
minY = p.y;
|
|
357
|
+
}
|
|
358
|
+
if (p.y > maxY) {
|
|
359
|
+
maxY = p.y;
|
|
360
|
+
}
|
|
323
361
|
}
|
|
324
362
|
const width = maxX - minX;
|
|
325
363
|
const height = maxY - minY;
|
|
364
|
+
if (width === 0 && height === 0) {
|
|
365
|
+
throw new Error(
|
|
366
|
+
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
|
|
367
|
+
);
|
|
368
|
+
}
|
|
326
369
|
const scaleX = logicalWidth / (width * (1 + FIT_PADDING * 2));
|
|
327
370
|
const scaleY = logicalHeight / (height * (1 + FIT_PADDING * 2));
|
|
328
371
|
const s = Math.min(scaleX, scaleY);
|
|
@@ -331,7 +374,7 @@ function createRenderer(options) {
|
|
|
331
374
|
return {
|
|
332
375
|
scale: s,
|
|
333
376
|
offsetX: (logicalWidth - boundsWidth) / 2 - minX * s,
|
|
334
|
-
offsetY: (logicalHeight - boundsHeight) / 2 - minY * s
|
|
377
|
+
offsetY: (logicalHeight - boundsHeight) / 2 - minY * s,
|
|
335
378
|
};
|
|
336
379
|
}
|
|
337
380
|
function calculateBoundaries() {
|
|
@@ -537,156 +580,199 @@ function createRenderer(options) {
|
|
|
537
580
|
return new Promise((resolve) => {
|
|
538
581
|
morphResolve = resolve;
|
|
539
582
|
});
|
|
540
|
-
}
|
|
583
|
+
},
|
|
541
584
|
};
|
|
542
585
|
}
|
|
543
586
|
|
|
544
|
-
// src/curves.ts
|
|
587
|
+
// src/curves/artemis2.ts
|
|
545
588
|
var TWO_PI2 = Math.PI * 2;
|
|
546
|
-
function
|
|
547
|
-
const a = 0.35,
|
|
548
|
-
|
|
589
|
+
function artemis2Fn(t, _time, _params) {
|
|
590
|
+
const a = 0.35,
|
|
591
|
+
b = 0.15,
|
|
592
|
+
ox = 0.175;
|
|
593
|
+
const s = Math.sin(t),
|
|
594
|
+
c = Math.cos(t);
|
|
549
595
|
const denom = 1 + s * s;
|
|
550
596
|
return {
|
|
551
|
-
x: c * (1 + a * c) / denom - ox,
|
|
552
|
-
y: s * c * (1 + b * c) / denom
|
|
597
|
+
x: (c * (1 + a * c)) / denom - ox,
|
|
598
|
+
y: (s * c * (1 + b * c)) / denom,
|
|
553
599
|
};
|
|
554
600
|
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
566
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
function astroid(t, _time, _params) {
|
|
601
|
+
var artemis2 = {
|
|
602
|
+
name: "Artemis II",
|
|
603
|
+
fn: artemis2Fn,
|
|
604
|
+
period: TWO_PI2,
|
|
605
|
+
speed: 0.7,
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
// src/curves/astroid.ts
|
|
609
|
+
var TWO_PI3 = Math.PI * 2;
|
|
610
|
+
function astroidFn(t, _time, _params) {
|
|
570
611
|
const c = Math.cos(t);
|
|
571
612
|
const s = Math.sin(t);
|
|
572
613
|
return {
|
|
573
614
|
x: c * c * c,
|
|
574
|
-
y: s * s * s
|
|
615
|
+
y: s * s * s,
|
|
575
616
|
};
|
|
576
617
|
}
|
|
577
|
-
|
|
618
|
+
var astroid = {
|
|
619
|
+
name: "Astroid",
|
|
620
|
+
fn: astroidFn,
|
|
621
|
+
period: TWO_PI3,
|
|
622
|
+
speed: 1.1,
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
// src/curves/deltoid.ts
|
|
626
|
+
var TWO_PI4 = Math.PI * 2;
|
|
627
|
+
function deltoidFn(t, _time, _params) {
|
|
578
628
|
return {
|
|
579
629
|
x: 2 * Math.cos(t) + Math.cos(2 * t),
|
|
580
|
-
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
630
|
+
y: 2 * Math.sin(t) - Math.sin(2 * t),
|
|
581
631
|
};
|
|
582
632
|
}
|
|
583
|
-
|
|
584
|
-
|
|
633
|
+
var deltoid = {
|
|
634
|
+
name: "Deltoid",
|
|
635
|
+
fn: deltoidFn,
|
|
636
|
+
period: TWO_PI4,
|
|
637
|
+
speed: 0.9,
|
|
638
|
+
};
|
|
639
|
+
|
|
640
|
+
// src/curves/epicycloid3.ts
|
|
641
|
+
var TWO_PI5 = Math.PI * 2;
|
|
642
|
+
function epicycloid3Fn(t, _time, _params) {
|
|
585
643
|
return {
|
|
586
|
-
x:
|
|
587
|
-
y:
|
|
644
|
+
x: 4 * Math.cos(t) - Math.cos(4 * t),
|
|
645
|
+
y: 4 * Math.sin(t) - Math.sin(4 * t),
|
|
588
646
|
};
|
|
589
647
|
}
|
|
590
|
-
|
|
591
|
-
|
|
648
|
+
var epicycloid3 = {
|
|
649
|
+
name: "Epicycloid (n=3)",
|
|
650
|
+
fn: epicycloid3Fn,
|
|
651
|
+
period: TWO_PI5,
|
|
652
|
+
speed: 0.75,
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
// src/curves/epitrochoid7.ts
|
|
656
|
+
var TWO_PI6 = Math.PI * 2;
|
|
657
|
+
function epitrochoid7Fn(t, _time, _params) {
|
|
658
|
+
const d = 1 + 0.55 * Math.sin(t * 0.5);
|
|
592
659
|
return {
|
|
593
|
-
x:
|
|
594
|
-
y:
|
|
660
|
+
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
661
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
function epitrochoid7SkeletonFn(t) {
|
|
665
|
+
const d = 1.275;
|
|
666
|
+
return {
|
|
667
|
+
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
668
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t),
|
|
595
669
|
};
|
|
596
670
|
}
|
|
597
|
-
|
|
671
|
+
var epitrochoid7 = {
|
|
672
|
+
name: "Epitrochoid",
|
|
673
|
+
fn: epitrochoid7Fn,
|
|
674
|
+
period: TWO_PI6,
|
|
675
|
+
speed: 1.4,
|
|
676
|
+
skeletonFn: epitrochoid7SkeletonFn,
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
// src/curves/lissajous32.ts
|
|
680
|
+
var TWO_PI7 = Math.PI * 2;
|
|
681
|
+
function lissajous32Fn(t, time, _params) {
|
|
598
682
|
const phi = time * 0.45;
|
|
599
683
|
return {
|
|
600
684
|
x: Math.sin(3 * t + phi),
|
|
601
|
-
y: Math.sin(2 * t)
|
|
685
|
+
y: Math.sin(2 * t),
|
|
602
686
|
};
|
|
603
687
|
}
|
|
604
|
-
|
|
688
|
+
var lissajous32 = {
|
|
689
|
+
name: "Lissajous 3:2",
|
|
690
|
+
fn: lissajous32Fn,
|
|
691
|
+
period: TWO_PI7,
|
|
692
|
+
speed: 2,
|
|
693
|
+
skeleton: "live",
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
// src/curves/lissajous43.ts
|
|
697
|
+
var TWO_PI8 = Math.PI * 2;
|
|
698
|
+
function lissajous43Fn(t, time, _params) {
|
|
605
699
|
const phi = time * 0.38;
|
|
606
700
|
return {
|
|
607
701
|
x: Math.sin(4 * t + phi),
|
|
608
|
-
y: Math.sin(3 * t)
|
|
702
|
+
y: Math.sin(3 * t),
|
|
609
703
|
};
|
|
610
704
|
}
|
|
611
|
-
|
|
705
|
+
var lissajous43 = {
|
|
706
|
+
name: "Lissajous 4:3",
|
|
707
|
+
fn: lissajous43Fn,
|
|
708
|
+
period: TWO_PI8,
|
|
709
|
+
speed: 1.8,
|
|
710
|
+
skeleton: "live",
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
// src/curves/lame.ts
|
|
714
|
+
var TWO_PI9 = Math.PI * 2;
|
|
715
|
+
function lameFn(t, time, _params) {
|
|
716
|
+
const p = 1.75 + 1.25 * Math.sin(time * 0.48);
|
|
717
|
+
const c = Math.cos(t),
|
|
718
|
+
s = Math.sin(t);
|
|
612
719
|
return {
|
|
613
|
-
x:
|
|
614
|
-
y:
|
|
720
|
+
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
721
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p),
|
|
615
722
|
};
|
|
616
723
|
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
724
|
+
var lame = {
|
|
725
|
+
name: "Lam\xE9 Curve",
|
|
726
|
+
fn: lameFn,
|
|
727
|
+
period: TWO_PI9,
|
|
728
|
+
speed: 1,
|
|
729
|
+
skeleton: "live",
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
// src/curves/rose3.ts
|
|
733
|
+
var TWO_PI10 = Math.PI * 2;
|
|
734
|
+
function rose3Fn(t, _time, _params) {
|
|
735
|
+
const r = Math.cos(3 * t);
|
|
620
736
|
return {
|
|
621
|
-
x:
|
|
622
|
-
y:
|
|
737
|
+
x: r * Math.cos(t),
|
|
738
|
+
y: r * Math.sin(t),
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
var rose3 = {
|
|
742
|
+
name: "Rose (n=3)",
|
|
743
|
+
fn: rose3Fn,
|
|
744
|
+
period: TWO_PI10,
|
|
745
|
+
speed: 1.15,
|
|
746
|
+
};
|
|
747
|
+
|
|
748
|
+
// src/curves/rose5.ts
|
|
749
|
+
var TWO_PI11 = Math.PI * 2;
|
|
750
|
+
function rose5Fn(t, _time, _params) {
|
|
751
|
+
const r = Math.cos(5 * t);
|
|
752
|
+
return {
|
|
753
|
+
x: r * Math.cos(t),
|
|
754
|
+
y: r * Math.sin(t),
|
|
623
755
|
};
|
|
624
756
|
}
|
|
757
|
+
var rose5 = {
|
|
758
|
+
name: "Rose (n=5)",
|
|
759
|
+
fn: rose5Fn,
|
|
760
|
+
period: TWO_PI11,
|
|
761
|
+
speed: 1,
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
// src/curves/index.ts
|
|
625
765
|
var curves = {
|
|
626
|
-
artemis2
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
speed: 1.4,
|
|
637
|
-
skeletonFn: epitrochoid7Skeleton
|
|
638
|
-
},
|
|
639
|
-
astroid: {
|
|
640
|
-
name: "Astroid",
|
|
641
|
-
fn: astroid,
|
|
642
|
-
period: TWO_PI2,
|
|
643
|
-
speed: 1.1
|
|
644
|
-
},
|
|
645
|
-
deltoid: {
|
|
646
|
-
name: "Deltoid",
|
|
647
|
-
fn: deltoid,
|
|
648
|
-
period: TWO_PI2,
|
|
649
|
-
speed: 0.9
|
|
650
|
-
},
|
|
651
|
-
rose5: {
|
|
652
|
-
name: "Rose (n=5)",
|
|
653
|
-
fn: rose5,
|
|
654
|
-
period: TWO_PI2,
|
|
655
|
-
speed: 1
|
|
656
|
-
},
|
|
657
|
-
rose3: {
|
|
658
|
-
name: "Rose (n=3)",
|
|
659
|
-
fn: rose3,
|
|
660
|
-
period: TWO_PI2,
|
|
661
|
-
speed: 1.15
|
|
662
|
-
},
|
|
663
|
-
lissajous32: {
|
|
664
|
-
name: "Lissajous 3:2",
|
|
665
|
-
fn: lissajous32,
|
|
666
|
-
period: TWO_PI2,
|
|
667
|
-
speed: 2,
|
|
668
|
-
skeleton: "live"
|
|
669
|
-
},
|
|
670
|
-
lissajous43: {
|
|
671
|
-
name: "Lissajous 4:3",
|
|
672
|
-
fn: lissajous43,
|
|
673
|
-
period: TWO_PI2,
|
|
674
|
-
speed: 1.8,
|
|
675
|
-
skeleton: "live"
|
|
676
|
-
},
|
|
677
|
-
epicycloid3: {
|
|
678
|
-
name: "Epicycloid (n=3)",
|
|
679
|
-
fn: epicycloid3,
|
|
680
|
-
period: TWO_PI2,
|
|
681
|
-
speed: 0.75
|
|
682
|
-
},
|
|
683
|
-
lame: {
|
|
684
|
-
name: "Lam\xE9 Curve",
|
|
685
|
-
fn: lame,
|
|
686
|
-
period: TWO_PI2,
|
|
687
|
-
speed: 1,
|
|
688
|
-
skeleton: "live"
|
|
689
|
-
}
|
|
766
|
+
artemis2,
|
|
767
|
+
epitrochoid7,
|
|
768
|
+
astroid,
|
|
769
|
+
deltoid,
|
|
770
|
+
rose5,
|
|
771
|
+
rose3,
|
|
772
|
+
lissajous32,
|
|
773
|
+
lissajous43,
|
|
774
|
+
epicycloid3,
|
|
775
|
+
lame,
|
|
690
776
|
};
|
|
691
777
|
|
|
692
778
|
// src/index.ts
|
|
@@ -697,31 +783,46 @@ function createSarmal(canvas, curveDef, options) {
|
|
|
697
783
|
}
|
|
698
784
|
|
|
699
785
|
// src/auto-init.ts
|
|
786
|
+
function parsePalette(value) {
|
|
787
|
+
try {
|
|
788
|
+
const parsed = JSON.parse(value);
|
|
789
|
+
if (Array.isArray(parsed)) {
|
|
790
|
+
return parsed;
|
|
791
|
+
}
|
|
792
|
+
} catch {}
|
|
793
|
+
return value;
|
|
794
|
+
}
|
|
700
795
|
function init() {
|
|
701
796
|
const canvases = document.querySelectorAll("canvas[data-sarmal]");
|
|
702
797
|
canvases.forEach((canvas) => {
|
|
703
798
|
const curveName = canvas.getAttribute("data-sarmal");
|
|
704
799
|
if (curveName == null) {
|
|
705
|
-
return console.warn("[sarmal] curveName
|
|
800
|
+
return console.warn("[sarmal] curveName is required");
|
|
706
801
|
}
|
|
707
802
|
const curveDef = curves[curveName];
|
|
708
803
|
if (!curveDef) {
|
|
709
804
|
return console.error(`[sarmal] "${curveName}" is not a valid curve name`);
|
|
710
805
|
}
|
|
711
806
|
const sarmal = createSarmal(canvas, curveDef, {
|
|
712
|
-
...canvas.dataset.trailColor && { trailColor: canvas.dataset.trailColor },
|
|
713
|
-
...canvas.dataset.skeletonColor && { skeletonColor: canvas.dataset.skeletonColor },
|
|
714
|
-
...canvas.dataset.headColor && { headColor: canvas.dataset.headColor },
|
|
715
|
-
...canvas.dataset.headRadius && { headRadius: parseFloat(canvas.dataset.headRadius) },
|
|
716
|
-
...canvas.dataset.trailLength && { trailLength: parseInt(canvas.dataset.trailLength, 10) }
|
|
807
|
+
...(canvas.dataset.trailColor && { trailColor: canvas.dataset.trailColor }),
|
|
808
|
+
...(canvas.dataset.skeletonColor && { skeletonColor: canvas.dataset.skeletonColor }),
|
|
809
|
+
...(canvas.dataset.headColor && { headColor: canvas.dataset.headColor }),
|
|
810
|
+
...(canvas.dataset.headRadius && { headRadius: parseFloat(canvas.dataset.headRadius) }),
|
|
811
|
+
...(canvas.dataset.trailLength && { trailLength: parseInt(canvas.dataset.trailLength, 10) }),
|
|
812
|
+
...(canvas.dataset.trailStyle && {
|
|
813
|
+
trailStyle: canvas.dataset.trailStyle,
|
|
814
|
+
}),
|
|
815
|
+
...(canvas.dataset.palette && { palette: parsePalette(canvas.dataset.palette) }),
|
|
717
816
|
});
|
|
718
817
|
sarmal.start();
|
|
719
818
|
});
|
|
720
819
|
}
|
|
721
820
|
if (document.readyState === "loading") {
|
|
722
|
-
document.addEventListener("DOMContentLoaded",
|
|
821
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
822
|
+
requestAnimationFrame(init);
|
|
823
|
+
});
|
|
723
824
|
} else {
|
|
724
|
-
init
|
|
825
|
+
requestAnimationFrame(init);
|
|
725
826
|
}
|
|
726
827
|
//# sourceMappingURL=auto-init.js.map
|
|
727
|
-
//# sourceMappingURL=auto-init.js.map
|
|
828
|
+
//# sourceMappingURL=auto-init.js.map
|