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