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