pixi-effects 0.16.1 → 0.16.3
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/CHANGELOG.md +33 -0
- package/README.md +11 -9
- package/ai/SKILL.md +1 -1
- package/ai/chat-template.html +3 -3
- package/ai/reference/cheatsheet.md +7 -3
- package/ai/reference/pitfalls.md +1 -0
- package/ai/reference/recipes.md +23 -0
- package/ai/template.html +5 -5
- package/dist/{Base-qvqNxvyt.d.ts → Base-BQUodYZK.d.ts} +1 -1
- package/dist/{Base-DPEqyeB0.d.cts → Base-OHqp8qvX.d.cts} +1 -1
- package/dist/Composition-3WWNVRR5.cjs +14 -0
- package/dist/{Composition-ZZGSMQ4E.cjs.map → Composition-3WWNVRR5.cjs.map} +1 -1
- package/dist/Composition-VJWY2NDL.js +5 -0
- package/dist/{Composition-X2VZSVPD.js.map → Composition-VJWY2NDL.js.map} +1 -1
- package/dist/Controller.cjs +9 -3
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/Controller.js +9 -3
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-BIGDIla0.d.ts → Movie-DilBC348.d.ts} +8 -2
- package/dist/{Movie-CJMfAizW.d.cts → Movie-oA0SUAyb.d.cts} +8 -2
- package/dist/Presenter.d.cts +2 -2
- package/dist/Presenter.d.ts +2 -2
- package/dist/{chunk-V54NBCWG.cjs → chunk-2ROVCPSL.cjs} +28 -27
- package/dist/chunk-2ROVCPSL.cjs.map +1 -0
- package/dist/{chunk-SPPNTV7E.cjs → chunk-FJA5VUOF.cjs} +30 -13
- package/dist/chunk-FJA5VUOF.cjs.map +1 -0
- package/dist/{chunk-I2YXLHIU.js → chunk-XTIHKODH.js} +5 -4
- package/dist/chunk-XTIHKODH.js.map +1 -0
- package/dist/{chunk-7D7RAQWM.js → chunk-ZNKQH356.js} +30 -13
- package/dist/chunk-ZNKQH356.js.map +1 -0
- package/dist/index.cjs +128 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -5
- package/dist/index.d.ts +37 -5
- package/dist/index.js +106 -17
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/dist/three.cjs +5 -5
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +1 -1
- package/dist/{types-C8XEUoqe.d.cts → types-SS51lP6O.d.cts} +7 -1
- package/dist/{types-C8XEUoqe.d.ts → types-SS51lP6O.d.ts} +7 -1
- package/docs/dsl.md +31 -1
- package/llms-full.txt +63 -5
- package/package.json +2 -1
- package/dist/Composition-X2VZSVPD.js +0 -5
- package/dist/Composition-ZZGSMQ4E.cjs +0 -14
- package/dist/chunk-7D7RAQWM.js.map +0 -1
- package/dist/chunk-I2YXLHIU.js.map +0 -1
- package/dist/chunk-SPPNTV7E.cjs.map +0 -1
- package/dist/chunk-V54NBCWG.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunk2ROVCPSL_cjs = require('./chunk-2ROVCPSL.cjs');
|
|
4
|
+
var chunkFJA5VUOF_cjs = require('./chunk-FJA5VUOF.cjs');
|
|
5
5
|
var chunkUQBGW5DO_cjs = require('./chunk-UQBGW5DO.cjs');
|
|
6
6
|
var PIXI = require('pixi.js');
|
|
7
7
|
var gsap = require('gsap');
|
|
@@ -867,16 +867,16 @@ function expandTransitions(spec) {
|
|
|
867
867
|
if (toUses > 1) {
|
|
868
868
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
869
869
|
}
|
|
870
|
-
const tStart =
|
|
870
|
+
const tStart = chunkFJA5VUOF_cjs.resolveAt(t.at, parentDuration);
|
|
871
871
|
const tEnd = tStart + t.duration;
|
|
872
872
|
const fromSeq = fromEntry.seq;
|
|
873
|
-
const fromStart =
|
|
873
|
+
const fromStart = chunkFJA5VUOF_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
874
874
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
875
875
|
if (tStart < fromStart - EPS || tEnd > fromEnd + EPS) {
|
|
876
876
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
|
|
877
877
|
}
|
|
878
878
|
const toSeq = toEntry.seq;
|
|
879
|
-
const toStart =
|
|
879
|
+
const toStart = chunkFJA5VUOF_cjs.resolveAt(toSeq.at, parentDuration);
|
|
880
880
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
881
881
|
if (tStart < toStart - EPS || tEnd > toEnd + EPS) {
|
|
882
882
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
|
|
@@ -1216,9 +1216,9 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1216
1216
|
onCanvas = inter === 0 && area > 0 ? "none" : inter >= area - 1e-6 ? "full" : "partial";
|
|
1217
1217
|
if (area === 0) onCanvas = "none";
|
|
1218
1218
|
}
|
|
1219
|
-
const keys =
|
|
1219
|
+
const keys = chunkFJA5VUOF_cjs.collectPropKeys(seq.spec);
|
|
1220
1220
|
const carried = carriers.some((c) => {
|
|
1221
|
-
const k =
|
|
1221
|
+
const k = chunkFJA5VUOF_cjs.collectPropKeys(c.spec);
|
|
1222
1222
|
return (c.spec.keyframes ?? []).length > 0 && (k.has("x") || k.has("y") || k.has("rotation") || k.has("scale"));
|
|
1223
1223
|
});
|
|
1224
1224
|
const moving = parentMoving || carried || (seq.spec.keyframes ?? []).length > 0 && (keys.has("x") || keys.has("y"));
|
|
@@ -1239,7 +1239,7 @@ function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
|
1239
1239
|
const group = parentScene ?? (name !== void 0 && blending.has(name) ? name : void 0);
|
|
1240
1240
|
if (group) scene.set(info, group);
|
|
1241
1241
|
if (zero || seq.showsNothingYet) scaledToNothing.add(info);
|
|
1242
|
-
if (seq instanceof
|
|
1242
|
+
if (seq instanceof chunk2ROVCPSL_cjs.CompositionSequence) walk2(seq, prefix + label + "/", insideThreeD || threeD, visible, group, moving, zero);
|
|
1243
1243
|
});
|
|
1244
1244
|
};
|
|
1245
1245
|
walk2(root, "", false, true);
|
|
@@ -1300,10 +1300,10 @@ function walk(comp, parentStart, parentEnd, depth, prefix, rows, transitions) {
|
|
|
1300
1300
|
const start = parentStart + (seq.at ?? 0);
|
|
1301
1301
|
const end = Math.min(parentEnd, seq.duration !== void 0 ? start + seq.duration : parentEnd);
|
|
1302
1302
|
const span = end - start;
|
|
1303
|
-
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start +
|
|
1303
|
+
const keys = (seq.spec.keyframes ?? []).map((kf) => round(start + chunkFJA5VUOF_cjs.resolveAt(kf.at, span))).sort((a, b) => a - b).slice(0, MAX_KEYS);
|
|
1304
1304
|
const row = { path: prefix + name, name, type: seq.spec.type, depth, start: round(start), end: round(end), keys, detail: detailOf(seq) };
|
|
1305
1305
|
const inner = [];
|
|
1306
|
-
const isComp = seq instanceof
|
|
1306
|
+
const isComp = seq instanceof chunk2ROVCPSL_cjs.CompositionSequence;
|
|
1307
1307
|
if (isComp) walk(seq, start, end, depth + 1, prefix + name + "/", inner, transitions);
|
|
1308
1308
|
entries.push({ row, inner, groupable: !isComp });
|
|
1309
1309
|
});
|
|
@@ -1851,7 +1851,7 @@ var Movie = class {
|
|
|
1851
1851
|
height: options.composition.height ?? this.height,
|
|
1852
1852
|
duration: options.composition.duration ?? this.duration
|
|
1853
1853
|
} : void 0;
|
|
1854
|
-
await
|
|
1854
|
+
await chunkFJA5VUOF_cjs.ensureFilterLibrary(seededComposition);
|
|
1855
1855
|
const userComposition = seededComposition ? expandTransitions(seededComposition) : void 0;
|
|
1856
1856
|
const rootSeqSpec = {
|
|
1857
1857
|
type: "composition",
|
|
@@ -1861,7 +1861,7 @@ var Movie = class {
|
|
|
1861
1861
|
...userComposition
|
|
1862
1862
|
};
|
|
1863
1863
|
if (userComposition) carryTransitionWindows(userComposition, rootSeqSpec);
|
|
1864
|
-
const composition = new
|
|
1864
|
+
const composition = new chunk2ROVCPSL_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
1865
1865
|
await composition.build();
|
|
1866
1866
|
this._rootSequence = composition;
|
|
1867
1867
|
if (composition.target) root.addChild(composition.target);
|
|
@@ -2140,7 +2140,8 @@ var Movie = class {
|
|
|
2140
2140
|
_renderNow() {
|
|
2141
2141
|
const app = this.app;
|
|
2142
2142
|
if (!app?.renderer) return;
|
|
2143
|
-
this._rootSequence?.syncFrame();
|
|
2143
|
+
if (!this._synced) this._rootSequence?.syncFrame();
|
|
2144
|
+
this._synced = false;
|
|
2144
2145
|
PIXI.Culler.shared.cull(app.stage, app.renderer.screen, false);
|
|
2145
2146
|
app.renderer.render({ container: app.stage });
|
|
2146
2147
|
}
|
|
@@ -2149,9 +2150,17 @@ var Movie = class {
|
|
|
2149
2150
|
throw new Error(`pixi-effects: movie.${what}() needs a ready movie \u2014 await movie.init(...) first`);
|
|
2150
2151
|
}
|
|
2151
2152
|
}
|
|
2152
|
-
/**
|
|
2153
|
+
/** True when the layers were already synced to the playhead for the frame about to be drawn (so `_renderNow` need not do it again). */
|
|
2154
|
+
_synced = false;
|
|
2155
|
+
/**
|
|
2156
|
+
* Projects every `threeD` layer for the current frame (see src/space). A threeD card is drawn into its own texture HERE, before the stage is
|
|
2157
|
+
* drawn, so the shapes inside it must be brought up to the playhead first: syncing only in `_renderNow` left every card showing the state of
|
|
2158
|
+
* the frame before (after a jump seek, a card whose children were animated showed a stale picture).
|
|
2159
|
+
*/
|
|
2153
2160
|
_updateSpace(t = this._timeOf(this.currentFrame)) {
|
|
2154
2161
|
if (!this._rootSequence || !this.app) return;
|
|
2162
|
+
this._rootSequence.syncFrame();
|
|
2163
|
+
this._synced = true;
|
|
2155
2164
|
this._rootSequence.updateSpace(t, this.app.renderer);
|
|
2156
2165
|
}
|
|
2157
2166
|
/** The motion blur an operation uses: its own option when given (`false` is off), otherwise the movie's. */
|
|
@@ -2456,6 +2465,9 @@ function splitText(text, style = {}, opts = {}) {
|
|
|
2456
2465
|
align = "left";
|
|
2457
2466
|
}
|
|
2458
2467
|
const x0 = opts.x ?? 0, y0 = opts.y ?? 0;
|
|
2468
|
+
for (const [n, v] of [["x", x0], ["y", y0]]) {
|
|
2469
|
+
if (typeof v !== "number" || !Number.isFinite(v)) throw new Error(`splitText(): ${n} must be a number of pixels (e.g. ${n}: 640), got ${JSON.stringify(v)}: the pieces are placed by measuring, so an expression such as 'GW/2' cannot be used here. \`y\` is the top of the line.`);
|
|
2470
|
+
}
|
|
2459
2471
|
if (text === "") return [];
|
|
2460
2472
|
const ts = new PIXI.TextStyle(style);
|
|
2461
2473
|
const lineHeight = PIXI.CanvasTextMetrics.measureText("M", ts).lineHeight ?? PIXI.CanvasTextMetrics.measureText("M", ts).height;
|
|
@@ -2617,17 +2629,17 @@ function orbit(opts) {
|
|
|
2617
2629
|
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
2618
2630
|
}
|
|
2619
2631
|
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
2620
|
-
const fixedR = opts.radius ??
|
|
2632
|
+
const fixedR = opts.radius ?? chunkFJA5VUOF_cjs.homeDistance(height, fov ?? chunkFJA5VUOF_cjs.DEFAULT_FOV);
|
|
2621
2633
|
const start = opts.start ?? -degrees / 2;
|
|
2622
2634
|
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
2623
2635
|
const easeFn = parseEase(ease);
|
|
2624
2636
|
const dollyEase = dolly ? parseEase(dolly.ease ?? ease) : null;
|
|
2625
2637
|
const pos = (i) => {
|
|
2626
2638
|
const p = i / steps;
|
|
2627
|
-
const a = (start + degrees * easeFn(p)) *
|
|
2639
|
+
const a = (start + degrees * easeFn(p)) * chunkFJA5VUOF_cjs.DEG;
|
|
2628
2640
|
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
2629
2641
|
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
2630
|
-
const R =
|
|
2642
|
+
const R = chunkFJA5VUOF_cjs.homeDistance(height, f);
|
|
2631
2643
|
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
2632
2644
|
};
|
|
2633
2645
|
const keyframes = [];
|
|
@@ -2682,7 +2694,7 @@ function particles(opts) {
|
|
|
2682
2694
|
const round3 = (v) => Math.round(v * 1e6) / 1e6;
|
|
2683
2695
|
const out = [];
|
|
2684
2696
|
for (let i = 0; i < count; i++) {
|
|
2685
|
-
const r =
|
|
2697
|
+
const r = chunkFJA5VUOF_cjs.random(seed * 1000003 + i * 7919 + 17);
|
|
2686
2698
|
const pick = ([a2, b]) => a2 + r() * (b - a2);
|
|
2687
2699
|
const born = at + r() * emit;
|
|
2688
2700
|
const lifetime = pick(life);
|
|
@@ -2695,7 +2707,7 @@ function particles(opts) {
|
|
|
2695
2707
|
const turn = spin ? pick(spin) : 0;
|
|
2696
2708
|
const startAngle = spin ? r() * 360 : 0;
|
|
2697
2709
|
const swayAmp = sway?.amp ?? 0, swayFreq = sway?.freq ?? 1;
|
|
2698
|
-
const n0 = sway ?
|
|
2710
|
+
const n0 = sway ? chunkFJA5VUOF_cjs.noise(0, seed * 1000003 + i) : 0;
|
|
2699
2711
|
const at_ = (t) => {
|
|
2700
2712
|
const axis = (p0, v0, acc) => {
|
|
2701
2713
|
if (drag > 0) {
|
|
@@ -2704,7 +2716,7 @@ function particles(opts) {
|
|
|
2704
2716
|
}
|
|
2705
2717
|
return p0 + v0 * t + 0.5 * acc * t * t;
|
|
2706
2718
|
};
|
|
2707
|
-
const sw = sway ? swayAmp * (
|
|
2719
|
+
const sw = sway ? swayAmp * (chunkFJA5VUOF_cjs.noise(t * swayFreq, seed * 1000003 + i) - n0) : 0;
|
|
2708
2720
|
return { x: axis(x0, vx, wind) + sw, y: axis(y0, vy, gravity) };
|
|
2709
2721
|
};
|
|
2710
2722
|
const kfs = [];
|
|
@@ -2766,7 +2778,7 @@ function followPath(opts) {
|
|
|
2766
2778
|
if (steps > MAX_STEPS) throw new Error(`followPath(): ${steps} samples is too many (max ${MAX_STEPS}); lower frameRate or duration`);
|
|
2767
2779
|
const segments = [];
|
|
2768
2780
|
let total = 0;
|
|
2769
|
-
for (const line of
|
|
2781
|
+
for (const line of chunkFJA5VUOF_cjs.flattenSvgPath(d)) {
|
|
2770
2782
|
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
2771
2783
|
for (let i = 2; i < p.length; i += 2) {
|
|
2772
2784
|
const len = Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]);
|
|
@@ -2816,6 +2828,78 @@ function followPath(opts) {
|
|
|
2816
2828
|
return out;
|
|
2817
2829
|
}
|
|
2818
2830
|
|
|
2831
|
+
// src/presets/cameraPath.ts
|
|
2832
|
+
var KEYS4 = ["points", "at", "duration", "ease", "look", "lookAhead", "smooth", "from", "to", "frameRate"];
|
|
2833
|
+
var MAX_STEPS2 = 4e3;
|
|
2834
|
+
var PER_SPAN = 48;
|
|
2835
|
+
function cameraPath(opts) {
|
|
2836
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("cameraPath()", opts, KEYS4);
|
|
2837
|
+
const { points, at = 0, duration, ease = "none", look = "ahead", lookAhead = 0.08, smooth = true, from = 0, to = 1, frameRate = 30 } = opts;
|
|
2838
|
+
if (!Array.isArray(points) || points.length < 2) throw new Error("cameraPath(): points needs at least two points: [[x, y, z], [x, y, z], \u2026]");
|
|
2839
|
+
points.forEach((p, i) => {
|
|
2840
|
+
if (!Array.isArray(p) || p.length !== 3 || !p.every(Number.isFinite)) throw new Error(`cameraPath(): points[${i}] must be [x, y, z] numbers, got ${JSON.stringify(p)}`);
|
|
2841
|
+
});
|
|
2842
|
+
if (!(Number.isFinite(duration) && duration > 0)) throw new Error(`cameraPath(): duration must be a positive number of seconds, got ${duration}`);
|
|
2843
|
+
if (!(Number.isFinite(frameRate) && frameRate > 0)) throw new Error(`cameraPath(): frameRate must be a positive number (samples per second), got ${frameRate}`);
|
|
2844
|
+
if (look !== "ahead" && !(Array.isArray(look) && look.length === 3 && look.every(Number.isFinite))) throw new Error(`cameraPath(): look must be 'ahead' or [x, y, z] numbers, got ${JSON.stringify(look)}`);
|
|
2845
|
+
if (!(Number.isFinite(lookAhead) && lookAhead >= 0 && lookAhead <= 1)) throw new Error(`cameraPath(): lookAhead must be a fraction of the route between 0 and 1, got ${lookAhead}`);
|
|
2846
|
+
for (const [n, v] of [["from", from], ["to", to]]) {
|
|
2847
|
+
if (!(Number.isFinite(v) && v >= 0 && v <= 1)) throw new Error(`cameraPath(): ${n} must be a fraction of the route between 0 and 1, got ${v}`);
|
|
2848
|
+
}
|
|
2849
|
+
const steps = Math.max(1, Math.round(duration * frameRate));
|
|
2850
|
+
if (steps > MAX_STEPS2) throw new Error(`cameraPath(): ${steps} samples is too many (max ${MAX_STEPS2}); lower frameRate or duration`);
|
|
2851
|
+
const curve = [];
|
|
2852
|
+
if (smooth && points.length > 2) {
|
|
2853
|
+
const pts = points;
|
|
2854
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
2855
|
+
const p0 = pts[Math.max(i - 1, 0)], p1 = pts[i], p2 = pts[i + 1], p3 = pts[Math.min(i + 2, pts.length - 1)];
|
|
2856
|
+
for (let s = 0; s < PER_SPAN; s++) curve.push(catmullRom(p0, p1, p2, p3, s / PER_SPAN));
|
|
2857
|
+
}
|
|
2858
|
+
curve.push(pts[pts.length - 1]);
|
|
2859
|
+
} else curve.push(...points);
|
|
2860
|
+
const cum = [0];
|
|
2861
|
+
for (let i = 1; i < curve.length; i++) cum.push(cum[i - 1] + dist(curve[i - 1], curve[i]));
|
|
2862
|
+
const total = cum[cum.length - 1];
|
|
2863
|
+
if (!(total > 0)) throw new Error("cameraPath(): the route has no length (the points are all the same)");
|
|
2864
|
+
const find = (s) => {
|
|
2865
|
+
let lo = 0, hi = cum.length - 1;
|
|
2866
|
+
while (lo < hi - 1) {
|
|
2867
|
+
const mid = lo + hi >> 1;
|
|
2868
|
+
if (cum[mid] <= s) lo = mid;
|
|
2869
|
+
else hi = mid;
|
|
2870
|
+
}
|
|
2871
|
+
return lo;
|
|
2872
|
+
};
|
|
2873
|
+
const along = (fraction) => {
|
|
2874
|
+
const s = fraction * total;
|
|
2875
|
+
if (s >= total) {
|
|
2876
|
+
const a2 = curve[curve.length - 2], b2 = curve[curve.length - 1], len = dist(a2, b2) || 1, extra = s - total;
|
|
2877
|
+
return [b2[0] + (b2[0] - a2[0]) / len * extra, b2[1] + (b2[1] - a2[1]) / len * extra, b2[2] + (b2[2] - a2[2]) / len * extra];
|
|
2878
|
+
}
|
|
2879
|
+
const i = find(Math.max(s, 0)), span = cum[i + 1] - cum[i], t = span > 0 ? (s - cum[i]) / span : 0;
|
|
2880
|
+
const a = curve[i], b = curve[i + 1];
|
|
2881
|
+
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
|
|
2882
|
+
};
|
|
2883
|
+
const shape = parseEase(ease);
|
|
2884
|
+
const round3 = (v) => Math.round(v * 1e6) / 1e6;
|
|
2885
|
+
const sample = (k) => {
|
|
2886
|
+
const p = from + (to - from) * shape(k / steps);
|
|
2887
|
+
const pos = along(Math.min(Math.max(p, 0), 1));
|
|
2888
|
+
const target = look === "ahead" ? along(Math.max(p + (to >= from ? lookAhead : -lookAhead), 0)) : look;
|
|
2889
|
+
return { x: round3(pos[0]), y: round3(pos[1]), z: round3(pos[2]), lookAtX: round3(target[0]), lookAtY: round3(target[1]), lookAtZ: round3(target[2]) };
|
|
2890
|
+
};
|
|
2891
|
+
const out = [{ at, set: sample(0) }];
|
|
2892
|
+
const step = duration / steps;
|
|
2893
|
+
for (let k = 1; k <= steps; k++) out.push({ at: round3(at + (k - 1) * step), to: sample(k), duration: round3(step), ease: "none" });
|
|
2894
|
+
return out;
|
|
2895
|
+
}
|
|
2896
|
+
var dist = (a, b) => Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
2897
|
+
function catmullRom(p0, p1, p2, p3, t) {
|
|
2898
|
+
const t2 = t * t, t3 = t2 * t;
|
|
2899
|
+
const c = (a, b, d, e) => 0.5 * (2 * b + (d - a) * t + (2 * a - 5 * b + 4 * d - e) * t2 + (3 * b - a - 3 * d + e) * t3);
|
|
2900
|
+
return [c(p0[0], p1[0], p2[0], p3[0]), c(p0[1], p1[1], p2[1], p3[1]), c(p0[2], p1[2], p2[2], p3[2])];
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2819
2903
|
// src/presets/stagger.ts
|
|
2820
2904
|
var STAGGER_KEYS = ["each", "amount", "from", "grid", "ease", "seed"];
|
|
2821
2905
|
var FROM_NAMES = ["start", "end", "center", "edges", "random"];
|
|
@@ -2835,11 +2919,11 @@ function stagger(items, options = {}) {
|
|
|
2835
2919
|
if (grid && !(Array.isArray(grid) && grid.length === 2 && grid.every((g) => Number.isInteger(g) && g > 0) && grid[0] * grid[1] >= n)) {
|
|
2836
2920
|
throw new Error(`stagger(): grid must be [columns, rows] and hold all ${n} items, got ${JSON.stringify(grid)}`);
|
|
2837
2921
|
}
|
|
2838
|
-
const
|
|
2839
|
-
const max =
|
|
2922
|
+
const dist2 = distances(n, from, grid, seed);
|
|
2923
|
+
const max = dist2.reduce((m, d) => Math.max(m, d), 0);
|
|
2840
2924
|
const total = amount !== void 0 ? amount : (each ?? 0.1) * max;
|
|
2841
2925
|
const shape = parseEase(ease);
|
|
2842
|
-
const delays =
|
|
2926
|
+
const delays = dist2.map((d) => max === 0 ? 0 : Math.round(total * shape(d / max) * 1e6) / 1e6);
|
|
2843
2927
|
if (isCount) return delays;
|
|
2844
2928
|
return items.map((layer, i) => ({ ...layer, at: Math.round(((layer.at ?? 0) + delays[i]) * 1e6) / 1e6 }));
|
|
2845
2929
|
}
|
|
@@ -2847,7 +2931,7 @@ function distances(n, from, grid, seed) {
|
|
|
2847
2931
|
if (n === 0) return [];
|
|
2848
2932
|
if (from === "random") {
|
|
2849
2933
|
const order = Array.from({ length: n }, (_, i) => i);
|
|
2850
|
-
const r =
|
|
2934
|
+
const r = chunkFJA5VUOF_cjs.random(seed);
|
|
2851
2935
|
for (let i = n - 1; i > 0; i--) {
|
|
2852
2936
|
const j = Math.floor(r() * (i + 1));
|
|
2853
2937
|
[order[i], order[j]] = [order[j], order[i]];
|
|
@@ -2882,7 +2966,7 @@ function distances(n, from, grid, seed) {
|
|
|
2882
2966
|
|
|
2883
2967
|
// src/presets/wiggle.ts
|
|
2884
2968
|
var WIGGLE_KEYS = ["at", "duration", "freq", "seed", "ease", "props"];
|
|
2885
|
-
var
|
|
2969
|
+
var MAX_STEPS3 = 2e3;
|
|
2886
2970
|
function wiggle(opts) {
|
|
2887
2971
|
chunkUQBGW5DO_cjs.warnUnknownOptions("wiggle()", opts, WIGGLE_KEYS);
|
|
2888
2972
|
const { at = 0, duration, freq = 3, seed = 0, ease = "sine.inOut", props } = opts;
|
|
@@ -2896,7 +2980,7 @@ function wiggle(opts) {
|
|
|
2896
2980
|
if (p.around === void 0 || p.around === null || p.around === "") throw new Error(`wiggle(): props.${n}.around is missing`);
|
|
2897
2981
|
}
|
|
2898
2982
|
const steps = Math.ceil(duration * freq - 1e-9);
|
|
2899
|
-
if (steps >
|
|
2983
|
+
if (steps > MAX_STEPS3) throw new Error(`wiggle(): ${steps} steps is too many (max ${MAX_STEPS3}); lower freq or duration`);
|
|
2900
2984
|
const set = {};
|
|
2901
2985
|
for (const n of names) set[n] = props[n].around;
|
|
2902
2986
|
const out = [{ at, set }];
|
|
@@ -2909,7 +2993,7 @@ function wiggle(opts) {
|
|
|
2909
2993
|
to[n] = p.around;
|
|
2910
2994
|
return;
|
|
2911
2995
|
}
|
|
2912
|
-
const off = (
|
|
2996
|
+
const off = (chunkFJA5VUOF_cjs.rand(seed * 7919 + pi * 104729 + s * 31 + 1) * 2 - 1) * p.amp;
|
|
2913
2997
|
to[n] = typeof p.around === "number" ? p.around + off : `(${p.around}) ${off < 0 ? "-" : "+"} ${Math.abs(off)}`;
|
|
2914
2998
|
});
|
|
2915
2999
|
out.push({ at: at + s * stepLen, to, duration: stepLen, ease });
|
|
@@ -2918,7 +3002,7 @@ function wiggle(opts) {
|
|
|
2918
3002
|
}
|
|
2919
3003
|
|
|
2920
3004
|
// src/presets/animateText.ts
|
|
2921
|
-
var
|
|
3005
|
+
var KEYS5 = ["by", "x", "y", "align", "name", "at", "duration", "in", "out", "stagger", "idle", "styleFor"];
|
|
2922
3006
|
var PRESETS = {
|
|
2923
3007
|
rise: { from: { y: 40, alpha: 0 }, duration: 0.5, ease: "back.out(2)" },
|
|
2924
3008
|
drop: { from: { y: -50, alpha: 0 }, duration: 0.7, ease: "bounce.out" },
|
|
@@ -2930,8 +3014,13 @@ var PRESETS = {
|
|
|
2930
3014
|
};
|
|
2931
3015
|
var PRESET_NAMES = Object.keys(PRESETS);
|
|
2932
3016
|
function animateText(text, style, options) {
|
|
2933
|
-
chunkUQBGW5DO_cjs.warnUnknownOptions("animateText()", options,
|
|
3017
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("animateText()", options, KEYS5);
|
|
2934
3018
|
const { by = "chars", x = 0, y = 0, align = "left", name = "text", at = 0, duration, idle, styleFor } = options;
|
|
3019
|
+
for (const [n, v] of [["x", x], ["y", y]]) {
|
|
3020
|
+
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
3021
|
+
throw new Error(`animateText(): ${n} must be a number of pixels (e.g. ${n}: 640), got ${JSON.stringify(v)}. The letters are measured once, when the layers are made, so an expression such as 'GW/2' cannot be used here: compute the number (W / 2) yourself. \`y\` is the TOP of the line.`);
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
2935
3024
|
if (!(Number.isFinite(duration) && duration > 0)) throw new Error(`animateText(): duration must be a positive number of seconds (how long until the last piece is gone), got ${duration}`);
|
|
2936
3025
|
const pieces = splitText(text, style, { by, x, y, align });
|
|
2937
3026
|
if (pieces.length === 0) return [];
|
|
@@ -3014,11 +3103,11 @@ function resolveTween(spec, which) {
|
|
|
3014
3103
|
}
|
|
3015
3104
|
|
|
3016
3105
|
// src/presets/react.ts
|
|
3017
|
-
var
|
|
3106
|
+
var KEYS6 = ["at", "duration", "props", "audioOffset", "loop", "frameRate"];
|
|
3018
3107
|
var PROP_KEYS = ["base", "amount", "band", "beats", "decay", "attack", "release", "invert", "curve"];
|
|
3019
|
-
var
|
|
3108
|
+
var MAX_STEPS4 = 4e3;
|
|
3020
3109
|
function react(env, options) {
|
|
3021
|
-
chunkUQBGW5DO_cjs.warnUnknownOptions("react()", options,
|
|
3110
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("react()", options, KEYS6);
|
|
3022
3111
|
const { at = 0, duration, props, audioOffset = 0, loop = false } = options;
|
|
3023
3112
|
const frameRate = options.frameRate ?? env.frameRate;
|
|
3024
3113
|
if (!(Number.isFinite(duration) && duration > 0)) throw new Error(`react(): duration must be a positive number of seconds, got ${duration}`);
|
|
@@ -3033,7 +3122,7 @@ function react(env, options) {
|
|
|
3033
3122
|
if (p.beats && !(p.decay === void 0 || Number.isFinite(p.decay) && p.decay > 0)) throw new Error(`react(): props.${n}.decay must be a positive number of seconds, got ${p.decay}`);
|
|
3034
3123
|
}
|
|
3035
3124
|
const steps = Math.max(1, Math.round(duration * frameRate));
|
|
3036
|
-
if (steps >
|
|
3125
|
+
if (steps > MAX_STEPS4) throw new Error(`react(): too many keyframes (${steps} steps, max ${MAX_STEPS4}); lower frameRate (now ${frameRate}) or duration`);
|
|
3037
3126
|
const wrap = (a) => loop && env.duration > 0 ? (a % env.duration + env.duration) % env.duration : a;
|
|
3038
3127
|
const beatPulse = (a, decay) => {
|
|
3039
3128
|
const beats = env.beats;
|
|
@@ -3369,24 +3458,25 @@ function withFade(spec, opts) {
|
|
|
3369
3458
|
|
|
3370
3459
|
Object.defineProperty(exports, "noise", {
|
|
3371
3460
|
enumerable: true,
|
|
3372
|
-
get: function () { return
|
|
3461
|
+
get: function () { return chunkFJA5VUOF_cjs.noise; }
|
|
3373
3462
|
});
|
|
3374
3463
|
Object.defineProperty(exports, "rand", {
|
|
3375
3464
|
enumerable: true,
|
|
3376
|
-
get: function () { return
|
|
3465
|
+
get: function () { return chunkFJA5VUOF_cjs.rand; }
|
|
3377
3466
|
});
|
|
3378
3467
|
Object.defineProperty(exports, "random", {
|
|
3379
3468
|
enumerable: true,
|
|
3380
|
-
get: function () { return
|
|
3469
|
+
get: function () { return chunkFJA5VUOF_cjs.random; }
|
|
3381
3470
|
});
|
|
3382
3471
|
Object.defineProperty(exports, "registerSequenceType", {
|
|
3383
3472
|
enumerable: true,
|
|
3384
|
-
get: function () { return
|
|
3473
|
+
get: function () { return chunkFJA5VUOF_cjs.registerSequenceType; }
|
|
3385
3474
|
});
|
|
3386
3475
|
exports.Movie = Movie;
|
|
3387
3476
|
exports.animateText = animateText;
|
|
3388
3477
|
exports.audioEnvelope = audioEnvelope;
|
|
3389
3478
|
exports.bpmEnvelope = bpmEnvelope;
|
|
3479
|
+
exports.cameraPath = cameraPath;
|
|
3390
3480
|
exports.computeEnvelope = computeEnvelope;
|
|
3391
3481
|
exports.deck = deck;
|
|
3392
3482
|
exports.dismissLoader = dismissLoader;
|