pixi-effects 0.9.0 → 0.11.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/CHANGELOG.md +36 -0
- package/README.md +6 -6
- package/ai/SKILL.md +4 -3
- package/ai/reference/cheatsheet.md +17 -6
- package/ai/reference/pitfalls.md +3 -3
- package/ai/reference/recipes.md +141 -11
- package/ai/template.html +11 -8
- package/ai/tools/render.mjs +14 -5
- package/dist/{Base-CSIulyIq.d.cts → Base-CwUxTfja.d.cts} +1 -1
- package/dist/{Base-DVgwyIUj.d.ts → Base-CyvSLoCP.d.ts} +1 -1
- package/dist/Composition-7TEKHZNQ.cjs +14 -0
- package/dist/{Composition-CM62XJKT.cjs.map → Composition-7TEKHZNQ.cjs.map} +1 -1
- package/dist/Composition-HIISJAX2.js +5 -0
- package/dist/{Composition-RJDSQYTV.js.map → Composition-HIISJAX2.js.map} +1 -1
- package/dist/Controller.cjs +34 -0
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +12 -2
- package/dist/Controller.d.ts +12 -2
- package/dist/Controller.js +34 -0
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-qGHp15c_.d.cts → Movie-DSSNOF3T.d.cts} +61 -2
- package/dist/{Movie-QMlFyHkf.d.ts → Movie-nzmWsxWX.d.ts} +61 -2
- package/dist/{chunk-O4AJYUPK.js → chunk-3IPDNC3E.js} +90 -14
- package/dist/chunk-3IPDNC3E.js.map +1 -0
- package/dist/{chunk-AGMNSJJH.cjs → chunk-6NWJLVCA.cjs} +196 -12
- package/dist/chunk-6NWJLVCA.cjs.map +1 -0
- package/dist/{chunk-FNKSXBKB.js → chunk-C6QHKYC5.js} +193 -14
- package/dist/chunk-C6QHKYC5.js.map +1 -0
- package/dist/{chunk-PDBDDGG5.cjs → chunk-F7NCHS6Q.cjs} +108 -32
- package/dist/chunk-F7NCHS6Q.cjs.map +1 -0
- package/dist/index.cjs +542 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +303 -5
- package/dist/index.d.ts +303 -5
- package/dist/index.js +511 -27
- package/dist/index.js.map +1 -1
- package/dist/loader.css +110 -0
- 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-oJijbn-K.d.ts → types-BXu28nJj.d.cts} +26 -2
- package/dist/{types-oJijbn-K.d.cts → types-BXu28nJj.d.ts} +26 -2
- package/docs/api.md +16 -1
- package/docs/dsl.md +137 -2
- package/llms-full.txt +318 -26
- package/package.json +5 -2
- package/dist/Composition-CM62XJKT.cjs +0 -14
- package/dist/Composition-RJDSQYTV.js +0 -5
- package/dist/chunk-AGMNSJJH.cjs.map +0 -1
- package/dist/chunk-FNKSXBKB.js.map +0 -1
- package/dist/chunk-O4AJYUPK.js.map +0 -1
- package/dist/chunk-PDBDDGG5.cjs.map +0 -1
|
@@ -1,8 +1,43 @@
|
|
|
1
1
|
import { suggestName } from './chunk-DKGG7WD4.js';
|
|
2
2
|
import * as PIXI from 'pixi.js';
|
|
3
|
-
import { Rectangle, Container, Graphics, Assets, Texture, Sprite, Text, Filter, GlProgram, defaultFilterVert, GpuProgram, UniformGroup, FillGradient, Color
|
|
3
|
+
import { Rectangle, Container, GraphicsPath, Graphics, Assets, Texture, Sprite, Text, Filter, GlProgram, defaultFilterVert, GpuProgram, UniformGroup, FillGradient, Color } from 'pixi.js';
|
|
4
4
|
import { gsap } from 'gsap';
|
|
5
5
|
|
|
6
|
+
// src/expr/random.ts
|
|
7
|
+
function mix(h) {
|
|
8
|
+
h = Math.imul(h ^ h >>> 16, 2246822507);
|
|
9
|
+
h = Math.imul(h ^ h >>> 13, 3266489909);
|
|
10
|
+
return (h ^ h >>> 16) >>> 0;
|
|
11
|
+
}
|
|
12
|
+
function fold(n) {
|
|
13
|
+
if (!Number.isFinite(n)) return 0;
|
|
14
|
+
const i = Math.floor(n);
|
|
15
|
+
const f = n - i;
|
|
16
|
+
return (i | 0) ^ Math.imul(Math.floor(f * 1048576), 2654435761);
|
|
17
|
+
}
|
|
18
|
+
function rand(seed) {
|
|
19
|
+
return mix(fold(seed) + 2654435769) / 4294967296;
|
|
20
|
+
}
|
|
21
|
+
function random(seed) {
|
|
22
|
+
let a = fold(seed) + 1831565813 | 0;
|
|
23
|
+
return () => {
|
|
24
|
+
a = a + 1831565813 | 0;
|
|
25
|
+
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
26
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
27
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function noise(x, seed = 0) {
|
|
31
|
+
if (!Number.isFinite(x)) return 0;
|
|
32
|
+
const i = Math.floor(x);
|
|
33
|
+
const f = x - i;
|
|
34
|
+
const s = fold(seed) * 668265261;
|
|
35
|
+
const a = mix((i | 0) + s) / 2147483648 - 1;
|
|
36
|
+
const b = mix((i + 1 | 0) + s) / 2147483648 - 1;
|
|
37
|
+
const u = f * f * f * (f * (f * 6 - 15) + 10);
|
|
38
|
+
return a + (b - a) * u;
|
|
39
|
+
}
|
|
40
|
+
|
|
6
41
|
// src/expr/Parser.ts
|
|
7
42
|
var FUNCS = {
|
|
8
43
|
min: Math.min,
|
|
@@ -15,8 +50,19 @@ var FUNCS = {
|
|
|
15
50
|
pow: Math.pow,
|
|
16
51
|
sin: Math.sin,
|
|
17
52
|
cos: Math.cos,
|
|
18
|
-
tan: Math.tan
|
|
53
|
+
tan: Math.tan,
|
|
54
|
+
rand: (seed) => rand(seed),
|
|
55
|
+
noise: (x, seed = 0) => noise(x, seed),
|
|
56
|
+
lerp: (a, b, t) => a + (b - a) * t,
|
|
57
|
+
clamp: (x, lo, hi) => Math.min(Math.max(x, lo), hi),
|
|
58
|
+
smoothstep: (a, b, x) => {
|
|
59
|
+
const u = Math.min(Math.max((x - a) / (b - a), 0), 1);
|
|
60
|
+
return u * u * (3 - 2 * u);
|
|
61
|
+
},
|
|
62
|
+
mod: (a, b) => (a % b + b) % b,
|
|
63
|
+
step: (edge, x) => x >= edge ? 1 : 0
|
|
19
64
|
};
|
|
65
|
+
var CONSTS = { PI: Math.PI };
|
|
20
66
|
function isDigit(c) {
|
|
21
67
|
return c >= "0" && c <= "9";
|
|
22
68
|
}
|
|
@@ -162,6 +208,7 @@ function evalNode(node, scope) {
|
|
|
162
208
|
case "num":
|
|
163
209
|
return node.value;
|
|
164
210
|
case "var": {
|
|
211
|
+
if (node.name in CONSTS) return CONSTS[node.name];
|
|
165
212
|
const v = scope[node.name];
|
|
166
213
|
if (typeof v !== "number") throw new Error(`undefined variable: ${node.name}`);
|
|
167
214
|
return v;
|
|
@@ -943,6 +990,12 @@ var Sequence = class {
|
|
|
943
990
|
this.target = null;
|
|
944
991
|
}
|
|
945
992
|
};
|
|
993
|
+
var NullSequence = class extends Sequence {
|
|
994
|
+
async build() {
|
|
995
|
+
this.target = new Container();
|
|
996
|
+
this.buildFilters();
|
|
997
|
+
}
|
|
998
|
+
};
|
|
946
999
|
|
|
947
1000
|
// src/space/specKeys.ts
|
|
948
1001
|
function collectPropKeys(spec) {
|
|
@@ -2073,6 +2126,85 @@ function slice(line, a, b) {
|
|
|
2073
2126
|
return out;
|
|
2074
2127
|
}
|
|
2075
2128
|
|
|
2129
|
+
// src/sequences/morphPath.ts
|
|
2130
|
+
function resample(line, n) {
|
|
2131
|
+
const p = line.closed ? [...line.pts, line.pts[0], line.pts[1]] : line.pts;
|
|
2132
|
+
const cum = [0];
|
|
2133
|
+
for (let i = 2; i < p.length; i += 2) cum.push(cum[cum.length - 1] + Math.hypot(p[i] - p[i - 2], p[i + 1] - p[i - 1]));
|
|
2134
|
+
const total = cum[cum.length - 1];
|
|
2135
|
+
const out = [];
|
|
2136
|
+
if (!(total > 0)) {
|
|
2137
|
+
for (let i = 0; i < n; i++) out.push(p[0], p[1]);
|
|
2138
|
+
return out;
|
|
2139
|
+
}
|
|
2140
|
+
let seg = 1;
|
|
2141
|
+
for (let i = 0; i < n; i++) {
|
|
2142
|
+
const s = line.closed ? i * total / n : n === 1 ? 0 : i * total / (n - 1);
|
|
2143
|
+
while (seg < cum.length - 1 && cum[seg] < s) seg++;
|
|
2144
|
+
const len = cum[seg] - cum[seg - 1];
|
|
2145
|
+
const t = len > 0 ? (s - cum[seg - 1]) / len : 0;
|
|
2146
|
+
const k = seg * 2;
|
|
2147
|
+
out.push(p[k - 2] + (p[k] - p[k - 2]) * t, p[k - 1] + (p[k + 1] - p[k - 1]) * t);
|
|
2148
|
+
}
|
|
2149
|
+
return out;
|
|
2150
|
+
}
|
|
2151
|
+
var centroid = (pts) => {
|
|
2152
|
+
let x = 0, y = 0;
|
|
2153
|
+
for (let i = 0; i < pts.length; i += 2) {
|
|
2154
|
+
x += pts[i];
|
|
2155
|
+
y += pts[i + 1];
|
|
2156
|
+
}
|
|
2157
|
+
const n = pts.length / 2;
|
|
2158
|
+
return [x / n, y / n];
|
|
2159
|
+
};
|
|
2160
|
+
function align(a, b) {
|
|
2161
|
+
const n = a.length / 2;
|
|
2162
|
+
let best = b, bestCost = Infinity;
|
|
2163
|
+
for (const reversed of [false, true]) {
|
|
2164
|
+
for (let k = 0; k < n; k++) {
|
|
2165
|
+
let cost = 0;
|
|
2166
|
+
for (let i = 0; i < n && cost < bestCost; i++) {
|
|
2167
|
+
const j = reversed ? ((k - i) % n + n) % n : (k + i) % n;
|
|
2168
|
+
cost += (a[2 * i] - b[2 * j]) ** 2 + (a[2 * i + 1] - b[2 * j + 1]) ** 2;
|
|
2169
|
+
}
|
|
2170
|
+
if (cost < bestCost) {
|
|
2171
|
+
bestCost = cost;
|
|
2172
|
+
const out = [];
|
|
2173
|
+
for (let i = 0; i < n; i++) {
|
|
2174
|
+
const j = reversed ? ((k - i) % n + n) % n : (k + i) % n;
|
|
2175
|
+
out.push(b[2 * j], b[2 * j + 1]);
|
|
2176
|
+
}
|
|
2177
|
+
best = out;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
return best;
|
|
2182
|
+
}
|
|
2183
|
+
function buildMorph(from, to, n = 128) {
|
|
2184
|
+
if (from.length === 0 || to.length === 0) return [];
|
|
2185
|
+
const pairs = [];
|
|
2186
|
+
const count = Math.max(from.length, to.length);
|
|
2187
|
+
for (let i = 0; i < count; i++) {
|
|
2188
|
+
const fa = from[i], fb = to[i];
|
|
2189
|
+
const closed = (fa?.closed ?? fb.closed) && (fb?.closed ?? fa.closed);
|
|
2190
|
+
const a = fa ? resample({ pts: fa.pts, closed }, n) : collapsed(resample({ pts: fb.pts, closed }, n));
|
|
2191
|
+
let b = fb ? resample({ pts: fb.pts, closed }, n) : collapsed(a);
|
|
2192
|
+
if (closed && fa && fb) b = align(a, b);
|
|
2193
|
+
pairs.push({ a, b, closed });
|
|
2194
|
+
}
|
|
2195
|
+
return pairs;
|
|
2196
|
+
}
|
|
2197
|
+
function collapsed(pts) {
|
|
2198
|
+
const [cx, cy] = centroid(pts);
|
|
2199
|
+
const out = [];
|
|
2200
|
+
for (let i = 0; i < pts.length; i += 2) out.push(cx, cy);
|
|
2201
|
+
return out;
|
|
2202
|
+
}
|
|
2203
|
+
function morphAt(pairs, t) {
|
|
2204
|
+
const u = Math.min(Math.max(t, 0), 1);
|
|
2205
|
+
return pairs.map(({ a, b, closed }) => ({ pts: a.map((v, i) => v + (b[i] - v) * u), closed }));
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2076
2208
|
// src/sequences/Shape.ts
|
|
2077
2209
|
var STYLE_KEYS = ["fillColor", "fillAlpha", "strokeColor", "strokeAlpha", "strokeWidth"];
|
|
2078
2210
|
var COLOR_KEYS = /* @__PURE__ */ new Set(["fillColor", "strokeColor"]);
|
|
@@ -2084,7 +2216,7 @@ var GEOMETRY_KEYS_BY_SHAPE = {
|
|
|
2084
2216
|
arc: ["radius", "innerRadius", "startAngle", "endAngle"],
|
|
2085
2217
|
line: [...TRIM_KEYS],
|
|
2086
2218
|
polygon: [...TRIM_KEYS],
|
|
2087
|
-
path: [...TRIM_KEYS]
|
|
2219
|
+
path: [...TRIM_KEYS, "morph"]
|
|
2088
2220
|
};
|
|
2089
2221
|
var ANCHORED_SHAPES = /* @__PURE__ */ new Set(["rect", "circle", "ellipse", "arc"]);
|
|
2090
2222
|
var ShapeSequence = class extends Sequence {
|
|
@@ -2127,8 +2259,9 @@ var ShapeSequence = class extends Sequence {
|
|
|
2127
2259
|
}
|
|
2128
2260
|
const gradientSpec = this.spec.fillGradient ?? this.spec.initial?.fillGradient;
|
|
2129
2261
|
if (gradientSpec) this._state.fillStyle = makeGradientFill(gradientSpec);
|
|
2130
|
-
|
|
2131
|
-
this.
|
|
2262
|
+
const morph = this._setupMorph();
|
|
2263
|
+
this._drawGeometry = makeDrawGeometry(this.spec, scope, this._state, morph);
|
|
2264
|
+
this._outline = makeOutline(this.spec, scope, this._state, morph);
|
|
2132
2265
|
const { trimStart, trimEnd } = this._state;
|
|
2133
2266
|
this._state.trimStart = 0;
|
|
2134
2267
|
this._state.trimEnd = 1;
|
|
@@ -2157,6 +2290,33 @@ var ShapeSequence = class extends Sequence {
|
|
|
2157
2290
|
this._redraw();
|
|
2158
2291
|
this.buildFilters();
|
|
2159
2292
|
}
|
|
2293
|
+
/** The prepared morph between `d` and `morphTo`, or null (and a warning when the spec asked for one that cannot work). */
|
|
2294
|
+
_setupMorph() {
|
|
2295
|
+
const who = describeLayer(this.spec);
|
|
2296
|
+
const top = this.spec;
|
|
2297
|
+
const wanted = this.spec.shape === "path" && (this._state.morph !== void 0 || collectPropKeys(this.spec).has("morph"));
|
|
2298
|
+
if (this.spec.shape !== "path") {
|
|
2299
|
+
if ("morphTo" in top) console.warn(`pixi-effects: ${who}: morphTo only works on a path shape (shape: 'path'); ignored`);
|
|
2300
|
+
return null;
|
|
2301
|
+
}
|
|
2302
|
+
if (top.morphTo === void 0) {
|
|
2303
|
+
if (wanted) console.warn(`pixi-effects: ${who}: morph needs morphTo (the outline to morph into); ignored`);
|
|
2304
|
+
return null;
|
|
2305
|
+
}
|
|
2306
|
+
let points2 = 128;
|
|
2307
|
+
if (top.morphPoints !== void 0) {
|
|
2308
|
+
const n = Number(top.morphPoints);
|
|
2309
|
+
if (Number.isInteger(n) && n >= 8 && n <= 2048) points2 = n;
|
|
2310
|
+
else console.warn(`pixi-effects: ${who}: morphPoints must be a whole number from 8 to 2048, got ${String(top.morphPoints)}; using 128`);
|
|
2311
|
+
}
|
|
2312
|
+
const pairs = buildMorph(flattenSvgPath(this.spec.d), flattenSvgPath(String(top.morphTo)), points2);
|
|
2313
|
+
if (pairs.length === 0) {
|
|
2314
|
+
console.warn(`pixi-effects: ${who}: morphTo "${String(top.morphTo)}" (or d) draws nothing, so there is nothing to morph; ignored`);
|
|
2315
|
+
return null;
|
|
2316
|
+
}
|
|
2317
|
+
this._state.morph ??= 0;
|
|
2318
|
+
return { pairs, to: String(top.morphTo) };
|
|
2319
|
+
}
|
|
2160
2320
|
_fresh = false;
|
|
2161
2321
|
_outline = null;
|
|
2162
2322
|
_redraw() {
|
|
@@ -2391,7 +2551,7 @@ var STATE_DRAWERS = {
|
|
|
2391
2551
|
ellipse: drawEllipseFromState,
|
|
2392
2552
|
arc: drawArcFromState
|
|
2393
2553
|
};
|
|
2394
|
-
function makeDrawGeometry(spec, scope, state) {
|
|
2554
|
+
function makeDrawGeometry(spec, scope, state, morph) {
|
|
2395
2555
|
const stateDrawer = STATE_DRAWERS[spec.shape];
|
|
2396
2556
|
if (stateDrawer) return (g) => stateDrawer(g, state);
|
|
2397
2557
|
switch (spec.shape) {
|
|
@@ -2399,13 +2559,30 @@ function makeDrawGeometry(spec, scope, state) {
|
|
|
2399
2559
|
return makeLineDraw(spec, scope);
|
|
2400
2560
|
case "polygon":
|
|
2401
2561
|
return makePolygonDraw(spec, scope);
|
|
2402
|
-
case "path":
|
|
2403
|
-
|
|
2562
|
+
case "path": {
|
|
2563
|
+
const plain = makePathDraw(spec);
|
|
2564
|
+
if (!morph) return plain;
|
|
2565
|
+
const last = makePathDraw({ ...spec, d: morph.to });
|
|
2566
|
+
return (g) => {
|
|
2567
|
+
const t = state.morph ?? 0;
|
|
2568
|
+
if (t <= 0) plain(g);
|
|
2569
|
+
else if (t >= 1) last(g);
|
|
2570
|
+
else for (const part of morphAt(morph.pairs, t)) drawPolyline(g, part);
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2404
2573
|
}
|
|
2405
2574
|
return () => {
|
|
2406
2575
|
};
|
|
2407
2576
|
}
|
|
2408
|
-
function
|
|
2577
|
+
function drawPolyline(g, part) {
|
|
2578
|
+
if (part.closed) {
|
|
2579
|
+
g.poly(part.pts, true);
|
|
2580
|
+
return;
|
|
2581
|
+
}
|
|
2582
|
+
g.moveTo(part.pts[0], part.pts[1]);
|
|
2583
|
+
for (let i = 2; i < part.pts.length; i += 2) g.lineTo(part.pts[i], part.pts[i + 1]);
|
|
2584
|
+
}
|
|
2585
|
+
function makeOutline(spec, scope, s, morph) {
|
|
2409
2586
|
switch (spec.shape) {
|
|
2410
2587
|
case "rect":
|
|
2411
2588
|
return () => {
|
|
@@ -2433,6 +2610,7 @@ function makeOutline(spec, scope, s) {
|
|
|
2433
2610
|
return () => lines;
|
|
2434
2611
|
}
|
|
2435
2612
|
case "path": {
|
|
2613
|
+
if (morph) return () => morphAt(morph.pairs, s.morph ?? 0);
|
|
2436
2614
|
let lines = null;
|
|
2437
2615
|
return () => lines ??= flattenSvgPath(spec.d);
|
|
2438
2616
|
}
|
|
@@ -2513,7 +2691,7 @@ function numOrZero(v, scope) {
|
|
|
2513
2691
|
var _CompositionSequence = null;
|
|
2514
2692
|
async function getCompositionSequence() {
|
|
2515
2693
|
if (!_CompositionSequence) {
|
|
2516
|
-
_CompositionSequence = (await import('./Composition-
|
|
2694
|
+
_CompositionSequence = (await import('./Composition-HIISJAX2.js')).CompositionSequence;
|
|
2517
2695
|
}
|
|
2518
2696
|
return _CompositionSequence;
|
|
2519
2697
|
}
|
|
@@ -2523,7 +2701,8 @@ var staticTypes = {
|
|
|
2523
2701
|
audio: AudioSequence,
|
|
2524
2702
|
video: VideoSequence,
|
|
2525
2703
|
shape: ShapeSequence,
|
|
2526
|
-
camera: CameraSequence
|
|
2704
|
+
camera: CameraSequence,
|
|
2705
|
+
null: NullSequence
|
|
2527
2706
|
};
|
|
2528
2707
|
var registry2 = {};
|
|
2529
2708
|
function registerSequenceType(type, ctor) {
|
|
@@ -2550,6 +2729,6 @@ async function buildSequenceTree(specs, parent, root) {
|
|
|
2550
2729
|
return out;
|
|
2551
2730
|
}
|
|
2552
2731
|
|
|
2553
|
-
export { CameraSequence, DEFAULT_FOV, DEG, NEAR, Sequence, buildScope, buildSequenceTree, cameraBasis, collectPropKeys, describeLayer, ensureFilterLibrary, evaluateExpr, homeCamera, homeDistance, lintText, lintTiming, projectLayer, registerSequenceType, resolveAt, summarizeWarnings };
|
|
2554
|
-
//# sourceMappingURL=chunk-
|
|
2555
|
-
//# sourceMappingURL=chunk-
|
|
2732
|
+
export { CameraSequence, DEFAULT_FOV, DEG, NEAR, NullSequence, Sequence, buildScope, buildSequenceTree, cameraBasis, collectPropKeys, describeLayer, ensureFilterLibrary, evaluateExpr, flattenSvgPath, homeCamera, homeDistance, lintText, lintTiming, noise, projectLayer, rand, random, registerSequenceType, resolveAt, summarizeWarnings };
|
|
2733
|
+
//# sourceMappingURL=chunk-C6QHKYC5.js.map
|
|
2734
|
+
//# sourceMappingURL=chunk-C6QHKYC5.js.map
|