pixi-effects 0.5.0 → 0.7.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 +30 -0
- package/README.md +17 -10
- package/ai/SKILL.md +1 -1
- package/ai/reference/cheatsheet.md +8 -2
- package/ai/reference/pitfalls.md +1 -0
- package/ai/reference/recipes.md +36 -1
- package/ai/template.html +4 -3
- package/ai/tools/check.mjs +14 -5
- package/ai/tools/render.mjs +202 -0
- package/ai/tools/view.mjs +269 -0
- package/dist/{Base-DnRAxroQ.d.cts → Base-CSIulyIq.d.cts} +1 -1
- package/dist/{Base-CPSFBkPm.d.ts → Base-DVgwyIUj.d.ts} +1 -1
- package/dist/Composition-3KHQPRBA.cjs +14 -0
- package/dist/{Composition-63EXHNJJ.cjs.map → Composition-3KHQPRBA.cjs.map} +1 -1
- package/dist/Composition-DT657FO5.js +5 -0
- package/dist/{Composition-TUCRSMJU.js.map → Composition-DT657FO5.js.map} +1 -1
- package/dist/Controller.cjs +77 -2
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +16 -2
- package/dist/Controller.d.ts +16 -2
- package/dist/Controller.js +77 -2
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-CuU_aaCm.d.cts → Movie-B0OUKlZI.d.ts} +54 -2
- package/dist/{Movie-VyDiUYOj.d.ts → Movie-BK9daiTt.d.cts} +54 -2
- package/dist/{chunk-5Q5XZG7Z.js → chunk-36Z4RIRK.js} +3 -3
- package/dist/{chunk-5Q5XZG7Z.js.map → chunk-36Z4RIRK.js.map} +1 -1
- package/dist/{chunk-UBPZLGLU.js → chunk-4O2NYDJG.js} +365 -44
- package/dist/chunk-4O2NYDJG.js.map +1 -0
- package/dist/{chunk-23M5QTWW.cjs → chunk-4VSIJLU3.cjs} +21 -21
- package/dist/{chunk-23M5QTWW.cjs.map → chunk-4VSIJLU3.cjs.map} +1 -1
- package/dist/{chunk-2RR43OIN.cjs → chunk-6I55T4OH.cjs} +403 -62
- package/dist/chunk-6I55T4OH.cjs.map +1 -0
- package/dist/index.cjs +234 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +226 -16
- package/dist/index.js.map +1 -1
- package/dist/three.cjs +6 -5
- package/dist/three.cjs.map +1 -1
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +2 -1
- package/dist/three.js.map +1 -1
- package/dist/{types-7VtTEKUW.d.ts → types-oJijbn-K.d.cts} +36 -7
- package/dist/{types-7VtTEKUW.d.cts → types-oJijbn-K.d.ts} +36 -7
- package/docs/api.md +7 -0
- package/docs/dsl.md +74 -8
- package/llms-full.txt +127 -12
- package/package.json +7 -4
- package/dist/Composition-63EXHNJJ.cjs +0 -13
- package/dist/Composition-TUCRSMJU.js +0 -4
- package/dist/chunk-2RR43OIN.cjs.map +0 -1
- package/dist/chunk-UBPZLGLU.js.map +0 -1
package/dist/three.cjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk6I55T4OH_cjs = require('./chunk-6I55T4OH.cjs');
|
|
4
|
+
require('./chunk-UQBGW5DO.cjs');
|
|
4
5
|
var pixi_js = require('pixi.js');
|
|
5
6
|
var three$1 = require('three');
|
|
6
7
|
|
|
7
|
-
var ThreeSequence = class extends
|
|
8
|
+
var ThreeSequence = class extends chunk6I55T4OH_cjs.Sequence {
|
|
8
9
|
_renderer = null;
|
|
9
10
|
_scene = null;
|
|
10
11
|
_camera = null;
|
|
@@ -23,7 +24,7 @@ var ThreeSequence = class extends chunk2RR43OIN_cjs.Sequence {
|
|
|
23
24
|
if (this.duration === void 0) {
|
|
24
25
|
this.duration = this.parent?.duration ?? this.root.duration;
|
|
25
26
|
}
|
|
26
|
-
const scope =
|
|
27
|
+
const scope = chunk6I55T4OH_cjs.buildScope(this, this.parent, this.root);
|
|
27
28
|
const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;
|
|
28
29
|
const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;
|
|
29
30
|
const resolution = spec.resolution ?? 1;
|
|
@@ -143,12 +144,12 @@ var ThreeSequence = class extends chunk2RR43OIN_cjs.Sequence {
|
|
|
143
144
|
function resolveDim(v, scope) {
|
|
144
145
|
if (v === void 0) return void 0;
|
|
145
146
|
if (typeof v === "number") return v;
|
|
146
|
-
return
|
|
147
|
+
return chunk6I55T4OH_cjs.evaluateExpr(v, scope);
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
// src/three/index.ts
|
|
150
151
|
function registerThree() {
|
|
151
|
-
|
|
152
|
+
chunk6I55T4OH_cjs.registerSequenceType("three", ThreeSequence);
|
|
152
153
|
}
|
|
153
154
|
function three(spec) {
|
|
154
155
|
return spec;
|
package/dist/three.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/three/ThreeSequence.ts","../src/three/index.ts"],"names":["Sequence","buildScope","WebGLRenderer","Scene","PerspectiveCamera","Texture","Sprite","evaluateExpr","registerSequenceType"],"mappings":";;;;;;AASO,IAAM,aAAA,GAAN,cAA4BA,0BAAA,CAAS;AAAA,EAClC,SAAA,GAAkC,IAAA;AAAA,EAClC,MAAA,GAAuB,IAAA;AAAA,EACvB,OAAA,GAAyB,IAAA;AAAA,EACzB,IAAA,GAA4B,IAAA;AAAA,EAC5B,WAAmC,EAAC;AAAA,EACpC,aAAA,GAAgB,KAAA;AAAA,EAChB,YAAA,uBAAmB,GAAA,EAAY;AAAA,EAEvC,IAAY,UAAA,GAAgC;AAC1C,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA,EAEmB,WAAA,GAA2B;AAC5C,IAAA,OAAO,EAAE,KAAA,EAAO,CAAC,SAAS,IAAA,CAAK,iBAAA,CAAkB,IAAI,CAAA,EAAE;AAAA,EACzD;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,IAAI,IAAA,CAAK,aAAa,MAAA,EAAW;AAC/B,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,MAAA,EAAQ,QAAA,IAAY,KAAK,IAAA,CAAK,QAAA;AAAA,IACrD;AAIA,IAAA,MAAM,QAAQC,4BAAA,CAAW,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,KAAK,IAAI,CAAA;AACrD,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,KAAA,EAAO,KAAK,KAAK,IAAA,CAAK,MAAA,EAAQ,KAAA,IAAS,IAAA,CAAK,IAAA,CAAK,KAAA;AAC/E,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,MAAA,EAAQ,KAAK,KAAK,IAAA,CAAK,MAAA,EAAQ,MAAA,IAAU,IAAA,CAAK,IAAA,CAAK,MAAA;AAClF,IAAA,MAAM,UAAA,GAAa,KAAK,UAAA,IAAc,CAAA;AAItC,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAM,QAAA,GAAW,IAAIC,qBAAA,CAAc,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,CAAA;AAC3E,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AACjB,IAAA,IAAI;AACF,MAAA,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,UAAU,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,UAAU,CAAA,EAAG,KAAK,CAAA;AACvF,MAAA,QAAA,CAAS,aAAA,CAAc,GAAU,CAAC,CAAA;AAElC,MAAA,MAAM,KAAA,GAAQ,IAAIC,aAAA,EAAM;AACxB,MAAA,MAAM,SAAiB,IAAIC,yBAAA,CAAkB,IAAI,KAAA,GAAQ,MAAA,EAAQ,KAAK,GAAI,CAAA;AAC1E,MAAA,MAAM,MAAoB,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAA,EAAU,OAAO,MAAA,EAAO;AAEnE,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACnC,MAAA,IAAI,MAAA,EAAQ,MAAA,EAAQ,GAAA,CAAI,MAAA,GAAS,MAAA,CAAO,MAAA;AACxC,MAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,MAAA,IAAA,CAAK,UAAU,GAAA,CAAI,MAAA;AACnB,MAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AACZ,MAAA,IAAA,CAAK,WAAW,EAAE,GAAI,MAAA,EAAQ,OAAA,IAAW,EAAC,EAAG;AAC7C,MAAA,IAAI,EAAE,QAAA,IAAY,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA,CAAS,SAAS,IAAA,CAAK,OAAA;AAG9D,MAAA,QAAA,CAAS,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAEnC,MAAA,MAAM,OAAA,GAAUC,eAAA,CAAQ,IAAA,CAAK,MAAM,CAAA;AACnC,MAAA,MAAM,MAAA,GAAS,IAAIC,cAAA,CAAO,EAAE,SAAS,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA;AACvD,MAAA,MAAA,CAAO,QAAA,GAAW,IAAA;AAElB,MAAA,MAAA,CAAO,KAAA,GAAQ,KAAA;AACf,MAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,MAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,MAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,MAAA,IAAA,CAAK,eAAA,GAAkB,MAAA;AACvB,MAAA,IAAA,CAAK,YAAA,EAAa;AAAA,IACpB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,gBAAA,EAAiB;AACtB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,KAAA,EAA8B;AAC/C,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,IAAa,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,IAAA,EAAM;AACpE,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,KAAA,EAAO,IAAA,CAAK,QAAA,IAAY,KAAK,CAAC,CAAA;AAC7D,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,MAAA,CAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA;AAAA,MAC1B,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,UAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,UAAA,OAAA,CAAQ,IAAA,CAAK,6DAAwD,GAAG,CAAA;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,KAAK,OAAO,CAAA;AAC/C,IAAC,IAAA,CAAK,MAAA,EAA0B,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAO;AAAA,EACxD;AAAA,EAEQ,kBAAkB,IAAA,EAAuD;AAC/E,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC3B,IAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,MAAA,IAAA,CAAK,SAAA,CAAU,MAAM,gCAAgC,CAAA;AACrD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,GAAA,GAAe,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,CAAC,CAAE,CAAA;AACzC,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,IAAA,CAAK,UAAU,IAAA,EAAM,CAAA,gBAAA,EAAmB,IAAA,CAAK,CAAC,CAAC,CAAA,0CAAA,CAAuC,CAAA;AACtF,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACxC,MAAA,GAAA,GAAO,GAAA,CAAgC,IAAA,CAAK,CAAC,CAAE,CAAA;AAC/C,MAAA,IAAI,OAAO,IAAA,EAAM;AACf,QAAA,IAAA,CAAK,UAAU,IAAA,EAAM,CAAA,CAAA,EAAI,IAAA,CAAK,CAAC,CAAC,CAAA,6BAAA,CAA+B,CAAA;AAC/D,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AACjC,IAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,EAAE,QAAS,GAAA,CAAA,EAAiB;AACzD,MAAA,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,CAAA,aAAA,EAAgB,IAAI,CAAA,CAAA,CAAG,CAAA;AAC5C,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,EAAE,MAAA,EAAQ,GAAA,EAAe,IAAA,EAAK;AAAA,EACvC;AAAA,EAEQ,SAAA,CAAU,MAAc,GAAA,EAAmB;AACjD,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA,EAAG;AACjC,IAAA,IAAA,CAAK,YAAA,CAAa,IAAI,IAAI,CAAA;AAC1B,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,SAAA,CAAW,CAAA;AAAA,EAC1E;AAAA,EAEQ,gBAAA,GAAyB;AAC/B,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACrB,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,UAAU,OAAA,EAAQ;AACvB,MAAA,IAAA,CAAK,UAAU,gBAAA,EAAiB;AAAA,IAClC,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,IAAA,CAAK,qDAAgD,GAAG,CAAA;AAAA,IAClE;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA,EAES,OAAA,GAAgB;AACvB,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,IAAI,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,OAAA,EAAS;AAC7B,MAAA,IAAI;AAAE,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,MAAG,SAAS,GAAA,EAAK;AAC3C,QAAA,OAAA,CAAQ,IAAA,CAAK,8CAAyC,GAAG,CAAA;AAAA,MAC3D;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAW,KAAK,MAAA,EAA0B,OAAA;AAChD,IAAA,IAAA,CAAK,gBAAA,EAAiB;AACtB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,WAAW,EAAC;AACjB,IAAA,KAAA,CAAM,OAAA,EAAQ;AACd,IAAA,OAAA,EAAS,QAAQ,IAAI,CAAA;AAAA,EACvB;AACF;AAEA,SAAS,UAAA,CAAW,GAA0B,KAAA,EAAmD;AAC/F,EAAA,IAAI,CAAA,KAAM,QAAW,OAAO,MAAA;AAC5B,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAClC,EAAA,OAAOC,8BAAA,CAAa,GAAG,KAAK,CAAA;AAC9B;;;ACxJO,SAAS,aAAA,GAAsB;AACpC,EAAAC,sCAAA,CAAqB,SAAS,aAAwC,CAAA;AACxE;AAMO,SAAS,MAAM,IAAA,EAAuC;AAC3D,EAAA,OAAO,IAAA;AACT","file":"three.cjs","sourcesContent":["import { Sprite, Texture } from 'pixi.js';\nimport { PerspectiveCamera, Scene, WebGLRenderer, type Camera } from 'three';\nimport { Sequence } from '../sequences/Base';\nimport { buildScope } from '../expr/Scope';\nimport { evaluateExpr } from '../expr/Parser';\nimport type { PathRouters } from '../core/Timeline';\nimport type { PropValue } from '../types';\nimport type { ThreeContext, ThreeSequenceSpec } from './types';\n\nexport class ThreeSequence extends Sequence {\n private _renderer: WebGLRenderer | null = null;\n private _scene: Scene | null = null;\n private _camera: Camera | null = null;\n private _ctx: ThreeContext | null = null;\n private _objects: Record<string, object> = {};\n private _warnedUpdate = false;\n private _warnedPaths = new Set<string>();\n\n private get _threeSpec(): ThreeSequenceSpec {\n return this.spec as unknown as ThreeSequenceSpec;\n }\n\n protected override pathRouters(): PathRouters {\n return { three: (path) => this._resolveThreePath(path) };\n }\n\n async build(): Promise<void> {\n const spec = this._threeSpec;\n if (this.duration === undefined) {\n this.duration = this.parent?.duration ?? this.root.duration;\n }\n\n // Resolve layer size. Expressions see the usual scope; intrinsic w/h are\n // still 0 here (same chicken-and-egg as shapes), so W/H/GW/GH carry it.\n const scope = buildScope(this, this.parent, this.root) as unknown as Record<string, number>;\n const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;\n const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;\n const resolution = spec.resolution ?? 1;\n\n // Offscreen canvas — never attached to the DOM. document.createElement\n // (not OffscreenCanvas) so PIXI's Texture.from and three both accept it.\n const canvas = document.createElement('canvas');\n const renderer = new WebGLRenderer({ canvas, alpha: true, antialias: true });\n this._renderer = renderer;\n try {\n renderer.setSize(Math.round(width * resolution), Math.round(height * resolution), false);\n renderer.setClearColor(0x000000, 0);\n\n const scene = new Scene();\n const camera: Camera = new PerspectiveCamera(50, width / height, 0.1, 2000);\n const ctx: ThreeContext = { scene, camera, renderer, width, height };\n\n const result = await spec.setup(ctx);\n if (result?.camera) ctx.camera = result.camera;\n this._scene = scene;\n this._camera = ctx.camera;\n this._ctx = ctx;\n this._objects = { ...(result?.objects ?? {}) };\n if (!('camera' in this._objects)) this._objects.camera = this._camera;\n\n // Frame 0 so the texture is never blank before the first tick.\n renderer.render(scene, this._camera);\n\n const texture = Texture.from(canvas);\n const sprite = new Sprite({ texture, label: spec.name });\n sprite.cullable = true;\n // Texture is canvas-sized (layer px × resolution); scale back to comp px.\n sprite.width = width;\n sprite.height = height;\n this.target = sprite;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this.buildFilters();\n } catch (err) {\n this._disposeRenderer();\n throw err;\n }\n }\n\n /**\n * Per-frame sync hook. Movie._awaitVideoFrames duck-types on this method\n * (same contract as VideoSequence) and awaits it inside gotoFrame — the\n * single frame path shared by playback and export, which is what makes\n * three layers deterministic in both.\n */\n async awaitFrameAt(local: number): Promise<void> {\n if (!this._renderer || !this._scene || !this._camera || !this._ctx) return;\n const spec = this._threeSpec;\n const t = Math.max(0, Math.min(local, this.duration ?? local));\n if (spec.update) {\n try {\n spec.update(t, this._ctx);\n } catch (err) {\n if (!this._warnedUpdate) {\n this._warnedUpdate = true;\n console.warn('pixi-effects: three update() threw (reported once) —', err);\n }\n }\n }\n this._renderer.render(this._scene, this._camera);\n (this.target as Sprite | null)?.texture.source.update();\n }\n\n private _resolveThreePath(path: string): { target: object; prop: string } | null {\n const segs = path.split('.');\n if (segs.length < 2) {\n this._warnPath(path, 'needs at least <object>.<prop>');\n return null;\n }\n let obj: unknown = this._objects[segs[0]!];\n if (obj == null) {\n this._warnPath(path, `unknown object \"${segs[0]}\" — expose it via setup's { objects }`);\n return null;\n }\n for (let i = 1; i < segs.length - 1; i++) {\n obj = (obj as Record<string, unknown>)[segs[i]!];\n if (obj == null) {\n this._warnPath(path, `\"${segs[i]}\" is undefined along the path`);\n return null;\n }\n }\n const prop = segs[segs.length - 1]!;\n if (typeof obj !== 'object' || !(prop in (obj as object))) {\n this._warnPath(path, `no property \"${prop}\"`);\n return null;\n }\n return { target: obj as object, prop };\n }\n\n private _warnPath(path: string, why: string): void {\n if (this._warnedPaths.has(path)) return;\n this._warnedPaths.add(path);\n console.warn(`pixi-effects: keyframe path three.${path} ${why}; skipped`);\n }\n\n private _disposeRenderer(): void {\n if (!this._renderer) return;\n try {\n this._renderer.dispose();\n this._renderer.forceContextLoss();\n } catch (err) {\n console.warn('pixi-effects: three renderer dispose threw —', err);\n }\n this._renderer = null;\n }\n\n override destroy(): void {\n const spec = this._threeSpec;\n if (this._ctx && spec.dispose) {\n try { spec.dispose(this._ctx); } catch (err) {\n console.warn('pixi-effects: three dispose() threw —', err);\n }\n }\n const texture = (this.target as Sprite | null)?.texture;\n this._disposeRenderer();\n this._scene = null;\n this._camera = null;\n this._ctx = null;\n this._objects = {};\n super.destroy();\n texture?.destroy(true); // canvas-backed source is per-sequence; safe to kill\n }\n}\n\nfunction resolveDim(v: PropValue | undefined, scope: Record<string, number>): number | undefined {\n if (v === undefined) return undefined;\n if (typeof v === 'number') return v;\n return evaluateExpr(v, scope);\n}\n","/**\n * pixi-effects/three — optional three.js integration.\n *\n * Import this entry only when you use `type: 'three'` sequences; the core\n * `pixi-effects` entry never touches three.js. Call `registerThree()` once\n * before Movie.init builds a composition containing a three sequence.\n */\nimport { registerSequenceType, type SequenceCtor } from '../core/Composition';\nimport { ThreeSequence } from './ThreeSequence';\nimport type { SequenceSpec } from '../types';\nimport type { ThreeSequenceSpec } from './types';\n\nexport { ThreeSequence } from './ThreeSequence';\nexport type { ThreeContext, ThreeSetupResult, ThreeSequenceSpec } from './types';\n\n/** Register the 'three' sequence type. Idempotent; explicit call so `sideEffects: false` bundlers can't drop it. */\nexport function registerThree(): void {\n registerSequenceType('three', ThreeSequence as unknown as SequenceCtor);\n}\n\n/**\n * Typing helper: accepts a strongly-typed three spec and returns it as a\n * core SequenceSpec, keeping three.js types out of the core union.\n */\nexport function three(spec: ThreeSequenceSpec): SequenceSpec {\n return spec as unknown as SequenceSpec;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/three/ThreeSequence.ts","../src/three/index.ts"],"names":["Sequence","buildScope","WebGLRenderer","Scene","PerspectiveCamera","Texture","Sprite","evaluateExpr","registerSequenceType"],"mappings":";;;;;;;AASO,IAAM,aAAA,GAAN,cAA4BA,0BAAA,CAAS;AAAA,EAClC,SAAA,GAAkC,IAAA;AAAA,EAClC,MAAA,GAAuB,IAAA;AAAA,EACvB,OAAA,GAAyB,IAAA;AAAA,EACzB,IAAA,GAA4B,IAAA;AAAA,EAC5B,WAAmC,EAAC;AAAA,EACpC,aAAA,GAAgB,KAAA;AAAA,EAChB,YAAA,uBAAmB,GAAA,EAAY;AAAA,EAEvC,IAAY,UAAA,GAAgC;AAC1C,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA,EAEmB,WAAA,GAA2B;AAC5C,IAAA,OAAO,EAAE,KAAA,EAAO,CAAC,SAAS,IAAA,CAAK,iBAAA,CAAkB,IAAI,CAAA,EAAE;AAAA,EACzD;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,IAAI,IAAA,CAAK,aAAa,MAAA,EAAW;AAC/B,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,MAAA,EAAQ,QAAA,IAAY,KAAK,IAAA,CAAK,QAAA;AAAA,IACrD;AAIA,IAAA,MAAM,QAAQC,4BAAA,CAAW,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,KAAK,IAAI,CAAA;AACrD,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,KAAA,EAAO,KAAK,KAAK,IAAA,CAAK,MAAA,EAAQ,KAAA,IAAS,IAAA,CAAK,IAAA,CAAK,KAAA;AAC/E,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,MAAA,EAAQ,KAAK,KAAK,IAAA,CAAK,MAAA,EAAQ,MAAA,IAAU,IAAA,CAAK,IAAA,CAAK,MAAA;AAClF,IAAA,MAAM,UAAA,GAAa,KAAK,UAAA,IAAc,CAAA;AAItC,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAM,QAAA,GAAW,IAAIC,qBAAA,CAAc,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,CAAA;AAC3E,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AACjB,IAAA,IAAI;AACF,MAAA,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,UAAU,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,UAAU,CAAA,EAAG,KAAK,CAAA;AACvF,MAAA,QAAA,CAAS,aAAA,CAAc,GAAU,CAAC,CAAA;AAElC,MAAA,MAAM,KAAA,GAAQ,IAAIC,aAAA,EAAM;AACxB,MAAA,MAAM,SAAiB,IAAIC,yBAAA,CAAkB,IAAI,KAAA,GAAQ,MAAA,EAAQ,KAAK,GAAI,CAAA;AAC1E,MAAA,MAAM,MAAoB,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAA,EAAU,OAAO,MAAA,EAAO;AAEnE,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACnC,MAAA,IAAI,MAAA,EAAQ,MAAA,EAAQ,GAAA,CAAI,MAAA,GAAS,MAAA,CAAO,MAAA;AACxC,MAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,MAAA,IAAA,CAAK,UAAU,GAAA,CAAI,MAAA;AACnB,MAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AACZ,MAAA,IAAA,CAAK,WAAW,EAAE,GAAI,MAAA,EAAQ,OAAA,IAAW,EAAC,EAAG;AAC7C,MAAA,IAAI,EAAE,QAAA,IAAY,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA,CAAS,SAAS,IAAA,CAAK,OAAA;AAG9D,MAAA,QAAA,CAAS,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAEnC,MAAA,MAAM,OAAA,GAAUC,eAAA,CAAQ,IAAA,CAAK,MAAM,CAAA;AACnC,MAAA,MAAM,MAAA,GAAS,IAAIC,cAAA,CAAO,EAAE,SAAS,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA;AACvD,MAAA,MAAA,CAAO,QAAA,GAAW,IAAA;AAElB,MAAA,MAAA,CAAO,KAAA,GAAQ,KAAA;AACf,MAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,MAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,MAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,MAAA,IAAA,CAAK,eAAA,GAAkB,MAAA;AACvB,MAAA,IAAA,CAAK,YAAA,EAAa;AAAA,IACpB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,gBAAA,EAAiB;AACtB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,KAAA,EAA8B;AAC/C,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,IAAa,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,IAAA,EAAM;AACpE,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,KAAA,EAAO,IAAA,CAAK,QAAA,IAAY,KAAK,CAAC,CAAA;AAC7D,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,MAAA,CAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA;AAAA,MAC1B,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,UAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,UAAA,OAAA,CAAQ,IAAA,CAAK,6DAAwD,GAAG,CAAA;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,KAAK,OAAO,CAAA;AAC/C,IAAC,IAAA,CAAK,MAAA,EAA0B,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAO;AAAA,EACxD;AAAA,EAEQ,kBAAkB,IAAA,EAAuD;AAC/E,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC3B,IAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,MAAA,IAAA,CAAK,SAAA,CAAU,MAAM,gCAAgC,CAAA;AACrD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,GAAA,GAAe,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,CAAC,CAAE,CAAA;AACzC,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,IAAA,CAAK,UAAU,IAAA,EAAM,CAAA,gBAAA,EAAmB,IAAA,CAAK,CAAC,CAAC,CAAA,0CAAA,CAAuC,CAAA;AACtF,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACxC,MAAA,GAAA,GAAO,GAAA,CAAgC,IAAA,CAAK,CAAC,CAAE,CAAA;AAC/C,MAAA,IAAI,OAAO,IAAA,EAAM;AACf,QAAA,IAAA,CAAK,UAAU,IAAA,EAAM,CAAA,CAAA,EAAI,IAAA,CAAK,CAAC,CAAC,CAAA,6BAAA,CAA+B,CAAA;AAC/D,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AACjC,IAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,EAAE,QAAS,GAAA,CAAA,EAAiB;AACzD,MAAA,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,CAAA,aAAA,EAAgB,IAAI,CAAA,CAAA,CAAG,CAAA;AAC5C,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,EAAE,MAAA,EAAQ,GAAA,EAAe,IAAA,EAAK;AAAA,EACvC;AAAA,EAEQ,SAAA,CAAU,MAAc,GAAA,EAAmB;AACjD,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA,EAAG;AACjC,IAAA,IAAA,CAAK,YAAA,CAAa,IAAI,IAAI,CAAA;AAC1B,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,SAAA,CAAW,CAAA;AAAA,EAC1E;AAAA,EAEQ,gBAAA,GAAyB;AAC/B,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACrB,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,UAAU,OAAA,EAAQ;AACvB,MAAA,IAAA,CAAK,UAAU,gBAAA,EAAiB;AAAA,IAClC,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,IAAA,CAAK,qDAAgD,GAAG,CAAA;AAAA,IAClE;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA,EAES,OAAA,GAAgB;AACvB,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,IAAI,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,OAAA,EAAS;AAC7B,MAAA,IAAI;AAAE,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,MAAG,SAAS,GAAA,EAAK;AAC3C,QAAA,OAAA,CAAQ,IAAA,CAAK,8CAAyC,GAAG,CAAA;AAAA,MAC3D;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAW,KAAK,MAAA,EAA0B,OAAA;AAChD,IAAA,IAAA,CAAK,gBAAA,EAAiB;AACtB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,WAAW,EAAC;AACjB,IAAA,KAAA,CAAM,OAAA,EAAQ;AACd,IAAA,OAAA,EAAS,QAAQ,IAAI,CAAA;AAAA,EACvB;AACF;AAEA,SAAS,UAAA,CAAW,GAA0B,KAAA,EAAmD;AAC/F,EAAA,IAAI,CAAA,KAAM,QAAW,OAAO,MAAA;AAC5B,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAClC,EAAA,OAAOC,8BAAA,CAAa,GAAG,KAAK,CAAA;AAC9B;;;ACxJO,SAAS,aAAA,GAAsB;AACpC,EAAAC,sCAAA,CAAqB,SAAS,aAAwC,CAAA;AACxE;AAMO,SAAS,MAAM,IAAA,EAAuC;AAC3D,EAAA,OAAO,IAAA;AACT","file":"three.cjs","sourcesContent":["import { Sprite, Texture } from 'pixi.js';\nimport { PerspectiveCamera, Scene, WebGLRenderer, type Camera } from 'three';\nimport { Sequence } from '../sequences/Base';\nimport { buildScope } from '../expr/Scope';\nimport { evaluateExpr } from '../expr/Parser';\nimport type { PathRouters } from '../core/Timeline';\nimport type { PropValue } from '../types';\nimport type { ThreeContext, ThreeSequenceSpec } from './types';\n\nexport class ThreeSequence extends Sequence {\n private _renderer: WebGLRenderer | null = null;\n private _scene: Scene | null = null;\n private _camera: Camera | null = null;\n private _ctx: ThreeContext | null = null;\n private _objects: Record<string, object> = {};\n private _warnedUpdate = false;\n private _warnedPaths = new Set<string>();\n\n private get _threeSpec(): ThreeSequenceSpec {\n return this.spec as unknown as ThreeSequenceSpec;\n }\n\n protected override pathRouters(): PathRouters {\n return { three: (path) => this._resolveThreePath(path) };\n }\n\n async build(): Promise<void> {\n const spec = this._threeSpec;\n if (this.duration === undefined) {\n this.duration = this.parent?.duration ?? this.root.duration;\n }\n\n // Resolve layer size. Expressions see the usual scope; intrinsic w/h are\n // still 0 here (same chicken-and-egg as shapes), so W/H/GW/GH carry it.\n const scope = buildScope(this, this.parent, this.root) as unknown as Record<string, number>;\n const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;\n const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;\n const resolution = spec.resolution ?? 1;\n\n // Offscreen canvas — never attached to the DOM. document.createElement\n // (not OffscreenCanvas) so PIXI's Texture.from and three both accept it.\n const canvas = document.createElement('canvas');\n const renderer = new WebGLRenderer({ canvas, alpha: true, antialias: true });\n this._renderer = renderer;\n try {\n renderer.setSize(Math.round(width * resolution), Math.round(height * resolution), false);\n renderer.setClearColor(0x000000, 0);\n\n const scene = new Scene();\n const camera: Camera = new PerspectiveCamera(50, width / height, 0.1, 2000);\n const ctx: ThreeContext = { scene, camera, renderer, width, height };\n\n const result = await spec.setup(ctx);\n if (result?.camera) ctx.camera = result.camera;\n this._scene = scene;\n this._camera = ctx.camera;\n this._ctx = ctx;\n this._objects = { ...(result?.objects ?? {}) };\n if (!('camera' in this._objects)) this._objects.camera = this._camera;\n\n // Frame 0 so the texture is never blank before the first tick.\n renderer.render(scene, this._camera);\n\n const texture = Texture.from(canvas);\n const sprite = new Sprite({ texture, label: spec.name });\n sprite.cullable = true;\n // Texture is canvas-sized (layer px × resolution); scale back to comp px.\n sprite.width = width;\n sprite.height = height;\n this.target = sprite;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this.buildFilters();\n } catch (err) {\n this._disposeRenderer();\n throw err;\n }\n }\n\n /**\n * Per-frame sync hook. Movie._awaitVideoFrames duck-types on this method\n * (same contract as VideoSequence) and awaits it inside gotoFrame — the\n * single frame path shared by playback and export, which is what makes\n * three layers deterministic in both.\n */\n async awaitFrameAt(local: number): Promise<void> {\n if (!this._renderer || !this._scene || !this._camera || !this._ctx) return;\n const spec = this._threeSpec;\n const t = Math.max(0, Math.min(local, this.duration ?? local));\n if (spec.update) {\n try {\n spec.update(t, this._ctx);\n } catch (err) {\n if (!this._warnedUpdate) {\n this._warnedUpdate = true;\n console.warn('pixi-effects: three update() threw (reported once) —', err);\n }\n }\n }\n this._renderer.render(this._scene, this._camera);\n (this.target as Sprite | null)?.texture.source.update();\n }\n\n private _resolveThreePath(path: string): { target: object; prop: string } | null {\n const segs = path.split('.');\n if (segs.length < 2) {\n this._warnPath(path, 'needs at least <object>.<prop>');\n return null;\n }\n let obj: unknown = this._objects[segs[0]!];\n if (obj == null) {\n this._warnPath(path, `unknown object \"${segs[0]}\" — expose it via setup's { objects }`);\n return null;\n }\n for (let i = 1; i < segs.length - 1; i++) {\n obj = (obj as Record<string, unknown>)[segs[i]!];\n if (obj == null) {\n this._warnPath(path, `\"${segs[i]}\" is undefined along the path`);\n return null;\n }\n }\n const prop = segs[segs.length - 1]!;\n if (typeof obj !== 'object' || !(prop in (obj as object))) {\n this._warnPath(path, `no property \"${prop}\"`);\n return null;\n }\n return { target: obj as object, prop };\n }\n\n private _warnPath(path: string, why: string): void {\n if (this._warnedPaths.has(path)) return;\n this._warnedPaths.add(path);\n console.warn(`pixi-effects: keyframe path three.${path} ${why}; skipped`);\n }\n\n private _disposeRenderer(): void {\n if (!this._renderer) return;\n try {\n this._renderer.dispose();\n this._renderer.forceContextLoss();\n } catch (err) {\n console.warn('pixi-effects: three renderer dispose threw —', err);\n }\n this._renderer = null;\n }\n\n override destroy(): void {\n const spec = this._threeSpec;\n if (this._ctx && spec.dispose) {\n try { spec.dispose(this._ctx); } catch (err) {\n console.warn('pixi-effects: three dispose() threw —', err);\n }\n }\n const texture = (this.target as Sprite | null)?.texture;\n this._disposeRenderer();\n this._scene = null;\n this._camera = null;\n this._ctx = null;\n this._objects = {};\n super.destroy();\n texture?.destroy(true); // canvas-backed source is per-sequence; safe to kill\n }\n}\n\nfunction resolveDim(v: PropValue | undefined, scope: Record<string, number>): number | undefined {\n if (v === undefined) return undefined;\n if (typeof v === 'number') return v;\n return evaluateExpr(v, scope);\n}\n","/**\n * pixi-effects/three — optional three.js integration.\n *\n * Import this entry only when you use `type: 'three'` sequences; the core\n * `pixi-effects` entry never touches three.js. Call `registerThree()` once\n * before Movie.init builds a composition containing a three sequence.\n */\nimport { registerSequenceType, type SequenceCtor } from '../core/Composition';\nimport { ThreeSequence } from './ThreeSequence';\nimport type { SequenceSpec } from '../types';\nimport type { ThreeSequenceSpec } from './types';\n\nexport { ThreeSequence } from './ThreeSequence';\nexport type { ThreeContext, ThreeSetupResult, ThreeSequenceSpec } from './types';\n\n/** Register the 'three' sequence type. Idempotent; explicit call so `sideEffects: false` bundlers can't drop it. */\nexport function registerThree(): void {\n registerSequenceType('three', ThreeSequence as unknown as SequenceCtor);\n}\n\n/**\n * Typing helper: accepts a strongly-typed three spec and returns it as a\n * core SequenceSpec, keeping three.js types out of the core union.\n */\nexport function three(spec: ThreeSequenceSpec): SequenceSpec {\n return spec as unknown as SequenceSpec;\n}\n"]}
|
package/dist/three.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { b as SequenceCommon, q as PropValue, S as SequenceSpec } from './types-
|
|
1
|
+
import { b as SequenceCommon, q as PropValue, S as SequenceSpec } from './types-oJijbn-K.cjs';
|
|
2
2
|
import { Scene, Camera, WebGLRenderer } from 'three';
|
|
3
|
-
import { S as Sequence, P as PathRouters } from './Base-
|
|
3
|
+
import { S as Sequence, P as PathRouters } from './Base-CSIulyIq.cjs';
|
|
4
4
|
import 'pixi.js';
|
|
5
5
|
import 'gsap';
|
|
6
6
|
|
package/dist/three.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { b as SequenceCommon, q as PropValue, S as SequenceSpec } from './types-
|
|
1
|
+
import { b as SequenceCommon, q as PropValue, S as SequenceSpec } from './types-oJijbn-K.js';
|
|
2
2
|
import { Scene, Camera, WebGLRenderer } from 'three';
|
|
3
|
-
import { S as Sequence, P as PathRouters } from './Base-
|
|
3
|
+
import { S as Sequence, P as PathRouters } from './Base-DVgwyIUj.js';
|
|
4
4
|
import 'pixi.js';
|
|
5
5
|
import 'gsap';
|
|
6
6
|
|
package/dist/three.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Sequence, buildScope, evaluateExpr, registerSequenceType } from './chunk-
|
|
1
|
+
import { Sequence, buildScope, evaluateExpr, registerSequenceType } from './chunk-4O2NYDJG.js';
|
|
2
|
+
import './chunk-DKGG7WD4.js';
|
|
2
3
|
import { Texture, Sprite } from 'pixi.js';
|
|
3
4
|
import { WebGLRenderer, Scene, PerspectiveCamera } from 'three';
|
|
4
5
|
|
package/dist/three.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/three/ThreeSequence.ts","../src/three/index.ts"],"names":[],"mappings":";;;;AASO,IAAM,aAAA,GAAN,cAA4B,QAAA,CAAS;AAAA,EAClC,SAAA,GAAkC,IAAA;AAAA,EAClC,MAAA,GAAuB,IAAA;AAAA,EACvB,OAAA,GAAyB,IAAA;AAAA,EACzB,IAAA,GAA4B,IAAA;AAAA,EAC5B,WAAmC,EAAC;AAAA,EACpC,aAAA,GAAgB,KAAA;AAAA,EAChB,YAAA,uBAAmB,GAAA,EAAY;AAAA,EAEvC,IAAY,UAAA,GAAgC;AAC1C,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,EACd;AAAA,EAEmB,WAAA,GAA2B;AAC5C,IAAA,OAAO,EAAE,KAAA,EAAO,CAAC,SAAS,IAAA,CAAK,iBAAA,CAAkB,IAAI,CAAA,EAAE;AAAA,EACzD;AAAA,EAEA,MAAM,KAAA,GAAuB;AAC3B,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,IAAI,IAAA,CAAK,aAAa,MAAA,EAAW;AAC/B,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA,CAAK,MAAA,EAAQ,QAAA,IAAY,KAAK,IAAA,CAAK,QAAA;AAAA,IACrD;AAIA,IAAA,MAAM,QAAQ,UAAA,CAAW,IAAA,EAAM,IAAA,CAAK,MAAA,EAAQ,KAAK,IAAI,CAAA;AACrD,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,KAAA,EAAO,KAAK,KAAK,IAAA,CAAK,MAAA,EAAQ,KAAA,IAAS,IAAA,CAAK,IAAA,CAAK,KAAA;AAC/E,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,IAAA,CAAK,MAAA,EAAQ,KAAK,KAAK,IAAA,CAAK,MAAA,EAAQ,MAAA,IAAU,IAAA,CAAK,IAAA,CAAK,MAAA;AAClF,IAAA,MAAM,UAAA,GAAa,KAAK,UAAA,IAAc,CAAA;AAItC,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,IAAA,MAAM,QAAA,GAAW,IAAI,aAAA,CAAc,EAAE,QAAQ,KAAA,EAAO,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,CAAA;AAC3E,IAAA,IAAA,CAAK,SAAA,GAAY,QAAA;AACjB,IAAA,IAAI;AACF,MAAA,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,UAAU,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,UAAU,CAAA,EAAG,KAAK,CAAA;AACvF,MAAA,QAAA,CAAS,aAAA,CAAc,GAAU,CAAC,CAAA;AAElC,MAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,MAAA,MAAM,SAAiB,IAAI,iBAAA,CAAkB,IAAI,KAAA,GAAQ,MAAA,EAAQ,KAAK,GAAI,CAAA;AAC1E,MAAA,MAAM,MAAoB,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAA,EAAU,OAAO,MAAA,EAAO;AAEnE,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACnC,MAAA,IAAI,MAAA,EAAQ,MAAA,EAAQ,GAAA,CAAI,MAAA,GAAS,MAAA,CAAO,MAAA;AACxC,MAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,MAAA,IAAA,CAAK,UAAU,GAAA,CAAI,MAAA;AACnB,MAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AACZ,MAAA,IAAA,CAAK,WAAW,EAAE,GAAI,MAAA,EAAQ,OAAA,IAAW,EAAC,EAAG;AAC7C,MAAA,IAAI,EAAE,QAAA,IAAY,IAAA,CAAK,WAAW,IAAA,CAAK,QAAA,CAAS,SAAS,IAAA,CAAK,OAAA;AAG9D,MAAA,QAAA,CAAS,MAAA,CAAO,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAEnC,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAA;AACnC,MAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAO,EAAE,SAAS,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA;AACvD,MAAA,MAAA,CAAO,QAAA,GAAW,IAAA;AAElB,MAAA,MAAA,CAAO,KAAA,GAAQ,KAAA;AACf,MAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAChB,MAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,MAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,MAAA,IAAA,CAAK,eAAA,GAAkB,MAAA;AACvB,MAAA,IAAA,CAAK,YAAA,EAAa;AAAA,IACpB,SAAS,GAAA,EAAK;AACZ,MAAA,IAAA,CAAK,gBAAA,EAAiB;AACtB,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,KAAA,EAA8B;AAC/C,IAAA,IAAI,CAAC,IAAA,CAAK,SAAA,IAAa,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,IAAA,EAAM;AACpE,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,KAAA,EAAO,IAAA,CAAK,QAAA,IAAY,KAAK,CAAC,CAAA;AAC7D,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,MAAA,CAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA;AAAA,MAC1B,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,UAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,UAAA,OAAA,CAAQ,IAAA,CAAK,6DAAwD,GAAG,CAAA;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,KAAK,OAAO,CAAA;AAC/C,IAAC,IAAA,CAAK,MAAA,EAA0B,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAO;AAAA,EACxD;AAAA,EAEQ,kBAAkB,IAAA,EAAuD;AAC/E,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC3B,IAAA,IAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACnB,MAAA,IAAA,CAAK,SAAA,CAAU,MAAM,gCAAgC,CAAA;AACrD,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI,GAAA,GAAe,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,CAAC,CAAE,CAAA;AACzC,IAAA,IAAI,OAAO,IAAA,EAAM;AACf,MAAA,IAAA,CAAK,UAAU,IAAA,EAAM,CAAA,gBAAA,EAAmB,IAAA,CAAK,CAAC,CAAC,CAAA,0CAAA,CAAuC,CAAA;AACtF,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACxC,MAAA,GAAA,GAAO,GAAA,CAAgC,IAAA,CAAK,CAAC,CAAE,CAAA;AAC/C,MAAA,IAAI,OAAO,IAAA,EAAM;AACf,QAAA,IAAA,CAAK,UAAU,IAAA,EAAM,CAAA,CAAA,EAAI,IAAA,CAAK,CAAC,CAAC,CAAA,6BAAA,CAA+B,CAAA;AAC/D,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AACjC,IAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,EAAE,QAAS,GAAA,CAAA,EAAiB;AACzD,MAAA,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,CAAA,aAAA,EAAgB,IAAI,CAAA,CAAA,CAAG,CAAA;AAC5C,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,OAAO,EAAE,MAAA,EAAQ,GAAA,EAAe,IAAA,EAAK;AAAA,EACvC;AAAA,EAEQ,SAAA,CAAU,MAAc,GAAA,EAAmB;AACjD,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA,EAAG;AACjC,IAAA,IAAA,CAAK,YAAA,CAAa,IAAI,IAAI,CAAA;AAC1B,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kCAAA,EAAqC,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,SAAA,CAAW,CAAA;AAAA,EAC1E;AAAA,EAEQ,gBAAA,GAAyB;AAC/B,IAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACrB,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,UAAU,OAAA,EAAQ;AACvB,MAAA,IAAA,CAAK,UAAU,gBAAA,EAAiB;AAAA,IAClC,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,IAAA,CAAK,qDAAgD,GAAG,CAAA;AAAA,IAClE;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA,EAES,OAAA,GAAgB;AACvB,IAAA,MAAM,OAAO,IAAA,CAAK,UAAA;AAClB,IAAA,IAAI,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK,OAAA,EAAS;AAC7B,MAAA,IAAI;AAAE,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,MAAG,SAAS,GAAA,EAAK;AAC3C,QAAA,OAAA,CAAQ,IAAA,CAAK,8CAAyC,GAAG,CAAA;AAAA,MAC3D;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAW,KAAK,MAAA,EAA0B,OAAA;AAChD,IAAA,IAAA,CAAK,gBAAA,EAAiB;AACtB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,WAAW,EAAC;AACjB,IAAA,KAAA,CAAM,OAAA,EAAQ;AACd,IAAA,OAAA,EAAS,QAAQ,IAAI,CAAA;AAAA,EACvB;AACF;AAEA,SAAS,UAAA,CAAW,GAA0B,KAAA,EAAmD;AAC/F,EAAA,IAAI,CAAA,KAAM,QAAW,OAAO,MAAA;AAC5B,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA;AAClC,EAAA,OAAO,YAAA,CAAa,GAAG,KAAK,CAAA;AAC9B;;;ACxJO,SAAS,aAAA,GAAsB;AACpC,EAAA,oBAAA,CAAqB,SAAS,aAAwC,CAAA;AACxE;AAMO,SAAS,MAAM,IAAA,EAAuC;AAC3D,EAAA,OAAO,IAAA;AACT","file":"three.js","sourcesContent":["import { Sprite, Texture } from 'pixi.js';\nimport { PerspectiveCamera, Scene, WebGLRenderer, type Camera } from 'three';\nimport { Sequence } from '../sequences/Base';\nimport { buildScope } from '../expr/Scope';\nimport { evaluateExpr } from '../expr/Parser';\nimport type { PathRouters } from '../core/Timeline';\nimport type { PropValue } from '../types';\nimport type { ThreeContext, ThreeSequenceSpec } from './types';\n\nexport class ThreeSequence extends Sequence {\n private _renderer: WebGLRenderer | null = null;\n private _scene: Scene | null = null;\n private _camera: Camera | null = null;\n private _ctx: ThreeContext | null = null;\n private _objects: Record<string, object> = {};\n private _warnedUpdate = false;\n private _warnedPaths = new Set<string>();\n\n private get _threeSpec(): ThreeSequenceSpec {\n return this.spec as unknown as ThreeSequenceSpec;\n }\n\n protected override pathRouters(): PathRouters {\n return { three: (path) => this._resolveThreePath(path) };\n }\n\n async build(): Promise<void> {\n const spec = this._threeSpec;\n if (this.duration === undefined) {\n this.duration = this.parent?.duration ?? this.root.duration;\n }\n\n // Resolve layer size. Expressions see the usual scope; intrinsic w/h are\n // still 0 here (same chicken-and-egg as shapes), so W/H/GW/GH carry it.\n const scope = buildScope(this, this.parent, this.root) as unknown as Record<string, number>;\n const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;\n const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;\n const resolution = spec.resolution ?? 1;\n\n // Offscreen canvas — never attached to the DOM. document.createElement\n // (not OffscreenCanvas) so PIXI's Texture.from and three both accept it.\n const canvas = document.createElement('canvas');\n const renderer = new WebGLRenderer({ canvas, alpha: true, antialias: true });\n this._renderer = renderer;\n try {\n renderer.setSize(Math.round(width * resolution), Math.round(height * resolution), false);\n renderer.setClearColor(0x000000, 0);\n\n const scene = new Scene();\n const camera: Camera = new PerspectiveCamera(50, width / height, 0.1, 2000);\n const ctx: ThreeContext = { scene, camera, renderer, width, height };\n\n const result = await spec.setup(ctx);\n if (result?.camera) ctx.camera = result.camera;\n this._scene = scene;\n this._camera = ctx.camera;\n this._ctx = ctx;\n this._objects = { ...(result?.objects ?? {}) };\n if (!('camera' in this._objects)) this._objects.camera = this._camera;\n\n // Frame 0 so the texture is never blank before the first tick.\n renderer.render(scene, this._camera);\n\n const texture = Texture.from(canvas);\n const sprite = new Sprite({ texture, label: spec.name });\n sprite.cullable = true;\n // Texture is canvas-sized (layer px × resolution); scale back to comp px.\n sprite.width = width;\n sprite.height = height;\n this.target = sprite;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this.buildFilters();\n } catch (err) {\n this._disposeRenderer();\n throw err;\n }\n }\n\n /**\n * Per-frame sync hook. Movie._awaitVideoFrames duck-types on this method\n * (same contract as VideoSequence) and awaits it inside gotoFrame — the\n * single frame path shared by playback and export, which is what makes\n * three layers deterministic in both.\n */\n async awaitFrameAt(local: number): Promise<void> {\n if (!this._renderer || !this._scene || !this._camera || !this._ctx) return;\n const spec = this._threeSpec;\n const t = Math.max(0, Math.min(local, this.duration ?? local));\n if (spec.update) {\n try {\n spec.update(t, this._ctx);\n } catch (err) {\n if (!this._warnedUpdate) {\n this._warnedUpdate = true;\n console.warn('pixi-effects: three update() threw (reported once) —', err);\n }\n }\n }\n this._renderer.render(this._scene, this._camera);\n (this.target as Sprite | null)?.texture.source.update();\n }\n\n private _resolveThreePath(path: string): { target: object; prop: string } | null {\n const segs = path.split('.');\n if (segs.length < 2) {\n this._warnPath(path, 'needs at least <object>.<prop>');\n return null;\n }\n let obj: unknown = this._objects[segs[0]!];\n if (obj == null) {\n this._warnPath(path, `unknown object \"${segs[0]}\" — expose it via setup's { objects }`);\n return null;\n }\n for (let i = 1; i < segs.length - 1; i++) {\n obj = (obj as Record<string, unknown>)[segs[i]!];\n if (obj == null) {\n this._warnPath(path, `\"${segs[i]}\" is undefined along the path`);\n return null;\n }\n }\n const prop = segs[segs.length - 1]!;\n if (typeof obj !== 'object' || !(prop in (obj as object))) {\n this._warnPath(path, `no property \"${prop}\"`);\n return null;\n }\n return { target: obj as object, prop };\n }\n\n private _warnPath(path: string, why: string): void {\n if (this._warnedPaths.has(path)) return;\n this._warnedPaths.add(path);\n console.warn(`pixi-effects: keyframe path three.${path} ${why}; skipped`);\n }\n\n private _disposeRenderer(): void {\n if (!this._renderer) return;\n try {\n this._renderer.dispose();\n this._renderer.forceContextLoss();\n } catch (err) {\n console.warn('pixi-effects: three renderer dispose threw —', err);\n }\n this._renderer = null;\n }\n\n override destroy(): void {\n const spec = this._threeSpec;\n if (this._ctx && spec.dispose) {\n try { spec.dispose(this._ctx); } catch (err) {\n console.warn('pixi-effects: three dispose() threw —', err);\n }\n }\n const texture = (this.target as Sprite | null)?.texture;\n this._disposeRenderer();\n this._scene = null;\n this._camera = null;\n this._ctx = null;\n this._objects = {};\n super.destroy();\n texture?.destroy(true); // canvas-backed source is per-sequence; safe to kill\n }\n}\n\nfunction resolveDim(v: PropValue | undefined, scope: Record<string, number>): number | undefined {\n if (v === undefined) return undefined;\n if (typeof v === 'number') return v;\n return evaluateExpr(v, scope);\n}\n","/**\n * pixi-effects/three — optional three.js integration.\n *\n * Import this entry only when you use `type: 'three'` sequences; the core\n * `pixi-effects` entry never touches three.js. Call `registerThree()` once\n * before Movie.init builds a composition containing a three sequence.\n */\nimport { registerSequenceType, type SequenceCtor } from '../core/Composition';\nimport { ThreeSequence } from './ThreeSequence';\nimport type { SequenceSpec } from '../types';\nimport type { ThreeSequenceSpec } from './types';\n\nexport { ThreeSequence } from './ThreeSequence';\nexport type { ThreeContext, ThreeSetupResult, ThreeSequenceSpec } from './types';\n\n/** Register the 'three' sequence type. Idempotent; explicit call so `sideEffects: false` bundlers can't drop it. */\nexport function registerThree(): void {\n registerSequenceType('three', ThreeSequence as unknown as SequenceCtor);\n}\n\n/**\n * Typing helper: accepts a strongly-typed three spec and returns it as a\n * core SequenceSpec, keeping three.js types out of the core union.\n */\nexport function three(spec: ThreeSequenceSpec): SequenceSpec {\n return spec as unknown as SequenceSpec;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/three/ThreeSequence.ts","../src/three/index.ts"],"names":[],"mappings":"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","file":"three.js","sourcesContent":["import { Sprite, Texture } from 'pixi.js';\nimport { PerspectiveCamera, Scene, WebGLRenderer, type Camera } from 'three';\nimport { Sequence } from '../sequences/Base';\nimport { buildScope } from '../expr/Scope';\nimport { evaluateExpr } from '../expr/Parser';\nimport type { PathRouters } from '../core/Timeline';\nimport type { PropValue } from '../types';\nimport type { ThreeContext, ThreeSequenceSpec } from './types';\n\nexport class ThreeSequence extends Sequence {\n private _renderer: WebGLRenderer | null = null;\n private _scene: Scene | null = null;\n private _camera: Camera | null = null;\n private _ctx: ThreeContext | null = null;\n private _objects: Record<string, object> = {};\n private _warnedUpdate = false;\n private _warnedPaths = new Set<string>();\n\n private get _threeSpec(): ThreeSequenceSpec {\n return this.spec as unknown as ThreeSequenceSpec;\n }\n\n protected override pathRouters(): PathRouters {\n return { three: (path) => this._resolveThreePath(path) };\n }\n\n async build(): Promise<void> {\n const spec = this._threeSpec;\n if (this.duration === undefined) {\n this.duration = this.parent?.duration ?? this.root.duration;\n }\n\n // Resolve layer size. Expressions see the usual scope; intrinsic w/h are\n // still 0 here (same chicken-and-egg as shapes), so W/H/GW/GH carry it.\n const scope = buildScope(this, this.parent, this.root) as unknown as Record<string, number>;\n const width = resolveDim(spec.width, scope) ?? this.parent?.width ?? this.root.width;\n const height = resolveDim(spec.height, scope) ?? this.parent?.height ?? this.root.height;\n const resolution = spec.resolution ?? 1;\n\n // Offscreen canvas — never attached to the DOM. document.createElement\n // (not OffscreenCanvas) so PIXI's Texture.from and three both accept it.\n const canvas = document.createElement('canvas');\n const renderer = new WebGLRenderer({ canvas, alpha: true, antialias: true });\n this._renderer = renderer;\n try {\n renderer.setSize(Math.round(width * resolution), Math.round(height * resolution), false);\n renderer.setClearColor(0x000000, 0);\n\n const scene = new Scene();\n const camera: Camera = new PerspectiveCamera(50, width / height, 0.1, 2000);\n const ctx: ThreeContext = { scene, camera, renderer, width, height };\n\n const result = await spec.setup(ctx);\n if (result?.camera) ctx.camera = result.camera;\n this._scene = scene;\n this._camera = ctx.camera;\n this._ctx = ctx;\n this._objects = { ...(result?.objects ?? {}) };\n if (!('camera' in this._objects)) this._objects.camera = this._camera;\n\n // Frame 0 so the texture is never blank before the first tick.\n renderer.render(scene, this._camera);\n\n const texture = Texture.from(canvas);\n const sprite = new Sprite({ texture, label: spec.name });\n sprite.cullable = true;\n // Texture is canvas-sized (layer px × resolution); scale back to comp px.\n sprite.width = width;\n sprite.height = height;\n this.target = sprite;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this.buildFilters();\n } catch (err) {\n this._disposeRenderer();\n throw err;\n }\n }\n\n /**\n * Per-frame sync hook. Movie._awaitVideoFrames duck-types on this method\n * (same contract as VideoSequence) and awaits it inside gotoFrame — the\n * single frame path shared by playback and export, which is what makes\n * three layers deterministic in both.\n */\n async awaitFrameAt(local: number): Promise<void> {\n if (!this._renderer || !this._scene || !this._camera || !this._ctx) return;\n const spec = this._threeSpec;\n const t = Math.max(0, Math.min(local, this.duration ?? local));\n if (spec.update) {\n try {\n spec.update(t, this._ctx);\n } catch (err) {\n if (!this._warnedUpdate) {\n this._warnedUpdate = true;\n console.warn('pixi-effects: three update() threw (reported once) —', err);\n }\n }\n }\n this._renderer.render(this._scene, this._camera);\n (this.target as Sprite | null)?.texture.source.update();\n }\n\n private _resolveThreePath(path: string): { target: object; prop: string } | null {\n const segs = path.split('.');\n if (segs.length < 2) {\n this._warnPath(path, 'needs at least <object>.<prop>');\n return null;\n }\n let obj: unknown = this._objects[segs[0]!];\n if (obj == null) {\n this._warnPath(path, `unknown object \"${segs[0]}\" — expose it via setup's { objects }`);\n return null;\n }\n for (let i = 1; i < segs.length - 1; i++) {\n obj = (obj as Record<string, unknown>)[segs[i]!];\n if (obj == null) {\n this._warnPath(path, `\"${segs[i]}\" is undefined along the path`);\n return null;\n }\n }\n const prop = segs[segs.length - 1]!;\n if (typeof obj !== 'object' || !(prop in (obj as object))) {\n this._warnPath(path, `no property \"${prop}\"`);\n return null;\n }\n return { target: obj as object, prop };\n }\n\n private _warnPath(path: string, why: string): void {\n if (this._warnedPaths.has(path)) return;\n this._warnedPaths.add(path);\n console.warn(`pixi-effects: keyframe path three.${path} ${why}; skipped`);\n }\n\n private _disposeRenderer(): void {\n if (!this._renderer) return;\n try {\n this._renderer.dispose();\n this._renderer.forceContextLoss();\n } catch (err) {\n console.warn('pixi-effects: three renderer dispose threw —', err);\n }\n this._renderer = null;\n }\n\n override destroy(): void {\n const spec = this._threeSpec;\n if (this._ctx && spec.dispose) {\n try { spec.dispose(this._ctx); } catch (err) {\n console.warn('pixi-effects: three dispose() threw —', err);\n }\n }\n const texture = (this.target as Sprite | null)?.texture;\n this._disposeRenderer();\n this._scene = null;\n this._camera = null;\n this._ctx = null;\n this._objects = {};\n super.destroy();\n texture?.destroy(true); // canvas-backed source is per-sequence; safe to kill\n }\n}\n\nfunction resolveDim(v: PropValue | undefined, scope: Record<string, number>): number | undefined {\n if (v === undefined) return undefined;\n if (typeof v === 'number') return v;\n return evaluateExpr(v, scope);\n}\n","/**\n * pixi-effects/three — optional three.js integration.\n *\n * Import this entry only when you use `type: 'three'` sequences; the core\n * `pixi-effects` entry never touches three.js. Call `registerThree()` once\n * before Movie.init builds a composition containing a three sequence.\n */\nimport { registerSequenceType, type SequenceCtor } from '../core/Composition';\nimport { ThreeSequence } from './ThreeSequence';\nimport type { SequenceSpec } from '../types';\nimport type { ThreeSequenceSpec } from './types';\n\nexport { ThreeSequence } from './ThreeSequence';\nexport type { ThreeContext, ThreeSetupResult, ThreeSequenceSpec } from './types';\n\n/** Register the 'three' sequence type. Idempotent; explicit call so `sideEffects: false` bundlers can't drop it. */\nexport function registerThree(): void {\n registerSequenceType('three', ThreeSequence as unknown as SequenceCtor);\n}\n\n/**\n * Typing helper: accepts a strongly-typed three spec and returns it as a\n * core SequenceSpec, keeping three.js types out of the core union.\n */\nexport function three(spec: ThreeSequenceSpec): SequenceSpec {\n return spec as unknown as SequenceSpec;\n}\n"]}
|
|
@@ -69,7 +69,20 @@ interface ChromaKeyFilterSpec {
|
|
|
69
69
|
smoothing?: number;
|
|
70
70
|
spill?: number;
|
|
71
71
|
}
|
|
72
|
-
|
|
72
|
+
/**
|
|
73
|
+
* A filter by name: `{ type: 'glow', outerStrength: 3, color: '#ffd166' }`. The type is the filter's class name without
|
|
74
|
+
* `Filter` in camelCase (case does not matter); every other key is the filter's own option. `blur`, `noise`, `alpha` and
|
|
75
|
+
* `colorMatrix` (`preset: 'sepia' | 'grayscale' | …` or a 20-number `matrix`) come from pixi.js; the rest are the filters of
|
|
76
|
+
* the `pixi-filters` package (add it to the import map, or `npm i pixi-filters`), loaded on first use. Animate an option with
|
|
77
|
+
* `'filters.<name>.<option>'` like any other filter.
|
|
78
|
+
*/
|
|
79
|
+
interface NamedFilterSpec {
|
|
80
|
+
type: NamedFilterType;
|
|
81
|
+
name?: string;
|
|
82
|
+
[option: string]: unknown;
|
|
83
|
+
}
|
|
84
|
+
type NamedFilterType = 'blur' | 'noise' | 'alpha' | 'colorMatrix' | 'adjustment' | 'advancedBloom' | 'ascii' | 'backdropBlur' | 'bevel' | 'bloom' | 'bulgePinch' | 'colorGradient' | 'colorMap' | 'colorOverlay' | 'colorReplace' | 'convolution' | 'crossHatch' | 'crt' | 'dot' | 'dropShadow' | 'emboss' | 'glitch' | 'glow' | 'godray' | 'grayscale' | 'hslAdjustment' | 'kawaseBlur' | 'motionBlur' | 'multiColorReplace' | 'oldFilm' | 'outline' | 'pixelate' | 'radialBlur' | 'reflection' | 'rgbSplit' | 'shockwave' | 'simpleLightmap' | 'simplexNoise' | 'tiltShift' | 'tiltShiftAxis' | 'twist' | 'zoomBlur';
|
|
85
|
+
type FilterSpec = ChromaKeyFilterSpec | CustomFilterSpec | NamedFilterSpec;
|
|
73
86
|
interface TransitionCommon {
|
|
74
87
|
/** Sibling sequence's `name` — the outgoing scene. */
|
|
75
88
|
from: string;
|
|
@@ -212,6 +225,10 @@ interface TextSequenceSpec extends SequenceCommon {
|
|
|
212
225
|
* The text. May contain `{value}`, replaced by the layer's animatable number
|
|
213
226
|
* `value` (a counter): `text: '{value} users'`, `initial: { value: 0 }`,
|
|
214
227
|
* keyframe `to: { value: 2480 }`. Format it with `format`.
|
|
228
|
+
*
|
|
229
|
+
* The text can change over time: a keyframe `set: { text: 'Two' }` swaps the string at that time (and back when
|
|
230
|
+
* you seek back; a string cannot be tweened). `visibleChars` is a number that shows only the first N characters
|
|
231
|
+
* (a typewriter): `initial: { visibleChars: 0 }`, keyframe `to: { visibleChars: 20 }`. It starts at 0 once it is animated.
|
|
215
232
|
*/
|
|
216
233
|
text?: string;
|
|
217
234
|
/** How `{value}` is printed: `decimals` (default 0) and thousands `grouping` (default false). */
|
|
@@ -336,6 +353,18 @@ interface GradientSpec {
|
|
|
336
353
|
/** radial: outer radius where the last stop applies, 0–1. Default 0.5. */
|
|
337
354
|
radius?: number;
|
|
338
355
|
}
|
|
356
|
+
/**
|
|
357
|
+
* Stroke trim (draw-on): the part of the outline that is stroked, as fractions 0–1 of its length. Animate `trimEnd`
|
|
358
|
+
* from 0 to 1 to draw a line / path / outline on; animate both for a travelling dash. The outline of a rect starts at
|
|
359
|
+
* its top-left and goes clockwise, of a circle / ellipse at 12 o'clock and goes clockwise; a polygon's closing edge counts.
|
|
360
|
+
* The fill is not trimmed. Not for `arc` (animate its `endAngle`).
|
|
361
|
+
*/
|
|
362
|
+
interface Trimmable {
|
|
363
|
+
/** Where the stroke starts, 0–1 of the outline. Default 0. Animatable. */
|
|
364
|
+
trimStart?: PropValue;
|
|
365
|
+
/** Where the stroke ends, 0–1 of the outline. Default 1. Animatable. */
|
|
366
|
+
trimEnd?: PropValue;
|
|
367
|
+
}
|
|
339
368
|
interface ShapeBase extends SequenceCommon {
|
|
340
369
|
type: 'shape';
|
|
341
370
|
/** Fill with a gradient instead of `fillColor` (top level or in `initial`). */
|
|
@@ -358,7 +387,7 @@ interface ShapeBase extends SequenceCommon {
|
|
|
358
387
|
/** How stroke corners join: `'miter'` (default; sharp points can poke out), `'round'` or `'bevel'`. Top level or in `initial`. */
|
|
359
388
|
strokeJoin?: 'miter' | 'round' | 'bevel';
|
|
360
389
|
}
|
|
361
|
-
interface RectShapeSpec extends ShapeBase {
|
|
390
|
+
interface RectShapeSpec extends ShapeBase, Trimmable {
|
|
362
391
|
shape: 'rect';
|
|
363
392
|
width: PropValue;
|
|
364
393
|
height: PropValue;
|
|
@@ -373,14 +402,14 @@ interface RectShapeSpec extends ShapeBase {
|
|
|
373
402
|
anchorX?: PropValue;
|
|
374
403
|
anchorY?: PropValue;
|
|
375
404
|
}
|
|
376
|
-
interface CircleShapeSpec extends ShapeBase {
|
|
405
|
+
interface CircleShapeSpec extends ShapeBase, Trimmable {
|
|
377
406
|
shape: 'circle';
|
|
378
407
|
radius: PropValue;
|
|
379
408
|
/** See RectShapeSpec.anchorX. Default 0.5 (centre). */
|
|
380
409
|
anchorX?: PropValue;
|
|
381
410
|
anchorY?: PropValue;
|
|
382
411
|
}
|
|
383
|
-
interface EllipseShapeSpec extends ShapeBase {
|
|
412
|
+
interface EllipseShapeSpec extends ShapeBase, Trimmable {
|
|
384
413
|
shape: 'ellipse';
|
|
385
414
|
radiusX: PropValue;
|
|
386
415
|
radiusY: PropValue;
|
|
@@ -404,20 +433,20 @@ interface ArcShapeSpec extends ShapeBase {
|
|
|
404
433
|
/** Degrees. Default 360. Animatable. */
|
|
405
434
|
endAngle?: PropValue;
|
|
406
435
|
}
|
|
407
|
-
interface LineShapeSpec extends ShapeBase {
|
|
436
|
+
interface LineShapeSpec extends ShapeBase, Trimmable {
|
|
408
437
|
shape: 'line';
|
|
409
438
|
/** Line endpoints relative to the shape's local origin. */
|
|
410
439
|
from: [PropValue, PropValue];
|
|
411
440
|
to: [PropValue, PropValue];
|
|
412
441
|
}
|
|
413
|
-
interface PolygonShapeSpec extends ShapeBase {
|
|
442
|
+
interface PolygonShapeSpec extends ShapeBase, Trimmable {
|
|
414
443
|
shape: 'polygon';
|
|
415
444
|
/** Vertices in local space. The path is auto-closed. */
|
|
416
445
|
points: Array<[PropValue, PropValue]>;
|
|
417
446
|
/** When true, draw an open polyline instead of a closed polygon. Default false. */
|
|
418
447
|
open?: boolean;
|
|
419
448
|
}
|
|
420
|
-
interface PathShapeSpec extends ShapeBase {
|
|
449
|
+
interface PathShapeSpec extends ShapeBase, Trimmable {
|
|
421
450
|
shape: 'path';
|
|
422
451
|
/** SVG path data (`d` attribute). Goes through PIXI's GraphicsContext.svg(). */
|
|
423
452
|
d: string;
|
|
@@ -69,7 +69,20 @@ interface ChromaKeyFilterSpec {
|
|
|
69
69
|
smoothing?: number;
|
|
70
70
|
spill?: number;
|
|
71
71
|
}
|
|
72
|
-
|
|
72
|
+
/**
|
|
73
|
+
* A filter by name: `{ type: 'glow', outerStrength: 3, color: '#ffd166' }`. The type is the filter's class name without
|
|
74
|
+
* `Filter` in camelCase (case does not matter); every other key is the filter's own option. `blur`, `noise`, `alpha` and
|
|
75
|
+
* `colorMatrix` (`preset: 'sepia' | 'grayscale' | …` or a 20-number `matrix`) come from pixi.js; the rest are the filters of
|
|
76
|
+
* the `pixi-filters` package (add it to the import map, or `npm i pixi-filters`), loaded on first use. Animate an option with
|
|
77
|
+
* `'filters.<name>.<option>'` like any other filter.
|
|
78
|
+
*/
|
|
79
|
+
interface NamedFilterSpec {
|
|
80
|
+
type: NamedFilterType;
|
|
81
|
+
name?: string;
|
|
82
|
+
[option: string]: unknown;
|
|
83
|
+
}
|
|
84
|
+
type NamedFilterType = 'blur' | 'noise' | 'alpha' | 'colorMatrix' | 'adjustment' | 'advancedBloom' | 'ascii' | 'backdropBlur' | 'bevel' | 'bloom' | 'bulgePinch' | 'colorGradient' | 'colorMap' | 'colorOverlay' | 'colorReplace' | 'convolution' | 'crossHatch' | 'crt' | 'dot' | 'dropShadow' | 'emboss' | 'glitch' | 'glow' | 'godray' | 'grayscale' | 'hslAdjustment' | 'kawaseBlur' | 'motionBlur' | 'multiColorReplace' | 'oldFilm' | 'outline' | 'pixelate' | 'radialBlur' | 'reflection' | 'rgbSplit' | 'shockwave' | 'simpleLightmap' | 'simplexNoise' | 'tiltShift' | 'tiltShiftAxis' | 'twist' | 'zoomBlur';
|
|
85
|
+
type FilterSpec = ChromaKeyFilterSpec | CustomFilterSpec | NamedFilterSpec;
|
|
73
86
|
interface TransitionCommon {
|
|
74
87
|
/** Sibling sequence's `name` — the outgoing scene. */
|
|
75
88
|
from: string;
|
|
@@ -212,6 +225,10 @@ interface TextSequenceSpec extends SequenceCommon {
|
|
|
212
225
|
* The text. May contain `{value}`, replaced by the layer's animatable number
|
|
213
226
|
* `value` (a counter): `text: '{value} users'`, `initial: { value: 0 }`,
|
|
214
227
|
* keyframe `to: { value: 2480 }`. Format it with `format`.
|
|
228
|
+
*
|
|
229
|
+
* The text can change over time: a keyframe `set: { text: 'Two' }` swaps the string at that time (and back when
|
|
230
|
+
* you seek back; a string cannot be tweened). `visibleChars` is a number that shows only the first N characters
|
|
231
|
+
* (a typewriter): `initial: { visibleChars: 0 }`, keyframe `to: { visibleChars: 20 }`. It starts at 0 once it is animated.
|
|
215
232
|
*/
|
|
216
233
|
text?: string;
|
|
217
234
|
/** How `{value}` is printed: `decimals` (default 0) and thousands `grouping` (default false). */
|
|
@@ -336,6 +353,18 @@ interface GradientSpec {
|
|
|
336
353
|
/** radial: outer radius where the last stop applies, 0–1. Default 0.5. */
|
|
337
354
|
radius?: number;
|
|
338
355
|
}
|
|
356
|
+
/**
|
|
357
|
+
* Stroke trim (draw-on): the part of the outline that is stroked, as fractions 0–1 of its length. Animate `trimEnd`
|
|
358
|
+
* from 0 to 1 to draw a line / path / outline on; animate both for a travelling dash. The outline of a rect starts at
|
|
359
|
+
* its top-left and goes clockwise, of a circle / ellipse at 12 o'clock and goes clockwise; a polygon's closing edge counts.
|
|
360
|
+
* The fill is not trimmed. Not for `arc` (animate its `endAngle`).
|
|
361
|
+
*/
|
|
362
|
+
interface Trimmable {
|
|
363
|
+
/** Where the stroke starts, 0–1 of the outline. Default 0. Animatable. */
|
|
364
|
+
trimStart?: PropValue;
|
|
365
|
+
/** Where the stroke ends, 0–1 of the outline. Default 1. Animatable. */
|
|
366
|
+
trimEnd?: PropValue;
|
|
367
|
+
}
|
|
339
368
|
interface ShapeBase extends SequenceCommon {
|
|
340
369
|
type: 'shape';
|
|
341
370
|
/** Fill with a gradient instead of `fillColor` (top level or in `initial`). */
|
|
@@ -358,7 +387,7 @@ interface ShapeBase extends SequenceCommon {
|
|
|
358
387
|
/** How stroke corners join: `'miter'` (default; sharp points can poke out), `'round'` or `'bevel'`. Top level or in `initial`. */
|
|
359
388
|
strokeJoin?: 'miter' | 'round' | 'bevel';
|
|
360
389
|
}
|
|
361
|
-
interface RectShapeSpec extends ShapeBase {
|
|
390
|
+
interface RectShapeSpec extends ShapeBase, Trimmable {
|
|
362
391
|
shape: 'rect';
|
|
363
392
|
width: PropValue;
|
|
364
393
|
height: PropValue;
|
|
@@ -373,14 +402,14 @@ interface RectShapeSpec extends ShapeBase {
|
|
|
373
402
|
anchorX?: PropValue;
|
|
374
403
|
anchorY?: PropValue;
|
|
375
404
|
}
|
|
376
|
-
interface CircleShapeSpec extends ShapeBase {
|
|
405
|
+
interface CircleShapeSpec extends ShapeBase, Trimmable {
|
|
377
406
|
shape: 'circle';
|
|
378
407
|
radius: PropValue;
|
|
379
408
|
/** See RectShapeSpec.anchorX. Default 0.5 (centre). */
|
|
380
409
|
anchorX?: PropValue;
|
|
381
410
|
anchorY?: PropValue;
|
|
382
411
|
}
|
|
383
|
-
interface EllipseShapeSpec extends ShapeBase {
|
|
412
|
+
interface EllipseShapeSpec extends ShapeBase, Trimmable {
|
|
384
413
|
shape: 'ellipse';
|
|
385
414
|
radiusX: PropValue;
|
|
386
415
|
radiusY: PropValue;
|
|
@@ -404,20 +433,20 @@ interface ArcShapeSpec extends ShapeBase {
|
|
|
404
433
|
/** Degrees. Default 360. Animatable. */
|
|
405
434
|
endAngle?: PropValue;
|
|
406
435
|
}
|
|
407
|
-
interface LineShapeSpec extends ShapeBase {
|
|
436
|
+
interface LineShapeSpec extends ShapeBase, Trimmable {
|
|
408
437
|
shape: 'line';
|
|
409
438
|
/** Line endpoints relative to the shape's local origin. */
|
|
410
439
|
from: [PropValue, PropValue];
|
|
411
440
|
to: [PropValue, PropValue];
|
|
412
441
|
}
|
|
413
|
-
interface PolygonShapeSpec extends ShapeBase {
|
|
442
|
+
interface PolygonShapeSpec extends ShapeBase, Trimmable {
|
|
414
443
|
shape: 'polygon';
|
|
415
444
|
/** Vertices in local space. The path is auto-closed. */
|
|
416
445
|
points: Array<[PropValue, PropValue]>;
|
|
417
446
|
/** When true, draw an open polyline instead of a closed polygon. Default false. */
|
|
418
447
|
open?: boolean;
|
|
419
448
|
}
|
|
420
|
-
interface PathShapeSpec extends ShapeBase {
|
|
449
|
+
interface PathShapeSpec extends ShapeBase, Trimmable {
|
|
421
450
|
shape: 'path';
|
|
422
451
|
/** SVG path data (`d` attribute). Goes through PIXI's GraphicsContext.svg(). */
|
|
423
452
|
d: string;
|
package/docs/api.md
CHANGED
|
@@ -167,6 +167,12 @@ Returns a `Blob` whose `type` is the container's MIME (e.g. `video/mp4`). Emits
|
|
|
167
167
|
|
|
168
168
|
The renderer also forces a keyframe every ~2 seconds so the resulting file scrubs efficiently in standard players.
|
|
169
169
|
|
|
170
|
+
### `movie.timelineData(): TimelineData` and `movie.timelineChart(options?): string`
|
|
171
|
+
|
|
172
|
+
The whole movie as rows on a time axis, for a person to read at a glance. `timelineData()` is the data: `{ duration, rows, transitions }`, a row per layer with `name`, `type`, `depth` (1 inside a composition), absolute `start` / `end` in seconds, `keys` (when each keyframe starts) and, for a family of generated layers, `parts` (one span per layer). Layers of one type whose names differ only by numbers (`ring10-0`, `ring9-1`, `pop-3` …), four or more, become ONE row (`ring#-# ×19`), so a movie with 700 generated layers is a screenful. `timelineChart({ title })` returns one self-contained HTML page (an inline SVG, no scripts): bars coloured by type, ◆ at each keyframe start, a shaded band per transition, a tooltip per bar. `pixi-effects-check` writes it next to the contact sheet as `timeline.html`.
|
|
173
|
+
|
|
174
|
+
`movie.timelineSvg()` is the chart alone (one `<svg>`, geometry in `data-*` attributes, each row `<g class="row" data-start>`): `pixi-effects-view` puts a playhead on it and turns a click into a seek.
|
|
175
|
+
|
|
170
176
|
### `movie.destroy(): Promise<void>`
|
|
171
177
|
|
|
172
178
|
Pauses playback, destroys the underlying PIXI Application, releases audio buffers and AudioContext, and marks the instance unusable.
|
|
@@ -182,6 +188,7 @@ movie.off(event, fn): this
|
|
|
182
188
|
| ----------- | ------------------------------------------------- | ----------------------------------------------------- |
|
|
183
189
|
| `'ready'` | none | once, after `init()` resolves |
|
|
184
190
|
| `'frame'` | `{ frame: number; totalFrames: number }` | every `gotoFrame` (so once per playback frame too) |
|
|
191
|
+
| `'play'` | none | when `play()` actually transitions from paused |
|
|
185
192
|
| `'pause'` | none | when `pause()` actually transitions from playing |
|
|
186
193
|
| `'progress'`| `{ progress: number; frame: number; totalFrames: number }` | during `render()`, once per encoded frame |
|
|
187
194
|
|
package/docs/dsl.md
CHANGED
|
@@ -71,7 +71,7 @@ A layer is **not removed** when its lifespan `[at, at + duration)` ends: it is o
|
|
|
71
71
|
|
|
72
72
|
### `text`
|
|
73
73
|
|
|
74
|
-
Renders a [PIXI.Text](https://pixijs.com/8.x/guides/components/scene-objects/text/text). Animatable position, rotation, scale, opacity and `fill`. `style` accepts any PixiJS `TextStyle` field and is applied once at build time — notably `fontSize fontFamily fontWeight fill letterSpacing lineHeight align wordWrap wordWrapWidth stroke dropShadow padding` (numbers may be expressions). A `dropShadow` glow is clipped unless `padding` is at least twice its `blur`. Text content
|
|
74
|
+
Renders a [PIXI.Text](https://pixijs.com/8.x/guides/components/scene-objects/text/text). Animatable position, rotation, scale, opacity and `fill`. `style` accepts any PixiJS `TextStyle` field and is applied once at build time — notably `fontSize fontFamily fontWeight fill letterSpacing lineHeight align wordWrap wordWrapWidth stroke dropShadow padding` (numbers may be expressions). A `dropShadow` glow is clipped unless `padding` is at least twice its `blur`. Text content can change over time (see *Changing text* below): a `{value}` placeholder prints an animatable number (counters), a keyframe `set: { text: '…' }` swaps the string, and `visibleChars` types it out. Multi-line text is centre-aligned unless `style.align` says otherwise. In expressions `w` / `h` are the size of the styled text, so `x: '-w'` places it just off the left edge.
|
|
75
75
|
|
|
76
76
|
```ts
|
|
77
77
|
{
|
|
@@ -103,6 +103,17 @@ The text's `fill` is also animatable via keyframes (under the `to`/`from`/`set`
|
|
|
103
103
|
}
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
#### Changing text: `set: { text }` and `visibleChars`
|
|
107
|
+
|
|
108
|
+
A keyframe `set: { text: 'Two' }` swaps the string at that time (layer-local `at`, undone when you seek back; a string cannot be tweened, so `to` / `from` with `text` warn). A countdown is one layer:
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
{ type: 'text', text: '3', duration: 4, style: { fontSize: 150 }, initial: { x: 'GW/2', y: 'GH/2', anchorX: 0.5, anchorY: 0.5 },
|
|
112
|
+
keyframes: [{ at: 1, set: { text: '2' } }, { at: 2, set: { text: '1' } }, { at: 3, set: { text: 'Go!' } }] }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`visibleChars` is a number that shows only the first N characters (counted as you see them: an emoji is one): a typewriter. `initial: { visibleChars: 0 }` and a keyframe `to: { visibleChars: 30 }, duration: 2.4, ease: 'none'` types 30 characters over 2.4 s (it starts at 0 as soon as it is animated). Use a left-aligned layer (`anchorX: 0`, `style.align: 'left'`) so the text grows to the right instead of re-centring each letter; the layer's `w` / `h` are those of the whole text. `set: { text }` and `visibleChars` combine (swap the string, `set: { visibleChars: 0 }`, type it again), and so does a `{value}` placeholder in the string.
|
|
116
|
+
|
|
106
117
|
#### Counters (`{value}`)
|
|
107
118
|
|
|
108
119
|
A text layer has one animatable number, `value`, printed wherever the text contains `{value}`. Animate it with the normal keyframes (any ease, `from`/`to`/`set`, `repeat`):
|
|
@@ -250,13 +261,13 @@ Every primitive draws centred on its local origin (so `anchorX`/`anchorY` and `p
|
|
|
250
261
|
|
|
251
262
|
| `shape` | Required props | Optional |
|
|
252
263
|
|-----------|------------------------------------------|------------------------|
|
|
253
|
-
| `rect` | `width`, `height` | `cornerRadius`
|
|
254
|
-
| `circle` | `radius` |
|
|
255
|
-
| `ellipse` | `radiusX`, `radiusY` |
|
|
264
|
+
| `rect` | `width`, `height` | `cornerRadius`, `trimStart`, `trimEnd` |
|
|
265
|
+
| `circle` | `radius` | `trimStart`, `trimEnd` |
|
|
266
|
+
| `ellipse` | `radiusX`, `radiusY` | `trimStart`, `trimEnd` |
|
|
256
267
|
| `arc` | `radius` | `innerRadius`, `startAngle` (0), `endAngle` (360) |
|
|
257
|
-
| `line` | `from: [x,y]`, `to: [x,y]` (canvas coordinates; stroke in `initial`) |
|
|
258
|
-
| `polygon` | `points: [[x,y], …]` | `open` (default false) |
|
|
259
|
-
| `path` | `d` (SVG path data) |
|
|
268
|
+
| `line` | `from: [x,y]`, `to: [x,y]` (canvas coordinates; stroke in `initial`) | `trimStart`, `trimEnd` |
|
|
269
|
+
| `polygon` | `points: [[x,y], …]` | `open` (default false), `trimStart`, `trimEnd` |
|
|
270
|
+
| `path` | `d` (SVG path data) | `trimStart`, `trimEnd` |
|
|
260
271
|
|
|
261
272
|
**`arc`** is an arc around its local origin (the centre). Angles are in **degrees: 0° is 3 o'clock and positive is clockwise**, so a progress ring starts at `startAngle: -90` (12 o'clock) and animates `endAngle` from `-90` to `270`. With a stroke and no fill it is an open arc line (`strokeCap: 'round'` for rounded ends); with a fill it is a sector (a pie slice), and with `innerRadius` a ring segment (a donut slice). A sweep of 360° or more is a full circle; `endAngle < startAngle` sweeps counter-clockwise. `radius`, `innerRadius`, `startAngle` and `endAngle` are all animatable.
|
|
262
273
|
|
|
@@ -266,6 +277,14 @@ Every primitive draws centred on its local origin (so `anchorX`/`anchorY` and `p
|
|
|
266
277
|
keyframes: [{ at: 0, to: { endAngle: 270 }, duration: 2, ease: 'power3.out' }] } // a progress ring filling clockwise from the top
|
|
267
278
|
```
|
|
268
279
|
|
|
280
|
+
**Draw-on (`trimStart` / `trimEnd`).** On every shape except `arc`, `trimStart` and `trimEnd` (0–1, default 0 and 1, both animatable) are the part of the outline that is stroked, as fractions of its length. Animate `trimEnd` from 0 to 1 to draw a line, border or SVG path on; animate `trimStart` after it to wipe it off the same way; animate both for a travelling dash. A rect's outline starts at its top-left and goes clockwise, a circle / ellipse's at 12 o'clock and goes clockwise, a polygon's includes its closing edge, and a path's several sub-paths count as one length in order. **The fill is not trimmed** (the whole shape stays filled): fade `fillAlpha` in after the draw-on. Use `strokeCap: 'round'` for a friendly end. For `arc`, animate `endAngle` instead (a `trim…` on an arc warns).
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
{ type: 'shape', shape: 'path', d: 'M 0 50 L 45 95 L 130 0', trimEnd: 0, strokeCap: 'round', strokeJoin: 'round',
|
|
284
|
+
initial: { x: 1040, y: 270, strokeColor: '#7bd88f', strokeWidth: 16 },
|
|
285
|
+
keyframes: [{ at: 0, to: { trimEnd: 1 }, duration: 1, ease: 'power2.inOut' }] } // a check mark drawing itself
|
|
286
|
+
```
|
|
287
|
+
|
|
269
288
|
`strokeCap` (`'butt'`, `'round'`, `'square'`) and `strokeJoin` (`'miter'`, `'round'`, `'bevel'`) work on every shape, at the top level or in `initial`; they are not animated. Sharp corners (the apex of an M in outlined text, a thin polygon) poke out with the default `miter` join: use `'round'`.
|
|
270
289
|
|
|
271
290
|
**Style** is set on `initial` and animatable via keyframes:
|
|
@@ -915,6 +934,53 @@ Removes a key color from the source. Works on video, image, or composition layer
|
|
|
915
934
|
|
|
916
935
|
Animatable: `threshold`, `smoothing`, `spill`. `keyColor` is set at build time.
|
|
917
936
|
|
|
937
|
+
### Named filters (`{ type: 'glow', … }`)
|
|
938
|
+
|
|
939
|
+
A filter by name, as plain data. `type` is the filter's class name without `Filter`, in camelCase (case does not matter), and every other key is that filter's own option. No import, and the layer stays JSON:
|
|
940
|
+
|
|
941
|
+
```ts
|
|
942
|
+
{ type: 'text', text: 'NEON', style: { fontSize: 140, fill: '#fff' }, initial: { x: 'GW/2', y: 'GH/2', anchorX: 0.5, anchorY: 0.5 },
|
|
943
|
+
filters: [{ type: 'glow', name: 'halo', outerStrength: 0, color: '#ff4d9d', distance: 20 }],
|
|
944
|
+
keyframes: [{ at: 0, to: { 'filters.halo.outerStrength': 6 }, duration: 1 }] } // animate any scalar option by name
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
Name a filter (`name: 'halo'`) to animate it with `'filters.halo.<option>'`. `blur`, `noise`, `alpha` and `colorMatrix` come from pixi.js. All the others come from the **`pixi-filters`** package, which is loaded the first time a layer uses one (add `"pixi-filters": "https://esm.sh/pixi-filters@6.1.5?external=pixi.js"` to the import map, or `npm i pixi-filters`; `ai/template.html` already has it). A misspelt type says what you probably meant. Verified rendering and exporting in a real browser (`examples/_checks/named-filters.html`, 24 filters):
|
|
948
|
+
|
|
949
|
+
| `type` | Options (the useful ones) | What it does |
|
|
950
|
+
|---|---|---|
|
|
951
|
+
| `blur` | `strength`, `quality` | Gaussian blur (pixi.js) |
|
|
952
|
+
| `noise` | `noise` (0–1), `seed` | Film grain (pixi.js) |
|
|
953
|
+
| `alpha` | `alpha` | Whole-layer opacity (pixi.js) |
|
|
954
|
+
| `colorMatrix` | `preset`: `'sepia' 'grayscale' 'negative' 'polaroid' 'technicolor' 'vintage' 'kodachrome' 'browni'`, or `matrix` (20 numbers) | Colour grade (pixi.js) |
|
|
955
|
+
| `adjustment` | `gamma contrast saturation brightness red green blue alpha` (1 = unchanged) | Colour grading |
|
|
956
|
+
| `hslAdjustment` | `hue` (degrees) `saturation lightness colorize alpha` | Hue shift |
|
|
957
|
+
| `grayscale` | – | Black and white |
|
|
958
|
+
| `glow` | `distance outerStrength innerStrength color alpha quality knockout` | Glow around the shape |
|
|
959
|
+
| `dropShadow` | `offset: { x, y }` `blur alpha color shadowOnly` | Shadow |
|
|
960
|
+
| `outline` | `thickness color alpha quality knockout` | Stroke around the shape |
|
|
961
|
+
| `pixelate` | `size` (a number, or `[w, h]`); animate `sizeX` / `sizeY` | Mosaic |
|
|
962
|
+
| `crt` | `curvature lineWidth lineContrast noise vignetting vignettingAlpha time` | Old monitor |
|
|
963
|
+
| `rgbSplit` | `red green blue` (each `{ x, y }` offset) | Chromatic aberration |
|
|
964
|
+
| `oldFilm` | `sepia noise scratch scratchDensity vignetting seed` | Aged film |
|
|
965
|
+
| `glitch` | `slices offset direction seed average` | Digital glitch |
|
|
966
|
+
| `bulgePinch` | `center radius strength` | Bulge (+) / pinch (−) |
|
|
967
|
+
| `twist` | `radius angle offset: { x, y }` | Swirl |
|
|
968
|
+
| `zoomBlur` | `strength center innerRadius radius` | Radial zoom streaks |
|
|
969
|
+
| `kawaseBlur` | `strength quality` | Cheap, wide blur |
|
|
970
|
+
| `radialBlur` / `motionBlur` | `angle center radius` / `velocity kernelSize` | Spin / directional blur |
|
|
971
|
+
| `emboss` | `strength` | Relief |
|
|
972
|
+
| `ascii` | `size color replaceColor` | Text-art |
|
|
973
|
+
| `colorOverlay` | `color alpha` | Tint over everything |
|
|
974
|
+
| `advancedBloom` / `bloom` | `threshold bloomScale brightness blur` | Bloom |
|
|
975
|
+
| `bevel`, `dot`, `crossHatch`, `tiltShift`, `reflection`, `shockwave`, `godray`, `simplexNoise`, `colorGradient`, `colorMap`, `colorReplace`, `multiColorReplace`, `convolution`, `backdropBlur`, `simpleLightmap`, `tiltShiftAxis` | see the [pixi-filters docs](https://pixijs.io/filters/docs/) | Other pixi-filters |
|
|
976
|
+
|
|
977
|
+
Gotchas, all measured:
|
|
978
|
+
|
|
979
|
+
- **Centres and offsets are in canvas pixels, not the layer's:** `twist.offset`, `bulgePinch.center`, `zoomBlur.center`, `radialBlur.center`, `shockwave.center` default to the canvas's top-left corner, so a layer in the middle looks unaffected. Put the centre on the layer: `{ type: 'twist', offset: { x: 640, y: 360 } }` for a layer centred on a 1280×720 canvas.
|
|
980
|
+
- **A filter works inside the layer's bounds.** Glow, dropShadow, outline and blur draw outside it and are clipped unless you widen the area (`filterArea: { x: -24, y: -24, width: w + 48, height: h + 48 }`, in the layer's own coordinates). Do not widen it for `grayscale`, `oldFilm` or other filters that paint the whole area: they fill the extra margin with black.
|
|
981
|
+
- **Animate scalars by name** (`'filters.halo.outerStrength'`). Options that are points (`rgbSplit.red`, `dropShadow.offset`) do not tween as a whole; animate `'filters.<name>.red.x'` if the filter exposes it, or swap the filter. `pixelate` animates through `sizeX` / `sizeY`, not `size`.
|
|
982
|
+
- Some filters take their value as one argument; the DSL hides that (`{ type: 'pixelate', size: 8 }`, `{ type: 'emboss', strength: 6 }`).
|
|
983
|
+
|
|
918
984
|
### `custom`
|
|
919
985
|
|
|
920
986
|
Escape hatch for any PIXI `Filter` instance — including PIXI's own built-ins (`BlurFilter`, `ColorMatrixFilter`, `NoiseFilter`, etc.), [pixi-filters](https://github.com/pixijs/filters), community packages, or your own `Filter` subclass. The instance is used as-is; animation works the same way as for `chromaKey` as long as the filter has writable scalar properties at the addressed paths.
|
|
@@ -948,7 +1014,7 @@ Notes:
|
|
|
948
1014
|
Notes:
|
|
949
1015
|
|
|
950
1016
|
- `filter` must be a PIXI `Filter` instance (constructor must have run on the consumer side). Plain object literals throw.
|
|
951
|
-
- `
|
|
1017
|
+
- Use `custom` for a filter that has no name above (a community filter, or your own `Filter`). For everything in pixi.js and `pixi-filters`, prefer the named form.
|
|
952
1018
|
- Without a `name`, the filter still applies but cannot be addressed via `filters.<name>.<prop>` keyframe paths.
|
|
953
1019
|
|
|
954
1020
|
---
|