@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/auto-init.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,29 +588,26 @@ 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/curves/artemis2.ts
|
|
588
596
|
var TWO_PI2 = Math.PI * 2;
|
|
589
597
|
function artemis2Fn(t, _time, _params) {
|
|
590
|
-
const a = 0.35,
|
|
591
|
-
|
|
592
|
-
ox = 0.175;
|
|
593
|
-
const s = Math.sin(t),
|
|
594
|
-
c = Math.cos(t);
|
|
598
|
+
const a = 0.35, b = 0.15, ox = 0.175;
|
|
599
|
+
const s = Math.sin(t), c = Math.cos(t);
|
|
595
600
|
const denom = 1 + s * s;
|
|
596
601
|
return {
|
|
597
|
-
x:
|
|
598
|
-
y:
|
|
602
|
+
x: c * (1 + a * c) / denom - ox,
|
|
603
|
+
y: s * c * (1 + b * c) / denom
|
|
599
604
|
};
|
|
600
605
|
}
|
|
601
606
|
var artemis2 = {
|
|
602
607
|
name: "Artemis II",
|
|
603
608
|
fn: artemis2Fn,
|
|
604
609
|
period: TWO_PI2,
|
|
605
|
-
speed: 0.7
|
|
610
|
+
speed: 0.7
|
|
606
611
|
};
|
|
607
612
|
|
|
608
613
|
// src/curves/astroid.ts
|
|
@@ -612,14 +617,14 @@ function astroidFn(t, _time, _params) {
|
|
|
612
617
|
const s = Math.sin(t);
|
|
613
618
|
return {
|
|
614
619
|
x: c * c * c,
|
|
615
|
-
y: s * s * s
|
|
620
|
+
y: s * s * s
|
|
616
621
|
};
|
|
617
622
|
}
|
|
618
623
|
var astroid = {
|
|
619
624
|
name: "Astroid",
|
|
620
625
|
fn: astroidFn,
|
|
621
626
|
period: TWO_PI3,
|
|
622
|
-
speed: 1.1
|
|
627
|
+
speed: 1.1
|
|
623
628
|
};
|
|
624
629
|
|
|
625
630
|
// src/curves/deltoid.ts
|
|
@@ -627,14 +632,14 @@ var TWO_PI4 = Math.PI * 2;
|
|
|
627
632
|
function deltoidFn(t, _time, _params) {
|
|
628
633
|
return {
|
|
629
634
|
x: 2 * Math.cos(t) + Math.cos(2 * t),
|
|
630
|
-
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
635
|
+
y: 2 * Math.sin(t) - Math.sin(2 * t)
|
|
631
636
|
};
|
|
632
637
|
}
|
|
633
638
|
var deltoid = {
|
|
634
639
|
name: "Deltoid",
|
|
635
640
|
fn: deltoidFn,
|
|
636
641
|
period: TWO_PI4,
|
|
637
|
-
speed: 0.9
|
|
642
|
+
speed: 0.9
|
|
638
643
|
};
|
|
639
644
|
|
|
640
645
|
// src/curves/epicycloid3.ts
|
|
@@ -642,14 +647,14 @@ var TWO_PI5 = Math.PI * 2;
|
|
|
642
647
|
function epicycloid3Fn(t, _time, _params) {
|
|
643
648
|
return {
|
|
644
649
|
x: 4 * Math.cos(t) - Math.cos(4 * t),
|
|
645
|
-
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
650
|
+
y: 4 * Math.sin(t) - Math.sin(4 * t)
|
|
646
651
|
};
|
|
647
652
|
}
|
|
648
653
|
var epicycloid3 = {
|
|
649
654
|
name: "Epicycloid (n=3)",
|
|
650
655
|
fn: epicycloid3Fn,
|
|
651
656
|
period: TWO_PI5,
|
|
652
|
-
speed: 0.75
|
|
657
|
+
speed: 0.75
|
|
653
658
|
};
|
|
654
659
|
|
|
655
660
|
// src/curves/epitrochoid7.ts
|
|
@@ -658,14 +663,14 @@ function epitrochoid7Fn(t, _time, _params) {
|
|
|
658
663
|
const d = 1 + 0.55 * Math.sin(t * 0.5);
|
|
659
664
|
return {
|
|
660
665
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
661
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
666
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
662
667
|
};
|
|
663
668
|
}
|
|
664
669
|
function epitrochoid7SkeletonFn(t) {
|
|
665
670
|
const d = 1.275;
|
|
666
671
|
return {
|
|
667
672
|
x: 7 * Math.cos(t) - d * Math.cos(7 * t),
|
|
668
|
-
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
673
|
+
y: 7 * Math.sin(t) - d * Math.sin(7 * t)
|
|
669
674
|
};
|
|
670
675
|
}
|
|
671
676
|
var epitrochoid7 = {
|
|
@@ -673,7 +678,7 @@ var epitrochoid7 = {
|
|
|
673
678
|
fn: epitrochoid7Fn,
|
|
674
679
|
period: TWO_PI6,
|
|
675
680
|
speed: 1.4,
|
|
676
|
-
skeletonFn: epitrochoid7SkeletonFn
|
|
681
|
+
skeletonFn: epitrochoid7SkeletonFn
|
|
677
682
|
};
|
|
678
683
|
|
|
679
684
|
// src/curves/lissajous32.ts
|
|
@@ -682,7 +687,7 @@ function lissajous32Fn(t, time, _params) {
|
|
|
682
687
|
const phi = time * 0.45;
|
|
683
688
|
return {
|
|
684
689
|
x: Math.sin(3 * t + phi),
|
|
685
|
-
y: Math.sin(2 * t)
|
|
690
|
+
y: Math.sin(2 * t)
|
|
686
691
|
};
|
|
687
692
|
}
|
|
688
693
|
var lissajous32 = {
|
|
@@ -690,7 +695,7 @@ var lissajous32 = {
|
|
|
690
695
|
fn: lissajous32Fn,
|
|
691
696
|
period: TWO_PI7,
|
|
692
697
|
speed: 2,
|
|
693
|
-
skeleton: "live"
|
|
698
|
+
skeleton: "live"
|
|
694
699
|
};
|
|
695
700
|
|
|
696
701
|
// src/curves/lissajous43.ts
|
|
@@ -699,7 +704,7 @@ function lissajous43Fn(t, time, _params) {
|
|
|
699
704
|
const phi = time * 0.38;
|
|
700
705
|
return {
|
|
701
706
|
x: Math.sin(4 * t + phi),
|
|
702
|
-
y: Math.sin(3 * t)
|
|
707
|
+
y: Math.sin(3 * t)
|
|
703
708
|
};
|
|
704
709
|
}
|
|
705
710
|
var lissajous43 = {
|
|
@@ -707,18 +712,17 @@ var lissajous43 = {
|
|
|
707
712
|
fn: lissajous43Fn,
|
|
708
713
|
period: TWO_PI8,
|
|
709
714
|
speed: 1.8,
|
|
710
|
-
skeleton: "live"
|
|
715
|
+
skeleton: "live"
|
|
711
716
|
};
|
|
712
717
|
|
|
713
718
|
// src/curves/lame.ts
|
|
714
719
|
var TWO_PI9 = Math.PI * 2;
|
|
715
720
|
function lameFn(t, time, _params) {
|
|
716
721
|
const p = 1.75 + 1.25 * Math.sin(time * 0.48);
|
|
717
|
-
const c = Math.cos(t),
|
|
718
|
-
s = Math.sin(t);
|
|
722
|
+
const c = Math.cos(t), s = Math.sin(t);
|
|
719
723
|
return {
|
|
720
724
|
x: Math.sign(c) * Math.pow(Math.abs(c), p),
|
|
721
|
-
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
725
|
+
y: Math.sign(s) * Math.pow(Math.abs(s), p)
|
|
722
726
|
};
|
|
723
727
|
}
|
|
724
728
|
var lame = {
|
|
@@ -726,7 +730,7 @@ var lame = {
|
|
|
726
730
|
fn: lameFn,
|
|
727
731
|
period: TWO_PI9,
|
|
728
732
|
speed: 1,
|
|
729
|
-
skeleton: "live"
|
|
733
|
+
skeleton: "live"
|
|
730
734
|
};
|
|
731
735
|
|
|
732
736
|
// src/curves/rose3.ts
|
|
@@ -735,14 +739,14 @@ function rose3Fn(t, _time, _params) {
|
|
|
735
739
|
const r = Math.cos(3 * t);
|
|
736
740
|
return {
|
|
737
741
|
x: r * Math.cos(t),
|
|
738
|
-
y: r * Math.sin(t)
|
|
742
|
+
y: r * Math.sin(t)
|
|
739
743
|
};
|
|
740
744
|
}
|
|
741
745
|
var rose3 = {
|
|
742
746
|
name: "Rose (n=3)",
|
|
743
747
|
fn: rose3Fn,
|
|
744
748
|
period: TWO_PI10,
|
|
745
|
-
speed: 1.15
|
|
749
|
+
speed: 1.15
|
|
746
750
|
};
|
|
747
751
|
|
|
748
752
|
// src/curves/rose5.ts
|
|
@@ -751,14 +755,14 @@ function rose5Fn(t, _time, _params) {
|
|
|
751
755
|
const r = Math.cos(5 * t);
|
|
752
756
|
return {
|
|
753
757
|
x: r * Math.cos(t),
|
|
754
|
-
y: r * Math.sin(t)
|
|
758
|
+
y: r * Math.sin(t)
|
|
755
759
|
};
|
|
756
760
|
}
|
|
757
761
|
var rose5 = {
|
|
758
762
|
name: "Rose (n=5)",
|
|
759
763
|
fn: rose5Fn,
|
|
760
764
|
period: TWO_PI11,
|
|
761
|
-
speed: 1
|
|
765
|
+
speed: 1
|
|
762
766
|
};
|
|
763
767
|
|
|
764
768
|
// src/curves/index.ts
|
|
@@ -772,7 +776,7 @@ var curves = {
|
|
|
772
776
|
lissajous32,
|
|
773
777
|
lissajous43,
|
|
774
778
|
epicycloid3,
|
|
775
|
-
lame
|
|
779
|
+
lame
|
|
776
780
|
};
|
|
777
781
|
|
|
778
782
|
// src/index.ts
|
|
@@ -789,7 +793,8 @@ function parsePalette(value) {
|
|
|
789
793
|
if (Array.isArray(parsed)) {
|
|
790
794
|
return parsed;
|
|
791
795
|
}
|
|
792
|
-
} catch {
|
|
796
|
+
} catch {
|
|
797
|
+
}
|
|
793
798
|
return value;
|
|
794
799
|
}
|
|
795
800
|
function init() {
|
|
@@ -804,15 +809,15 @@ function init() {
|
|
|
804
809
|
return console.error(`[sarmal] "${curveName}" is not a valid curve name`);
|
|
805
810
|
}
|
|
806
811
|
const sarmal = createSarmal(canvas, curveDef, {
|
|
807
|
-
...
|
|
808
|
-
...
|
|
809
|
-
...
|
|
810
|
-
...
|
|
811
|
-
...
|
|
812
|
-
...
|
|
813
|
-
trailStyle: canvas.dataset.trailStyle
|
|
814
|
-
}
|
|
815
|
-
...
|
|
812
|
+
...canvas.dataset.trailColor && { trailColor: canvas.dataset.trailColor },
|
|
813
|
+
...canvas.dataset.skeletonColor && { skeletonColor: canvas.dataset.skeletonColor },
|
|
814
|
+
...canvas.dataset.headColor && { headColor: canvas.dataset.headColor },
|
|
815
|
+
...canvas.dataset.headRadius && { headRadius: parseFloat(canvas.dataset.headRadius) },
|
|
816
|
+
...canvas.dataset.trailLength && { trailLength: parseInt(canvas.dataset.trailLength, 10) },
|
|
817
|
+
...canvas.dataset.trailStyle && {
|
|
818
|
+
trailStyle: canvas.dataset.trailStyle
|
|
819
|
+
},
|
|
820
|
+
...canvas.dataset.palette && { palette: parsePalette(canvas.dataset.palette) }
|
|
816
821
|
});
|
|
817
822
|
sarmal.start();
|
|
818
823
|
});
|
|
@@ -825,4 +830,4 @@ if (document.readyState === "loading") {
|
|
|
825
830
|
requestAnimationFrame(init);
|
|
826
831
|
}
|
|
827
832
|
//# sourceMappingURL=auto-init.js.map
|
|
828
|
-
//# sourceMappingURL=auto-init.js.map
|
|
833
|
+
//# sourceMappingURL=auto-init.js.map
|