@sarmal/core 0.9.7 → 0.10.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 +171 -166
- 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 +170 -165
- package/dist/auto-init.js.map +1 -1
- package/dist/curves/artemis2.cjs +7 -10
- package/dist/curves/artemis2.d.cts +1 -1
- package/dist/curves/artemis2.d.ts +1 -1
- package/dist/curves/artemis2.js +6 -9
- 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 +28 -32
- package/dist/curves/index.d.cts +11 -11
- package/dist/curves/index.d.ts +11 -11
- package/dist/curves/index.js +28 -44
- package/dist/curves/lame.cjs +5 -6
- package/dist/curves/lame.d.cts +1 -1
- package/dist/curves/lame.d.ts +1 -1
- package/dist/curves/lame.js +4 -5
- 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 +211 -283
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -64
- package/dist/index.d.ts +31 -64
- package/dist/index.js +211 -300
- package/dist/index.js.map +1 -1
- package/dist/types-DcyISvnH.d.cts +230 -0
- package/dist/types-DcyISvnH.d.ts +230 -0
- package/package.json +2 -1
- package/dist/types-cR2xOewv.d.cts +0 -234
- package/dist/types-cR2xOewv.d.ts +0 -234
package/dist/index.js
CHANGED
|
@@ -61,13 +61,13 @@ function resolveCurve(curveDef) {
|
|
|
61
61
|
period,
|
|
62
62
|
speed,
|
|
63
63
|
skeleton: curveDef.skeleton,
|
|
64
|
-
skeletonFn: curveDef.skeletonFn
|
|
64
|
+
skeletonFn: curveDef.skeletonFn
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
67
|
function createEngine(curveDef, trailLength = 120) {
|
|
68
68
|
if (!Number.isFinite(trailLength) || trailLength <= 0) {
|
|
69
69
|
throw new RangeError(
|
|
70
|
-
`[sarmal] trailLength must be a positive finite number, got ${trailLength}
|
|
70
|
+
`[sarmal] trailLength must be a positive finite number, got ${trailLength}`
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
let curve = resolveCurve(curveDef);
|
|
@@ -96,7 +96,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
96
96
|
actualTime += deltaTime;
|
|
97
97
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
98
98
|
const a = curve.fn(t, actualTime, EMPTY_PARAMS);
|
|
99
|
-
const tB = _morphStrategy === "normalized" ?
|
|
99
|
+
const tB = _morphStrategy === "normalized" ? t / curve.period * morphCurveB.period : t;
|
|
100
100
|
const b = morphCurveB.fn(tB, actualTime, EMPTY_PARAMS);
|
|
101
101
|
trail.push(a.x + (b.x - a.x) * _morphAlpha, a.y + (b.y - a.y) * _morphAlpha);
|
|
102
102
|
} else {
|
|
@@ -119,15 +119,15 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
119
119
|
actualTime = 0;
|
|
120
120
|
trail.clear();
|
|
121
121
|
},
|
|
122
|
-
|
|
123
|
-
t = (
|
|
122
|
+
jump(newT, { clearTrail = false } = {}) {
|
|
123
|
+
t = (newT % curve.period + curve.period) % curve.period;
|
|
124
124
|
if (clearTrail) {
|
|
125
125
|
trail.clear();
|
|
126
126
|
}
|
|
127
127
|
},
|
|
128
|
-
|
|
128
|
+
seek(targetT, { wrap = false, step = curve.period / trailLength } = {}) {
|
|
129
129
|
const advance = curve.speed * step;
|
|
130
|
-
const target = (
|
|
130
|
+
const target = (targetT % curve.period + curve.period) % curve.period;
|
|
131
131
|
const targetTime = target / curve.speed;
|
|
132
132
|
t = target;
|
|
133
133
|
actualTime = targetTime;
|
|
@@ -136,7 +136,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
136
136
|
const count = wrap ? trailLength : Math.min(trailLength, pointsFromStart);
|
|
137
137
|
for (let i = count - 1; i >= 0; i--) {
|
|
138
138
|
const sampleT = target - i * advance;
|
|
139
|
-
const wrappedT = (
|
|
139
|
+
const wrappedT = (sampleT % curve.period + curve.period) % curve.period;
|
|
140
140
|
const time = targetTime - i * step;
|
|
141
141
|
const point = curve.fn(wrappedT, time, EMPTY_PARAMS);
|
|
142
142
|
trail.push(point.x, point.y);
|
|
@@ -153,16 +153,13 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
153
153
|
...frozenB,
|
|
154
154
|
fn: (sampleT, time, params) => {
|
|
155
155
|
const a = frozenA.fn(sampleT, time, params);
|
|
156
|
-
const tB =
|
|
157
|
-
frozenStrategy === "normalized"
|
|
158
|
-
? (sampleT / frozenA.period) * frozenB.period
|
|
159
|
-
: sampleT;
|
|
156
|
+
const tB = frozenStrategy === "normalized" ? sampleT / frozenA.period * frozenB.period : sampleT;
|
|
160
157
|
const b = frozenB.fn(tB, time, params);
|
|
161
158
|
return {
|
|
162
159
|
x: a.x + (b.x - a.x) * frozenAlpha,
|
|
163
|
-
y: a.y + (b.y - a.y) * frozenAlpha
|
|
160
|
+
y: a.y + (b.y - a.y) * frozenAlpha
|
|
164
161
|
};
|
|
165
|
-
}
|
|
162
|
+
}
|
|
166
163
|
};
|
|
167
164
|
}
|
|
168
165
|
_morphStrategy = strategy;
|
|
@@ -175,7 +172,7 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
175
172
|
completeMorph() {
|
|
176
173
|
if (morphCurveB !== null) {
|
|
177
174
|
if (_morphStrategy === "normalized" && curve.period !== morphCurveB.period) {
|
|
178
|
-
t =
|
|
175
|
+
t = t / curve.period * morphCurveB.period;
|
|
179
176
|
}
|
|
180
177
|
curve = morphCurveB;
|
|
181
178
|
}
|
|
@@ -187,46 +184,132 @@ function createEngine(curveDef, trailLength = 120) {
|
|
|
187
184
|
const points = new Array(steps);
|
|
188
185
|
if (morphCurveB !== null && _morphAlpha !== null) {
|
|
189
186
|
for (let i = 0; i < steps; i++) {
|
|
190
|
-
const sampleT =
|
|
187
|
+
const sampleT = i / (steps - 1) * curve.period;
|
|
191
188
|
const a = sampleSkeleton(curve, sampleT);
|
|
192
|
-
const tB =
|
|
193
|
-
_morphStrategy === "normalized"
|
|
194
|
-
? (sampleT / curve.period) * morphCurveB.period
|
|
195
|
-
: sampleT;
|
|
189
|
+
const tB = _morphStrategy === "normalized" ? sampleT / curve.period * morphCurveB.period : sampleT;
|
|
196
190
|
const b = sampleSkeleton(morphCurveB, tB);
|
|
197
191
|
points[i] = {
|
|
198
192
|
x: a.x + (b.x - a.x) * _morphAlpha,
|
|
199
|
-
y: a.y + (b.y - a.y) * _morphAlpha
|
|
193
|
+
y: a.y + (b.y - a.y) * _morphAlpha
|
|
200
194
|
};
|
|
201
195
|
}
|
|
202
196
|
return points;
|
|
203
197
|
}
|
|
204
198
|
for (let i = 0; i < steps; i++) {
|
|
205
|
-
const sampleT =
|
|
199
|
+
const sampleT = i / (steps - 1) * curve.period;
|
|
206
200
|
points[i] = sampleSkeleton(curve, sampleT);
|
|
207
201
|
}
|
|
208
202
|
return points;
|
|
209
|
-
}
|
|
203
|
+
}
|
|
210
204
|
};
|
|
211
205
|
}
|
|
212
206
|
|
|
213
|
-
// src/renderer.ts
|
|
207
|
+
// src/renderer-shared.ts
|
|
214
208
|
var DEFAULT_MORPH_DURATION_MS = 300;
|
|
215
|
-
var DEFAULT_HEAD_RADIUS = 4;
|
|
216
|
-
var DEFAULT_SKELETON_COLOR = "#ffffff";
|
|
217
209
|
var DEFAULT_SKELETON_OPACITY = 0.15;
|
|
218
210
|
var FIT_PADDING = 0.1;
|
|
219
211
|
var TRAIL_FADE_CURVE = 1.5;
|
|
220
212
|
var TRAIL_MAX_OPACITY = 0.88;
|
|
221
213
|
var TRAIL_MIN_WIDTH = 0.5;
|
|
222
214
|
var TRAIL_MAX_WIDTH = 2.5;
|
|
215
|
+
function computeTangent(trail, i) {
|
|
216
|
+
const count = trail.length;
|
|
217
|
+
if (count < 2) {
|
|
218
|
+
return { x: 1, y: 0 };
|
|
219
|
+
}
|
|
220
|
+
if (i === 0) {
|
|
221
|
+
const dx2 = trail[1].x - trail[0].x;
|
|
222
|
+
const dy2 = trail[1].y - trail[0].y;
|
|
223
|
+
const len2 = Math.sqrt(dx2 * dx2 + dy2 * dy2) || 1;
|
|
224
|
+
return { x: dx2 / len2, y: dy2 / len2 };
|
|
225
|
+
}
|
|
226
|
+
if (i === count - 1) {
|
|
227
|
+
const dx2 = trail[count - 1].x - trail[count - 2].x;
|
|
228
|
+
const dy2 = trail[count - 1].y - trail[count - 2].y;
|
|
229
|
+
const len2 = Math.sqrt(dx2 * dx2 + dy2 * dy2) || 1;
|
|
230
|
+
return { x: dx2 / len2, y: dy2 / len2 };
|
|
231
|
+
}
|
|
232
|
+
const dx = trail[i + 1].x - trail[i - 1].x;
|
|
233
|
+
const dy = trail[i + 1].y - trail[i - 1].y;
|
|
234
|
+
const len = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
235
|
+
return { x: dx / len, y: dy / len };
|
|
236
|
+
}
|
|
237
|
+
function computeNormal(trail, i) {
|
|
238
|
+
const tangent = computeTangent(trail, i);
|
|
239
|
+
return { x: -tangent.y, y: tangent.x };
|
|
240
|
+
}
|
|
241
|
+
function computeTrailQuad(trail, i, trailCount, toX, toY) {
|
|
242
|
+
const progress = i / (trailCount - 1);
|
|
243
|
+
const nextProgress = (i + 1) / (trailCount - 1);
|
|
244
|
+
const opacity = Math.pow(progress, TRAIL_FADE_CURVE) * TRAIL_MAX_OPACITY;
|
|
245
|
+
const w0 = (TRAIL_MIN_WIDTH + progress * (TRAIL_MAX_WIDTH - TRAIL_MIN_WIDTH)) / 2;
|
|
246
|
+
const w1 = (TRAIL_MIN_WIDTH + nextProgress * (TRAIL_MAX_WIDTH - TRAIL_MIN_WIDTH)) / 2;
|
|
247
|
+
const curr = trail[i];
|
|
248
|
+
const next = trail[i + 1];
|
|
249
|
+
const n0 = computeNormal(trail, i);
|
|
250
|
+
const n1 = computeNormal(trail, i + 1);
|
|
251
|
+
const cx = toX(curr);
|
|
252
|
+
const cy = toY(curr);
|
|
253
|
+
const nx = toX(next);
|
|
254
|
+
const ny = toY(next);
|
|
255
|
+
return {
|
|
256
|
+
l0x: cx + n0.x * w0,
|
|
257
|
+
l0y: cy + n0.y * w0,
|
|
258
|
+
r0x: cx - n0.x * w0,
|
|
259
|
+
r0y: cy - n0.y * w0,
|
|
260
|
+
l1x: nx + n1.x * w1,
|
|
261
|
+
l1y: ny + n1.y * w1,
|
|
262
|
+
r1x: nx - n1.x * w1,
|
|
263
|
+
r1y: ny - n1.y * w1,
|
|
264
|
+
opacity,
|
|
265
|
+
progress
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function computeBoundaries(pts, logicalWidth, logicalHeight) {
|
|
269
|
+
if (pts.length === 0) return null;
|
|
270
|
+
const first = pts[0];
|
|
271
|
+
let minX = first.x, maxX = first.x, minY = first.y, maxY = first.y;
|
|
272
|
+
for (const p of pts) {
|
|
273
|
+
if (p.x < minX) {
|
|
274
|
+
minX = p.x;
|
|
275
|
+
}
|
|
276
|
+
if (p.x > maxX) {
|
|
277
|
+
maxX = p.x;
|
|
278
|
+
}
|
|
279
|
+
if (p.y < minY) {
|
|
280
|
+
minY = p.y;
|
|
281
|
+
}
|
|
282
|
+
if (p.y > maxY) {
|
|
283
|
+
maxY = p.y;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const w = maxX - minX;
|
|
287
|
+
const h = maxY - minY;
|
|
288
|
+
if (w === 0 && h === 0) {
|
|
289
|
+
throw new Error(
|
|
290
|
+
"[sarmal] Degenerate curve: all skeleton points are identical. Check that your curve fn returns distinct points for different values of t."
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
const scaleX = logicalWidth / (w * (1 + FIT_PADDING * 2));
|
|
294
|
+
const scaleY = logicalHeight / (h * (1 + FIT_PADDING * 2));
|
|
295
|
+
const scale = Math.min(scaleX, scaleY);
|
|
296
|
+
return {
|
|
297
|
+
scale,
|
|
298
|
+
offsetX: (logicalWidth - w * scale) / 2 - minX * scale,
|
|
299
|
+
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// src/renderer.ts
|
|
304
|
+
var DEFAULT_HEAD_RADIUS = 4;
|
|
305
|
+
var DEFAULT_SKELETON_COLOR = "#ffffff";
|
|
223
306
|
var GRADIENT = {
|
|
224
307
|
bard: ["#a855f7", "#3b82f6", "#14b8a6", "#ec4899"],
|
|
225
308
|
sunset: ["#f97316", "#dc2626", "#9333ea", "#f472b6"],
|
|
226
309
|
ocean: ["#1e3a8a", "#06b6d4", "#22d3ee", "#e0f2fe"],
|
|
227
310
|
ice: ["#1e3a8a", "#67e8f9"],
|
|
228
311
|
fire: ["#7f1d1d", "#fbbf24"],
|
|
229
|
-
forest: ["#14532d", "#86efac"]
|
|
312
|
+
forest: ["#14532d", "#86efac"]
|
|
230
313
|
};
|
|
231
314
|
var PRESETS = {
|
|
232
315
|
bard: GRADIENT.bard,
|
|
@@ -234,16 +317,16 @@ var PRESETS = {
|
|
|
234
317
|
ocean: GRADIENT.ocean,
|
|
235
318
|
ice: GRADIENT.ice,
|
|
236
319
|
fire: GRADIENT.fire,
|
|
237
|
-
forest: GRADIENT.forest
|
|
320
|
+
forest: GRADIENT.forest
|
|
238
321
|
};
|
|
239
322
|
function hexToRgb(hex) {
|
|
240
323
|
const n = parseInt(hex.slice(1), 16);
|
|
241
|
-
return { r: n >> 16, g:
|
|
324
|
+
return { r: n >> 16, g: n >> 8 & 255, b: n & 255 };
|
|
242
325
|
}
|
|
243
326
|
var lerpRgb = (a, b, t) => ({
|
|
244
327
|
r: Math.round(a.r + (b.r - a.r) * t),
|
|
245
328
|
g: Math.round(a.g + (b.g - a.g) * t),
|
|
246
|
-
b: Math.round(a.b + (b.b - a.b) * t)
|
|
329
|
+
b: Math.round(a.b + (b.b - a.b) * t)
|
|
247
330
|
});
|
|
248
331
|
function getPaletteColor(palette, position, timeOffset = 0) {
|
|
249
332
|
if (palette.length === 0) return { r: 255, g: 255, b: 255 };
|
|
@@ -263,33 +346,7 @@ function resolvePalette(palette, trailStyle) {
|
|
|
263
346
|
}
|
|
264
347
|
function hexToRgbComponents(hex) {
|
|
265
348
|
const n = parseInt(hex.slice(1), 16);
|
|
266
|
-
return `${n >> 16},${
|
|
267
|
-
}
|
|
268
|
-
function computeTangent(trail, i) {
|
|
269
|
-
const count = trail.length;
|
|
270
|
-
if (count < 2) {
|
|
271
|
-
return { x: 1, y: 0 };
|
|
272
|
-
}
|
|
273
|
-
if (i === 0) {
|
|
274
|
-
const dx2 = trail[1].x - trail[0].x;
|
|
275
|
-
const dy2 = trail[1].y - trail[0].y;
|
|
276
|
-
const len2 = Math.sqrt(dx2 * dx2 + dy2 * dy2) || 1;
|
|
277
|
-
return { x: dx2 / len2, y: dy2 / len2 };
|
|
278
|
-
}
|
|
279
|
-
if (i === count - 1) {
|
|
280
|
-
const dx2 = trail[count - 1].x - trail[count - 2].x;
|
|
281
|
-
const dy2 = trail[count - 1].y - trail[count - 2].y;
|
|
282
|
-
const len2 = Math.sqrt(dx2 * dx2 + dy2 * dy2) || 1;
|
|
283
|
-
return { x: dx2 / len2, y: dy2 / len2 };
|
|
284
|
-
}
|
|
285
|
-
const dx = trail[i + 1].x - trail[i - 1].x;
|
|
286
|
-
const dy = trail[i + 1].y - trail[i - 1].y;
|
|
287
|
-
const len = Math.sqrt(dx * dx + dy * dy) || 1;
|
|
288
|
-
return { x: dx / len, y: dy / len };
|
|
289
|
-
}
|
|
290
|
-
function computeNormal(trail, i) {
|
|
291
|
-
const tangent = computeTangent(trail, i);
|
|
292
|
-
return { x: -tangent.y, y: tangent.x };
|
|
349
|
+
return `${n >> 16},${n >> 8 & 255},${n & 255}`;
|
|
293
350
|
}
|
|
294
351
|
function applyDprSizing(target, logicalWidth, logicalHeight, dpr) {
|
|
295
352
|
target.style.width = `${logicalWidth}px`;
|
|
@@ -308,7 +365,7 @@ function createRenderer(options) {
|
|
|
308
365
|
skeletonColor: options.skeletonColor ?? DEFAULT_SKELETON_COLOR,
|
|
309
366
|
trailColor: options.trailColor ?? "#ffffff",
|
|
310
367
|
headColor: options.headColor ?? "#ffffff",
|
|
311
|
-
headRadius: options.headRadius ?? DEFAULT_HEAD_RADIUS
|
|
368
|
+
headRadius: options.headRadius ?? DEFAULT_HEAD_RADIUS
|
|
312
369
|
};
|
|
313
370
|
const trailStyle = options.trailStyle ?? "default";
|
|
314
371
|
const palette = resolvePalette(options.palette, trailStyle);
|
|
@@ -338,47 +395,8 @@ function createRenderer(options) {
|
|
|
338
395
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
339
396
|
let morphAlpha = 0;
|
|
340
397
|
let gradientAnimTime = 0;
|
|
341
|
-
function computeBoundaries(pts) {
|
|
342
|
-
if (pts.length === 0) return null;
|
|
343
|
-
const first = pts[0];
|
|
344
|
-
let minX = first.x,
|
|
345
|
-
maxX = first.x,
|
|
346
|
-
minY = first.y,
|
|
347
|
-
maxY = first.y;
|
|
348
|
-
for (const p of pts) {
|
|
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
|
-
}
|
|
361
|
-
}
|
|
362
|
-
const width = maxX - minX;
|
|
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
|
-
}
|
|
369
|
-
const scaleX = logicalWidth / (width * (1 + FIT_PADDING * 2));
|
|
370
|
-
const scaleY = logicalHeight / (height * (1 + FIT_PADDING * 2));
|
|
371
|
-
const s = Math.min(scaleX, scaleY);
|
|
372
|
-
const boundsWidth = width * s;
|
|
373
|
-
const boundsHeight = height * s;
|
|
374
|
-
return {
|
|
375
|
-
scale: s,
|
|
376
|
-
offsetX: (logicalWidth - boundsWidth) / 2 - minX * s,
|
|
377
|
-
offsetY: (logicalHeight - boundsHeight) / 2 - minY * s,
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
398
|
function calculateBoundaries() {
|
|
381
|
-
const b = computeBoundaries(skeleton);
|
|
399
|
+
const b = computeBoundaries(skeleton, logicalWidth, logicalHeight);
|
|
382
400
|
if (b) {
|
|
383
401
|
scale = b.scale;
|
|
384
402
|
offsetX = b.offsetX;
|
|
@@ -442,32 +460,22 @@ function createRenderer(options) {
|
|
|
442
460
|
if (trailCount < 2) {
|
|
443
461
|
return;
|
|
444
462
|
}
|
|
463
|
+
const toX = (p) => p.x * scale + offsetX;
|
|
464
|
+
const toY = (p) => p.y * scale + offsetY;
|
|
445
465
|
for (let i = 0; i < trailCount - 1; i++) {
|
|
446
|
-
const
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
const n0 = computeNormal(trail, i);
|
|
454
|
-
const n1 = computeNormal(trail, i + 1);
|
|
455
|
-
const halfW0 = width / 2;
|
|
456
|
-
const halfW1 = nextWidth / 2;
|
|
457
|
-
const l0x = curr.x * scale + offsetX + n0.x * halfW0;
|
|
458
|
-
const l0y = curr.y * scale + offsetY + n0.y * halfW0;
|
|
459
|
-
const r0x = curr.x * scale + offsetX - n0.x * halfW0;
|
|
460
|
-
const r0y = curr.y * scale + offsetY - n0.y * halfW0;
|
|
461
|
-
const l1x = next.x * scale + offsetX + n1.x * halfW1;
|
|
462
|
-
const l1y = next.y * scale + offsetY + n1.y * halfW1;
|
|
463
|
-
const r1x = next.x * scale + offsetX - n1.x * halfW1;
|
|
464
|
-
const r1y = next.y * scale + offsetY - n1.y * halfW1;
|
|
466
|
+
const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity, progress } = computeTrailQuad(
|
|
467
|
+
trail,
|
|
468
|
+
i,
|
|
469
|
+
trailCount,
|
|
470
|
+
toX,
|
|
471
|
+
toY
|
|
472
|
+
);
|
|
465
473
|
if (trailStyle === "default") {
|
|
466
|
-
ctx.fillStyle = `rgba(${trailRgb},${
|
|
474
|
+
ctx.fillStyle = `rgba(${trailRgb},${opacity})`;
|
|
467
475
|
} else {
|
|
468
476
|
const timeOffset = trailStyle === "gradient-animated" ? gradientAnimTime * 5e-4 : 0;
|
|
469
477
|
const color = getPaletteColor(palette, progress, timeOffset);
|
|
470
|
-
ctx.fillStyle = `rgba(${color.r},${color.g},${color.b},${
|
|
478
|
+
ctx.fillStyle = `rgba(${color.r},${color.g},${color.b},${opacity})`;
|
|
471
479
|
}
|
|
472
480
|
ctx.beginPath();
|
|
473
481
|
ctx.moveTo(l0x, l0y);
|
|
@@ -500,7 +508,7 @@ function createRenderer(options) {
|
|
|
500
508
|
morphAlpha = Math.min(1, morphAlpha + deltaTime / (morphDurationMs / 1e3));
|
|
501
509
|
engine.setMorphAlpha(morphAlpha);
|
|
502
510
|
const interpolatedSkeleton = engine.getSarmalSkeleton();
|
|
503
|
-
const bounds = computeBoundaries(interpolatedSkeleton);
|
|
511
|
+
const bounds = computeBoundaries(interpolatedSkeleton, logicalWidth, logicalHeight);
|
|
504
512
|
if (bounds) {
|
|
505
513
|
scale = bounds.scale;
|
|
506
514
|
offsetX = bounds.offsetX;
|
|
@@ -561,12 +569,12 @@ function createRenderer(options) {
|
|
|
561
569
|
animationId = null;
|
|
562
570
|
}
|
|
563
571
|
},
|
|
572
|
+
jump(t, options2) {
|
|
573
|
+
engine.jump(t, options2);
|
|
574
|
+
},
|
|
564
575
|
seek(t, options2) {
|
|
565
576
|
engine.seek(t, options2);
|
|
566
577
|
},
|
|
567
|
-
seekWithTrail(t) {
|
|
568
|
-
engine.seekWithTrail(t);
|
|
569
|
-
},
|
|
570
578
|
morphTo(target, options2) {
|
|
571
579
|
if (morphResolve !== null) {
|
|
572
580
|
engine.completeMorph();
|
|
@@ -580,20 +588,33 @@ function createRenderer(options) {
|
|
|
580
588
|
return new Promise((resolve) => {
|
|
581
589
|
morphResolve = resolve;
|
|
582
590
|
});
|
|
583
|
-
}
|
|
591
|
+
}
|
|
584
592
|
};
|
|
585
593
|
}
|
|
586
594
|
|
|
587
595
|
// src/renderer-svg.ts
|
|
588
|
-
var DEFAULT_MORPH_DURATION_MS2 = 300;
|
|
589
596
|
var MAX_TRAIL_SEGMENTS = 200;
|
|
590
|
-
var TRAIL_FADE_CURVE2 = 1.5;
|
|
591
|
-
var TRAIL_MAX_OPACITY2 = 0.88;
|
|
592
|
-
var TRAIL_MIN_WIDTH2 = 0.5;
|
|
593
|
-
var TRAIL_MAX_WIDTH2 = 2.5;
|
|
594
|
-
var DEFAULT_SKELETON_OPACITY2 = 0.15;
|
|
595
|
-
var FIT_PADDING2 = 0.1;
|
|
596
597
|
var EMPTY_PARAMS2 = {};
|
|
598
|
+
function pointsToPathString(pts, scale, offsetX, offsetY) {
|
|
599
|
+
if (pts.length < 2) return "";
|
|
600
|
+
const px = (p) => (p.x * scale + offsetX).toFixed(2);
|
|
601
|
+
const py = (p) => (p.y * scale + offsetY).toFixed(2);
|
|
602
|
+
let d = `M${px(pts[0])} ${py(pts[0])}`;
|
|
603
|
+
for (let i = 1; i < pts.length; i++) {
|
|
604
|
+
d += ` L${px(pts[i])} ${py(pts[i])}`;
|
|
605
|
+
}
|
|
606
|
+
return d + " Z";
|
|
607
|
+
}
|
|
608
|
+
function sampleCurveSkeleton(curveDef) {
|
|
609
|
+
const period = curveDef.period ?? Math.PI * 2;
|
|
610
|
+
const samples = Math.ceil(period * 50);
|
|
611
|
+
const pts = Array.from({ length: samples });
|
|
612
|
+
for (let i = 0; i < samples; i++) {
|
|
613
|
+
const t = i / (samples - 1) * period;
|
|
614
|
+
pts[i] = curveDef.skeletonFn ? curveDef.skeletonFn(t) : curveDef.fn(t, 0, EMPTY_PARAMS2);
|
|
615
|
+
}
|
|
616
|
+
return pts;
|
|
617
|
+
}
|
|
597
618
|
function el(tag) {
|
|
598
619
|
return document.createElementNS("http://www.w3.org/2000/svg", tag);
|
|
599
620
|
}
|
|
@@ -604,7 +625,7 @@ function createSVGRenderer(options) {
|
|
|
604
625
|
trailColor: options.trailColor ?? "#ffffff",
|
|
605
626
|
headColor: options.headColor ?? "#ffffff",
|
|
606
627
|
headRadius: options.headRadius ?? 4,
|
|
607
|
-
ariaLabel: options.ariaLabel ?? "Loading"
|
|
628
|
+
ariaLabel: options.ariaLabel ?? "Loading"
|
|
608
629
|
};
|
|
609
630
|
const rect = container.getBoundingClientRect();
|
|
610
631
|
const width = rect.width || 200;
|
|
@@ -621,7 +642,7 @@ function createSVGRenderer(options) {
|
|
|
621
642
|
const skeletonPath = el("path");
|
|
622
643
|
skeletonPath.setAttribute("fill", "none");
|
|
623
644
|
skeletonPath.setAttribute("stroke", opts.skeletonColor);
|
|
624
|
-
skeletonPath.setAttribute("stroke-opacity", String(
|
|
645
|
+
skeletonPath.setAttribute("stroke-opacity", String(DEFAULT_SKELETON_OPACITY));
|
|
625
646
|
skeletonPath.setAttribute("stroke-width", "1.5");
|
|
626
647
|
svg.appendChild(skeletonPath);
|
|
627
648
|
const skeletonPathA = el("path");
|
|
@@ -653,41 +674,13 @@ function createSVGRenderer(options) {
|
|
|
653
674
|
let scale = 1;
|
|
654
675
|
let offsetX = 0;
|
|
655
676
|
let offsetY = 0;
|
|
656
|
-
function
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
maxX = first.x,
|
|
663
|
-
minY = first.y,
|
|
664
|
-
maxY = first.y;
|
|
665
|
-
for (const p of skeleton2) {
|
|
666
|
-
if (p.x < minX) {
|
|
667
|
-
minX = p.x;
|
|
668
|
-
}
|
|
669
|
-
if (p.x > maxX) {
|
|
670
|
-
maxX = p.x;
|
|
671
|
-
}
|
|
672
|
-
if (p.y < minY) {
|
|
673
|
-
minY = p.y;
|
|
674
|
-
}
|
|
675
|
-
if (p.y > maxY) {
|
|
676
|
-
maxY = p.y;
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
const w = maxX - minX;
|
|
680
|
-
const h = maxY - minY;
|
|
681
|
-
if (w === 0 && h === 0) {
|
|
682
|
-
throw new Error(
|
|
683
|
-
"[sarmal] All skeleton points are identical. Check that your curve fn returns distinct points for different values of t.",
|
|
684
|
-
);
|
|
677
|
+
function applyBoundaries(skeleton2) {
|
|
678
|
+
const b = computeBoundaries(skeleton2, width, height);
|
|
679
|
+
if (b) {
|
|
680
|
+
scale = b.scale;
|
|
681
|
+
offsetX = b.offsetX;
|
|
682
|
+
offsetY = b.offsetY;
|
|
685
683
|
}
|
|
686
|
-
const scaleX = width / (w * (1 + FIT_PADDING2 * 2));
|
|
687
|
-
const scaleY = height / (h * (1 + FIT_PADDING2 * 2));
|
|
688
|
-
scale = Math.min(scaleX, scaleY);
|
|
689
|
-
offsetX = (width - w * scale) / 2 - minX * scale;
|
|
690
|
-
offsetY = (height - h * scale) / 2 - minY * scale;
|
|
691
684
|
}
|
|
692
685
|
function px(p) {
|
|
693
686
|
return p.x * scale + offsetX;
|
|
@@ -695,26 +688,11 @@ function createSVGRenderer(options) {
|
|
|
695
688
|
function py(p) {
|
|
696
689
|
return p.y * scale + offsetY;
|
|
697
690
|
}
|
|
698
|
-
function pxStr(p) {
|
|
699
|
-
return px(p).toFixed(2);
|
|
700
|
-
}
|
|
701
|
-
function pyStr(p) {
|
|
702
|
-
return py(p).toFixed(2);
|
|
703
|
-
}
|
|
704
691
|
function updateSkeleton(skeleton2) {
|
|
705
|
-
|
|
706
|
-
skeletonPath.setAttribute("d", "");
|
|
707
|
-
return;
|
|
708
|
-
}
|
|
709
|
-
let d = `M${pxStr(skeleton2[0])} ${pyStr(skeleton2[0])}`;
|
|
710
|
-
for (let i = 1; i < skeleton2.length; i++) {
|
|
711
|
-
d += ` L${pxStr(skeleton2[i])} ${pyStr(skeleton2[i])}`;
|
|
712
|
-
}
|
|
713
|
-
d += " Z";
|
|
714
|
-
skeletonPath.setAttribute("d", d);
|
|
692
|
+
skeletonPath.setAttribute("d", pointsToPathString(skeleton2, scale, offsetX, offsetY));
|
|
715
693
|
}
|
|
716
694
|
const skeleton = engine.getSarmalSkeleton();
|
|
717
|
-
|
|
695
|
+
applyBoundaries(skeleton);
|
|
718
696
|
if (!engine.isLiveSkeleton) {
|
|
719
697
|
updateSkeleton(skeleton);
|
|
720
698
|
}
|
|
@@ -726,25 +704,13 @@ function createSVGRenderer(options) {
|
|
|
726
704
|
return;
|
|
727
705
|
}
|
|
728
706
|
for (let i = 0; i < trailCount - 1; i++) {
|
|
729
|
-
const
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
const n0 = computeNormal(trail, i);
|
|
737
|
-
const n1 = computeNormal(trail, i + 1);
|
|
738
|
-
const halfW0 = width2 / 2;
|
|
739
|
-
const halfW1 = nextWidth / 2;
|
|
740
|
-
const l0x = px(curr) + n0.x * halfW0;
|
|
741
|
-
const l0y = py(curr) + n0.y * halfW0;
|
|
742
|
-
const r0x = px(curr) - n0.x * halfW0;
|
|
743
|
-
const r0y = py(curr) - n0.y * halfW0;
|
|
744
|
-
const l1x = px(next) + n1.x * halfW1;
|
|
745
|
-
const l1y = py(next) + n1.y * halfW1;
|
|
746
|
-
const r1x = px(next) - n1.x * halfW1;
|
|
747
|
-
const r1y = py(next) - n1.y * halfW1;
|
|
707
|
+
const { l0x, l0y, r0x, r0y, l1x, l1y, r1x, r1y, opacity } = computeTrailQuad(
|
|
708
|
+
trail,
|
|
709
|
+
i,
|
|
710
|
+
trailCount,
|
|
711
|
+
px,
|
|
712
|
+
py
|
|
713
|
+
);
|
|
748
714
|
const d = `M${l0x.toFixed(2)} ${l0y.toFixed(2)} L${l1x.toFixed(2)} ${l1y.toFixed(2)} L${r1x.toFixed(2)} ${r1y.toFixed(2)} L${r0x.toFixed(2)} ${r0y.toFixed(2)} Z`;
|
|
749
715
|
trailPaths[i].setAttribute("d", d);
|
|
750
716
|
trailPaths[i].setAttribute("fill-opacity", opacity.toFixed(3));
|
|
@@ -765,33 +731,11 @@ function createSVGRenderer(options) {
|
|
|
765
731
|
}
|
|
766
732
|
let animationId = null;
|
|
767
733
|
let lastTime = 0;
|
|
768
|
-
const prefersReducedMotion =
|
|
769
|
-
typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
734
|
+
const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
770
735
|
let morphResolve = null;
|
|
771
|
-
let morphDurationMs =
|
|
736
|
+
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
772
737
|
let morphTarget = null;
|
|
773
738
|
let morphAlpha = 0;
|
|
774
|
-
function buildSkeletonPath(target, scale2, offsetX2, offsetY2) {
|
|
775
|
-
const period = target.period ?? Math.PI * 2;
|
|
776
|
-
const samples = Math.max(50, Math.round(period * 20));
|
|
777
|
-
const points = [];
|
|
778
|
-
for (let i = 0; i <= samples; i++) {
|
|
779
|
-
const t = (i / samples) * period;
|
|
780
|
-
const p = target.fn(t, 0, EMPTY_PARAMS2);
|
|
781
|
-
points.push(p);
|
|
782
|
-
}
|
|
783
|
-
if (points.length < 2) {
|
|
784
|
-
return "";
|
|
785
|
-
}
|
|
786
|
-
const px2 = (p) => (p.x * scale2 + offsetX2).toFixed(2);
|
|
787
|
-
const py2 = (p) => (p.y * scale2 + offsetY2).toFixed(2);
|
|
788
|
-
let d = `M${px2(points[0])} ${py2(points[0])}`;
|
|
789
|
-
for (let i = 1; i < points.length; i++) {
|
|
790
|
-
d += ` L${px2(points[i])} ${py2(points[i])}`;
|
|
791
|
-
}
|
|
792
|
-
d += " Z";
|
|
793
|
-
return d;
|
|
794
|
-
}
|
|
795
739
|
function renderFrame() {
|
|
796
740
|
const now = performance.now();
|
|
797
741
|
const dt = Math.min((now - lastTime) / 1e3, 1 / 30);
|
|
@@ -804,16 +748,13 @@ function createSVGRenderer(options) {
|
|
|
804
748
|
skeletonPathA.setAttribute("visibility", "visible");
|
|
805
749
|
skeletonPathA.setAttribute(
|
|
806
750
|
"stroke-opacity",
|
|
807
|
-
String((1 - morphAlpha) *
|
|
751
|
+
String((1 - morphAlpha) * DEFAULT_SKELETON_OPACITY)
|
|
808
752
|
);
|
|
809
753
|
}
|
|
810
754
|
if (morphPathBBuilt) {
|
|
811
755
|
skeletonPathB.setAttribute("d", morphPathBBuilt);
|
|
812
756
|
skeletonPathB.setAttribute("visibility", "visible");
|
|
813
|
-
skeletonPathB.setAttribute(
|
|
814
|
-
"stroke-opacity",
|
|
815
|
-
String(morphAlpha * DEFAULT_SKELETON_OPACITY2),
|
|
816
|
-
);
|
|
757
|
+
skeletonPathB.setAttribute("stroke-opacity", String(morphAlpha * DEFAULT_SKELETON_OPACITY));
|
|
817
758
|
}
|
|
818
759
|
if (morphAlpha >= 1) {
|
|
819
760
|
engine.completeMorph();
|
|
@@ -826,7 +767,7 @@ function createSVGRenderer(options) {
|
|
|
826
767
|
skeletonPathA.setAttribute("visibility", "hidden");
|
|
827
768
|
skeletonPathB.setAttribute("visibility", "hidden");
|
|
828
769
|
const newSkeleton = engine.getSarmalSkeleton();
|
|
829
|
-
|
|
770
|
+
applyBoundaries(newSkeleton);
|
|
830
771
|
updateSkeleton(newSkeleton);
|
|
831
772
|
}
|
|
832
773
|
}
|
|
@@ -834,7 +775,7 @@ function createSVGRenderer(options) {
|
|
|
834
775
|
const trailCount = engine.trailCount;
|
|
835
776
|
if (engine.isLiveSkeleton && engine.morphAlpha === null) {
|
|
836
777
|
const liveSkeleton = engine.getSarmalSkeleton();
|
|
837
|
-
|
|
778
|
+
applyBoundaries(liveSkeleton);
|
|
838
779
|
updateSkeleton(liveSkeleton);
|
|
839
780
|
}
|
|
840
781
|
updateTrail(trail, trailCount);
|
|
@@ -868,12 +809,12 @@ function createSVGRenderer(options) {
|
|
|
868
809
|
}
|
|
869
810
|
svg.remove();
|
|
870
811
|
},
|
|
812
|
+
jump(t, options2) {
|
|
813
|
+
engine.jump(t, options2);
|
|
814
|
+
},
|
|
871
815
|
seek(t, options2) {
|
|
872
816
|
engine.seek(t, options2);
|
|
873
817
|
},
|
|
874
|
-
seekWithTrail(t) {
|
|
875
|
-
engine.seekWithTrail(t);
|
|
876
|
-
},
|
|
877
818
|
morphTo(target, options2) {
|
|
878
819
|
if (morphResolve !== null) {
|
|
879
820
|
engine.completeMorph();
|
|
@@ -883,29 +824,20 @@ function createSVGRenderer(options) {
|
|
|
883
824
|
skeletonPathA.setAttribute("visibility", "hidden");
|
|
884
825
|
skeletonPathB.setAttribute("visibility", "hidden");
|
|
885
826
|
}
|
|
886
|
-
morphDurationMs = options2?.duration ??
|
|
827
|
+
morphDurationMs = options2?.duration ?? DEFAULT_MORPH_DURATION_MS;
|
|
887
828
|
morphTarget = target;
|
|
888
829
|
morphAlpha = 0;
|
|
889
830
|
const currentSkeleton = engine.getSarmalSkeleton();
|
|
890
|
-
|
|
891
|
-
const px2 = (p) => (p.x * scale + offsetX).toFixed(2);
|
|
892
|
-
const py2 = (p) => (p.y * scale + offsetY).toFixed(2);
|
|
893
|
-
morphPathABuilt = `M${px2(currentSkeleton[0])} ${py2(currentSkeleton[0])}`;
|
|
894
|
-
for (let i = 1; i < currentSkeleton.length; i++) {
|
|
895
|
-
morphPathABuilt += ` L${px2(currentSkeleton[i])} ${py2(currentSkeleton[i])}`;
|
|
896
|
-
}
|
|
897
|
-
morphPathABuilt += " Z";
|
|
898
|
-
} else {
|
|
899
|
-
morphPathABuilt = "";
|
|
900
|
-
}
|
|
831
|
+
morphPathABuilt = pointsToPathString(currentSkeleton, scale, offsetX, offsetY);
|
|
901
832
|
engine.startMorph(target, options2?.morphStrategy);
|
|
902
833
|
if (morphTarget) {
|
|
903
|
-
|
|
834
|
+
const targetSkeleton = sampleCurveSkeleton(target);
|
|
835
|
+
morphPathBBuilt = pointsToPathString(targetSkeleton, scale, offsetX, offsetY);
|
|
904
836
|
}
|
|
905
837
|
return new Promise((resolve) => {
|
|
906
838
|
morphResolve = resolve;
|
|
907
839
|
});
|
|
908
|
-
}
|
|
840
|
+
}
|
|
909
841
|
};
|
|
910
842
|
}
|
|
911
843
|
function createSarmalSVG(container, curveDef, options) {
|
|
@@ -917,22 +849,19 @@ function createSarmalSVG(container, curveDef, options) {
|
|
|
917
849
|
// src/curves/artemis2.ts
|
|
918
850
|
var TWO_PI2 = Math.PI * 2;
|
|
919
851
|
function artemis2Fn(t, _time, _params) {
|
|
920
|
-
const a = 0.35,
|
|
921
|
-
|
|
922
|
-
ox = 0.175;
|
|
923
|
-
const s = Math.sin(t),
|
|
924
|
-
c = Math.cos(t);
|
|
852
|
+
const a = 0.35, b = 0.15, ox = 0.175;
|
|
853
|
+
const s = Math.sin(t), c = Math.cos(t);
|
|
925
854
|
const denom = 1 + s * s;
|
|
926
855
|
return {
|
|
927
|
-
x:
|
|
928
|
-
y:
|
|
856
|
+
x: c * (1 + a * c) / denom - ox,
|
|
857
|
+
y: s * c * (1 + b * c) / denom
|
|
929
858
|
};
|
|
930
859
|
}
|
|
931
860
|
var artemis2 = {
|
|
932
861
|
name: "Artemis II",
|
|
933
862
|
fn: artemis2Fn,
|
|
934
863
|
period: TWO_PI2,
|
|
935
|
-
speed: 0.7
|
|
864
|
+
speed: 0.7
|
|
936
865
|
};
|
|
937
866
|
|
|
938
867
|
// src/curves/astroid.ts
|
|
@@ -942,14 +871,14 @@ function astroidFn(t, _time, _params) {
|
|
|
942
871
|
const s = Math.sin(t);
|
|
943
872
|
return {
|
|
944
873
|
x: c * c * c,
|
|
945
|
-
y: s * s * s
|
|
874
|
+
y: s * s * s
|
|
946
875
|
};
|
|
947
876
|
}
|
|
948
877
|
var astroid = {
|
|
949
878
|
name: "Astroid",
|
|
950
879
|
fn: astroidFn,
|
|
951
880
|
period: TWO_PI3,
|
|
952
|
-
speed: 1.1
|
|
881
|
+
speed: 1.1
|
|
953
882
|
};
|
|
954
883
|
|
|
955
884
|
// src/curves/deltoid.ts
|
|
@@ -957,14 +886,14 @@ var TWO_PI4 = Math.PI * 2;
|
|
|
957
886
|
function deltoidFn(t, _time, _params) {
|
|
958
887
|
return {
|
|
959
888
|
x: 2 * Math.cos(t) + Math.cos(2 * t),
|
|
960
|
-
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
889
|
+
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
961
890
|
};
|
|
962
891
|
}
|
|
963
892
|
var deltoid = {
|
|
964
893
|
name: "Deltoid",
|
|
965
894
|
fn: deltoidFn,
|
|
966
895
|
period: TWO_PI4,
|
|
967
|
-
speed: 0.9
|
|
896
|
+
speed: 0.9
|
|
968
897
|
};
|
|
969
898
|
|
|
970
899
|
// src/curves/epicycloid3.ts
|
|
@@ -972,14 +901,14 @@ var TWO_PI5 = Math.PI * 2;
|
|
|
972
901
|
function epicycloid3Fn(t, _time, _params) {
|
|
973
902
|
return {
|
|
974
903
|
x: 4 * Math.cos(t) - Math.cos(4 * t),
|
|
975
|
-
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
904
|
+
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
976
905
|
};
|
|
977
906
|
}
|
|
978
907
|
var epicycloid3 = {
|
|
979
908
|
name: "Epicycloid (n=3)",
|
|
980
909
|
fn: epicycloid3Fn,
|
|
981
910
|
period: TWO_PI5,
|
|
982
|
-
speed: 0.75
|
|
911
|
+
speed: 0.75
|
|
983
912
|
};
|
|
984
913
|
|
|
985
914
|
// src/curves/epitrochoid7.ts
|
|
@@ -988,14 +917,14 @@ function epitrochoid7Fn(t, _time, _params) {
|
|
|
988
917
|
const d = 1 + 0.55 * Math.sin(t * 0.5);
|
|
989
918
|
return {
|
|
990
919
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
991
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
920
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
992
921
|
};
|
|
993
922
|
}
|
|
994
923
|
function epitrochoid7SkeletonFn(t) {
|
|
995
924
|
const d = 1.275;
|
|
996
925
|
return {
|
|
997
926
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
998
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
927
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
999
928
|
};
|
|
1000
929
|
}
|
|
1001
930
|
var epitrochoid7 = {
|
|
@@ -1003,7 +932,7 @@ var epitrochoid7 = {
|
|
|
1003
932
|
fn: epitrochoid7Fn,
|
|
1004
933
|
period: TWO_PI6,
|
|
1005
934
|
speed: 1.4,
|
|
1006
|
-
skeletonFn: epitrochoid7SkeletonFn
|
|
935
|
+
skeletonFn: epitrochoid7SkeletonFn
|
|
1007
936
|
};
|
|
1008
937
|
|
|
1009
938
|
// src/curves/lissajous32.ts
|
|
@@ -1012,7 +941,7 @@ function lissajous32Fn(t, time, _params) {
|
|
|
1012
941
|
const phi = time * 0.45;
|
|
1013
942
|
return {
|
|
1014
943
|
x: Math.sin(3 * t + phi),
|
|
1015
|
-
y: Math.sin(2 * t)
|
|
944
|
+
y: Math.sin(2 * t)
|
|
1016
945
|
};
|
|
1017
946
|
}
|
|
1018
947
|
var lissajous32 = {
|
|
@@ -1020,7 +949,7 @@ var lissajous32 = {
|
|
|
1020
949
|
fn: lissajous32Fn,
|
|
1021
950
|
period: TWO_PI7,
|
|
1022
951
|
speed: 2,
|
|
1023
|
-
skeleton: "live"
|
|
952
|
+
skeleton: "live"
|
|
1024
953
|
};
|
|
1025
954
|
|
|
1026
955
|
// src/curves/lissajous43.ts
|
|
@@ -1029,7 +958,7 @@ function lissajous43Fn(t, time, _params) {
|
|
|
1029
958
|
const phi = time * 0.38;
|
|
1030
959
|
return {
|
|
1031
960
|
x: Math.sin(4 * t + phi),
|
|
1032
|
-
y: Math.sin(3 * t)
|
|
961
|
+
y: Math.sin(3 * t)
|
|
1033
962
|
};
|
|
1034
963
|
}
|
|
1035
964
|
var lissajous43 = {
|
|
@@ -1037,18 +966,17 @@ var lissajous43 = {
|
|
|
1037
966
|
fn: lissajous43Fn,
|
|
1038
967
|
period: TWO_PI8,
|
|
1039
968
|
speed: 1.8,
|
|
1040
|
-
skeleton: "live"
|
|
969
|
+
skeleton: "live"
|
|
1041
970
|
};
|
|
1042
971
|
|
|
1043
972
|
// src/curves/lame.ts
|
|
1044
973
|
var TWO_PI9 = Math.PI * 2;
|
|
1045
974
|
function lameFn(t, time, _params) {
|
|
1046
975
|
const p = 1.75 + 1.25 * Math.sin(time * 0.48);
|
|
1047
|
-
const c = Math.cos(t),
|
|
1048
|
-
s = Math.sin(t);
|
|
976
|
+
const c = Math.cos(t), s = Math.sin(t);
|
|
1049
977
|
return {
|
|
1050
978
|
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
1051
|
-
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
979
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
1052
980
|
};
|
|
1053
981
|
}
|
|
1054
982
|
var lame = {
|
|
@@ -1056,7 +984,7 @@ var lame = {
|
|
|
1056
984
|
fn: lameFn,
|
|
1057
985
|
period: TWO_PI9,
|
|
1058
986
|
speed: 1,
|
|
1059
|
-
skeleton: "live"
|
|
987
|
+
skeleton: "live"
|
|
1060
988
|
};
|
|
1061
989
|
|
|
1062
990
|
// src/curves/rose3.ts
|
|
@@ -1065,14 +993,14 @@ function rose3Fn(t, _time, _params) {
|
|
|
1065
993
|
const r = Math.cos(3 * t);
|
|
1066
994
|
return {
|
|
1067
995
|
x: r * Math.cos(t),
|
|
1068
|
-
y: r * Math.sin(t)
|
|
996
|
+
y: r * Math.sin(t)
|
|
1069
997
|
};
|
|
1070
998
|
}
|
|
1071
999
|
var rose3 = {
|
|
1072
1000
|
name: "Rose (n=3)",
|
|
1073
1001
|
fn: rose3Fn,
|
|
1074
1002
|
period: TWO_PI10,
|
|
1075
|
-
speed: 1.15
|
|
1003
|
+
speed: 1.15
|
|
1076
1004
|
};
|
|
1077
1005
|
|
|
1078
1006
|
// src/curves/rose5.ts
|
|
@@ -1081,14 +1009,14 @@ function rose5Fn(t, _time, _params) {
|
|
|
1081
1009
|
const r = Math.cos(5 * t);
|
|
1082
1010
|
return {
|
|
1083
1011
|
x: r * Math.cos(t),
|
|
1084
|
-
y: r * Math.sin(t)
|
|
1012
|
+
y: r * Math.sin(t)
|
|
1085
1013
|
};
|
|
1086
1014
|
}
|
|
1087
1015
|
var rose5 = {
|
|
1088
1016
|
name: "Rose (n=5)",
|
|
1089
1017
|
fn: rose5Fn,
|
|
1090
1018
|
period: TWO_PI11,
|
|
1091
|
-
speed: 1
|
|
1019
|
+
speed: 1
|
|
1092
1020
|
};
|
|
1093
1021
|
|
|
1094
1022
|
// src/curves/index.ts
|
|
@@ -1102,7 +1030,7 @@ var curves = {
|
|
|
1102
1030
|
lissajous32,
|
|
1103
1031
|
lissajous43,
|
|
1104
1032
|
epicycloid3,
|
|
1105
|
-
lame
|
|
1033
|
+
lame
|
|
1106
1034
|
};
|
|
1107
1035
|
|
|
1108
1036
|
// src/index.ts
|
|
@@ -1112,23 +1040,6 @@ function createSarmal(canvas, curveDef, options) {
|
|
|
1112
1040
|
return createRenderer({ canvas, engine, ...rendererOpts });
|
|
1113
1041
|
}
|
|
1114
1042
|
|
|
1115
|
-
export {
|
|
1116
|
-
artemis2,
|
|
1117
|
-
astroid,
|
|
1118
|
-
createEngine,
|
|
1119
|
-
createRenderer,
|
|
1120
|
-
createSVGRenderer,
|
|
1121
|
-
createSarmal,
|
|
1122
|
-
createSarmalSVG,
|
|
1123
|
-
curves,
|
|
1124
|
-
deltoid,
|
|
1125
|
-
epicycloid3,
|
|
1126
|
-
epitrochoid7,
|
|
1127
|
-
lame,
|
|
1128
|
-
lissajous32,
|
|
1129
|
-
lissajous43,
|
|
1130
|
-
rose3,
|
|
1131
|
-
rose5,
|
|
1132
|
-
};
|
|
1133
|
-
//# sourceMappingURL=index.js.map
|
|
1043
|
+
export { artemis2, astroid, createEngine, createRenderer, createSVGRenderer, createSarmal, createSarmalSVG, curves, deltoid, epicycloid3, epitrochoid7, lame, lissajous32, lissajous43, rose3, rose5 };
|
|
1134
1044
|
//# sourceMappingURL=index.js.map
|
|
1045
|
+
//# sourceMappingURL=index.js.map
|