pixi-effects 0.2.0 → 0.3.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 +31 -0
- package/README.md +15 -5
- package/ai/SKILL.md +44 -0
- package/ai/reference/cheatsheet.md +120 -0
- package/ai/reference/pitfalls.md +54 -0
- package/ai/reference/recipes.md +375 -0
- package/ai/template.html +82 -0
- package/ai/tools/save-image.py +24 -0
- package/dist/{Base-B1Tdn0Cv.d.cts → Base-BDw6dKRB.d.cts} +1 -1
- package/dist/{Base-Bh_VSusi.d.ts → Base-Ba4Ta4ap.d.ts} +1 -1
- package/dist/Composition-6FDH5OPM.cjs +13 -0
- package/dist/{Composition-BI5HZJFL.cjs.map → Composition-6FDH5OPM.cjs.map} +1 -1
- package/dist/Composition-FEYAUMFI.js +4 -0
- package/dist/{Composition-IO7ZN32J.js.map → Composition-FEYAUMFI.js.map} +1 -1
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/Movie-DMpaT67V.d.ts +179 -0
- package/dist/Movie-W8ISiEBB.d.cts +179 -0
- package/dist/{chunk-H55V3U56.js → chunk-DIJG2RSF.js} +28 -11
- package/dist/chunk-DIJG2RSF.js.map +1 -0
- package/dist/{chunk-VJCDG6YG.js → chunk-PN5A6QA7.js} +248 -64
- package/dist/chunk-PN5A6QA7.js.map +1 -0
- package/dist/{chunk-7OIWYXGV.cjs → chunk-SIRVULFF.cjs} +251 -62
- package/dist/chunk-SIRVULFF.cjs.map +1 -0
- package/dist/{chunk-64IHCYYN.cjs → chunk-ZL262ZRM.cjs} +37 -20
- package/dist/chunk-ZL262ZRM.cjs.map +1 -0
- package/dist/index.cjs +324 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -31
- package/dist/index.d.ts +61 -31
- package/dist/index.js +321 -22
- package/dist/index.js.map +1 -1
- package/dist/three.cjs +5 -5
- package/dist/three.d.cts +2 -2
- package/dist/three.d.ts +2 -2
- package/dist/three.js +1 -1
- package/dist/{types-CNBilhpz.d.cts → types-3c8Vymgw.d.cts} +53 -6
- package/dist/{types-CNBilhpz.d.ts → types-3c8Vymgw.d.ts} +53 -6
- package/docs/api.md +333 -0
- package/docs/dsl.md +1017 -0
- package/llms-full.txt +1966 -0
- package/llms.txt +30 -0
- package/package.json +4 -3
- package/dist/Composition-BI5HZJFL.cjs +0 -13
- package/dist/Composition-IO7ZN32J.js +0 -4
- package/dist/Movie-CcR6h2jO.d.cts +0 -82
- package/dist/Movie-D-n8glA6.d.ts +0 -82
- package/dist/chunk-64IHCYYN.cjs.map +0 -1
- package/dist/chunk-7OIWYXGV.cjs.map +0 -1
- package/dist/chunk-H55V3U56.js.map +0 -1
- package/dist/chunk-VJCDG6YG.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/space/camera.ts","../src/space/depth.ts","../src/space/Layer3D.ts","../src/space/lint.ts","../src/sequences/Composition.ts"],"names":["i","DEG","frameOf","PerspectiveMesh","Texture","projectLayer","describeLayer","Matrix","RenderTexture","collectPropKeys","Sequence","Container","Rectangle","lintTiming","lintText","buildSequenceTree","CameraSequence","cameraBasis","homeCamera"],"mappings":"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","file":"chunk-ZL262ZRM.cjs","sourcesContent":["/** A camera layer's lifespan on the global timeline, seconds. */\nexport interface CameraWindow { start: number; end: number }\n\n/**\n * The active camera at time `t`: the last-listed (top-most) camera whose\n * lifespan covers `t`. Windows are [start, end), except that a camera running\n * to the end of its composition also covers the final instant `t === compEnd`.\n */\nexport function pickActiveCamera<T extends CameraWindow>(\n cams: readonly T[],\n t: number,\n compEnd: number,\n): T | null {\n for (let i = cams.length - 1; i >= 0; i--) {\n const c = cams[i]!;\n const inside = t >= c.start && (t < c.end || (c.end >= compEnd && t <= compEnd));\n if (inside) return c;\n }\n return null;\n}\n\n/** First pair of camera indices whose lifespans strictly overlap, or null. */\nexport function findOverlap(cams: readonly CameraWindow[]): [number, number] | null {\n for (let i = 0; i < cams.length; i++) {\n for (let j = i + 1; j < cams.length; j++) {\n const a = cams[i]!;\n const b = cams[j]!;\n if (a.start < b.end && b.start < a.end) return [i, j];\n }\n }\n return null;\n}\n","export interface DepthItem {\n /** Position in the composition's stack (monotonic; gaps allowed). */\n stackIndex: number;\n threeD: boolean;\n /** Camera-space depth (larger = farther). Only read for threeD items. */\n depth: number;\n}\n\nconst finite = (n: number): number => (Number.isFinite(n) ? n : 0);\n\n/**\n * zIndex per item. Non-3D items keep their stack index. Each run of\n * consecutive threeD items is redistributed over the same index slots,\n * farthest first (drawn first), ties in stack order.\n */\nexport function assignDepthOrder(items: readonly DepthItem[]): number[] {\n const out = items.map(i => i.stackIndex);\n let i = 0;\n while (i < items.length) {\n if (!items[i]!.threeD) { i++; continue; }\n let j = i;\n while (j + 1 < items.length && items[j + 1]!.threeD) j++;\n const run = items.slice(i, j + 1).map((it, k) => ({ it, pos: i + k }));\n const slots = run.map(r => r.it.stackIndex);\n const farthestFirst = [...run].sort((a, b) => finite(b.it.depth) - finite(a.it.depth));\n farthestFirst.forEach((r, k) => { out[r.pos] = slots[k]!; });\n i = j + 1;\n }\n return out;\n}\n","import { Container, Matrix, PerspectiveMesh, RenderTexture, Texture } from 'pixi.js';\nimport type { Sequence } from '../sequences/Base';\nimport { describeLayer } from '../core/lint';\nimport { DEG, projectLayer, type CameraBasis, type LayerTransform, type Rect } from './math';\n\n/** Render textures are capped at this many pixels on the long side; larger layers are downscaled. */\nexport const MAX_TEXTURE_SIZE = 4096;\n/**\n * Render textures are drawn at this multiple of the layer size (until the caps),\n * so a layer enlarged by perspective (z > 0) stays sharp instead of showing\n * jagged edges and soft text.\n */\nexport const SUPERSAMPLE = 2;\n/** Total texture pixels per layer are capped here (≈ one 2048² target); resolution drops to fit. */\nexport const MAX_TEXTURE_PIXELS = 2048 * 2048;\n/** MSAA multiplies target memory ~4x, so only small textures get it (supersampling covers the rest). */\nexport const ANTIALIAS_MAX_PIXELS = 1024 * 1024;\n/** Mesh grid per side. 20 keeps steeply tilted planes free of visible affine warping. */\nexport const MESH_GRID = 20;\n\n/** The slice of a Pixi renderer Layer3D needs (also what tests fake). */\nexport interface SpaceHost {\n render(options: {\n container: Container;\n target: RenderTexture;\n transform: Matrix;\n clear: boolean;\n clearColor: number[];\n }): void;\n}\n\ntype Carrier = Container & { z?: number; rotationX?: number; rotationY?: number };\n\ninterface TextureSize { w: number; h: number; resolution: number; antialias: boolean }\n\n/** Sum of the target's filter paddings: the texture must be this much larger on every side or filter output is clipped. */\nfunction filterPadding(target: Container): number {\n const filters = (target as unknown as { filters?: ReadonlyArray<{ padding?: number }> | null }).filters;\n if (!Array.isArray(filters)) return 0;\n let pad = 0;\n for (const f of filters) pad += f?.padding ?? 0;\n return Number.isFinite(pad) && pad > 0 ? Math.ceil(pad) : 0;\n}\n\nexport function readLayerTransform(target: Container): LayerTransform {\n const c = target as Carrier;\n return {\n x: c.x, y: c.y, z: c.z ?? 0,\n rotationX: (c.rotationX ?? 0) * DEG,\n rotationY: (c.rotationY ?? 0) * DEG,\n rotationZ: c.rotation,\n scaleX: c.scale.x, scaleY: c.scale.y,\n pivotX: c.pivot.x, pivotY: c.pivot.y,\n };\n}\n\n/**\n * Draws one `threeD` sequence: its display object is rendered into a\n * RenderTexture (with its own 2D transform replaced, so layer-local content\n * lands at the texture origin) and shown on a PerspectiveMesh whose four\n * corners come from projecting the layer through the active camera.\n *\n * The sequence's `target` is never in the scene graph; the composition adds\n * `display` instead. `z`, `rotationX`, `rotationY` live on `target` as plain\n * numeric props so GSAP tweens them like any other prop.\n */\nexport class Layer3D {\n readonly display: PerspectiveMesh;\n /** Camera-space depth from the last update (larger = farther). */\n depth = 0;\n private rt: RenderTexture | null = null;\n private size: TextureSize | null = null;\n private warnedBehind = false;\n\n constructor(\n private readonly seq: Sequence,\n private readonly frameOf: () => Rect,\n ) {\n const target = seq.target as Carrier;\n target.z ??= 0;\n target.rotationX ??= 0;\n target.rotationY ??= 0;\n this.display = new PerspectiveMesh({ texture: Texture.WHITE, verticesX: MESH_GRID, verticesY: MESH_GRID });\n if (seq.spec.name) this.display.label = seq.spec.name;\n this.display.visible = false;\n }\n\n update(host: SpaceHost, basis: CameraBasis): void {\n const target = this.seq.target as Carrier | null;\n // Pixi skips rendering (and clearing) a container that is not `visible`\n // (e.g. PixiPlugin autoAlpha at alpha 0), which would leave a stale texture.\n if (!target || !target.renderable || !target.visible) return this.hide();\n\n const bounds = this.frameOf();\n const pad = filterPadding(target);\n const needW = Math.ceil(bounds.width + 2 * pad);\n const needH = Math.ceil(bounds.height + 2 * pad);\n if (!(needW >= 1 && needH >= 1) || !Number.isFinite(bounds.x) || !Number.isFinite(bounds.y)) return this.hide();\n\n const size = this.sizeFor(needW, needH);\n // The quad covers exactly the texture's pixel rect in layer space.\n const frame: Rect = { x: bounds.x - pad, y: bounds.y - pad, width: size.w, height: size.h };\n const projected = projectLayer(readLayerTransform(target), frame, basis);\n this.depth = projected.depth;\n if (!projected.visible) {\n if (!this.warnedBehind) {\n this.warnedBehind = true;\n console.warn(\n `pixi-effects: ${describeLayer(this.seq.spec)} is at or behind the camera plane (z = ${(target.z ?? 0).toFixed(0)}) and is hidden. ` +\n `If that is unintended, lower its z or move the camera back (the default camera sits at z = (height/2)/tan(fov/2), about 989 for 720p at fov 40).`,\n );\n }\n return this.hide();\n }\n\n this.ensureTexture(size);\n // `transform` replaces the container's own local transform for this render\n // (Pixi RenderGroupSystem), while `container.alpha` still applies — so the\n // texture carries the layer's alpha and the mesh alpha stays at 1.\n host.render({\n container: target,\n target: this.rt!,\n transform: new Matrix().translate(-frame.x, -frame.y),\n clear: true,\n clearColor: [0, 0, 0, 0],\n });\n this.display.geometry.setCorners(...projected.corners);\n this.display.visible = true;\n }\n\n destroy(): void {\n this.display.destroy();\n this.rt?.destroy(true);\n this.rt = null;\n }\n\n private hide(): void {\n this.display.visible = false;\n }\n\n /**\n * Texture size for content of w×h. An existing texture is kept while it is at\n * least that big and at most 2x too big, so content whose bounds change every\n * frame (typewriter text, growing shapes) does not reallocate each frame.\n */\n private sizeFor(w: number, h: number): TextureSize {\n const cur = this.size;\n if (cur && cur.w >= w && cur.h >= h && cur.w <= 2 * w && cur.h <= 2 * h) return cur;\n const resolution = Math.min(\n SUPERSAMPLE,\n MAX_TEXTURE_SIZE / Math.max(w, h),\n Math.sqrt(MAX_TEXTURE_PIXELS / (w * h)),\n );\n const antialias = w * h * resolution * resolution <= ANTIALIAS_MAX_PIXELS;\n return { w, h, resolution, antialias };\n }\n\n private ensureTexture(size: TextureSize): void {\n if (this.rt && this.size === size) return;\n const next = RenderTexture.create({\n width: size.w, height: size.h, resolution: size.resolution, antialias: size.antialias,\n });\n this.display.texture = next;\n this.rt?.destroy(true);\n this.rt = next;\n this.size = size;\n }\n}\n","import { collectPropKeys } from './specKeys';\nimport { describeLayer } from '../core/lint';\nimport type { SequenceSpec } from '../types';\n\ntype Warn = (message: string) => void;\nconst defaultWarn: Warn = m => console.warn(m);\n\nconst FOV_HINT = 'perspective is the camera\\'s \"fov\" — add a { type: \"camera\" } layer and set fov in its initial / keyframes';\n\n/** Keys that are never valid for any layer, with a hint at what the author probably meant. */\nconst LAYER_ALIASES: Record<string, string> = {\n rotateX: 'did you mean \"rotationX\"?',\n rotateY: 'did you mean \"rotationY\"?',\n rotateZ: 'did you mean \"rotation\"?',\n rotationZ: 'did you mean \"rotation\" (it is the Z rotation)?',\n translateZ: 'did you mean \"z\"?',\n depth: 'did you mean \"z\"?',\n posZ: 'did you mean \"z\"?',\n perspective: FOV_HINT,\n zoom: FOV_HINT,\n};\n\n/** Camera-only mistakes. */\nconst CAMERA_ALIASES: Record<string, string> = {\n pointOfInterest: 'did you mean \"lookAtX / lookAtY / lookAtZ\"?',\n lookAt: 'did you mean \"lookAtX / lookAtY / lookAtZ\"?',\n};\n\nconst CAMERA_PROPS = ['x', 'y', 'z', 'fov', 'lookAtX', 'lookAtY', 'lookAtZ'];\nconst NEEDS_THREE_D = ['z', 'rotationX', 'rotationY'];\nconst SKEW_KEYS = ['skew', 'skewX', 'skewY'];\n\n/**\n * Warn (never throw) about the inputs an AI author is most likely to get wrong,\n * with a message that says what to change. One call per layer, at build time.\n */\nexport function lintSequence(spec: SequenceSpec, warn: Warn = defaultWarn): void {\n const who = describeLayer(spec);\n const keys = collectPropKeys(spec);\n const explained = new Set<string>();\n\n for (const k of keys) {\n const hint = LAYER_ALIASES[k] ?? (spec.type === 'camera' ? CAMERA_ALIASES[k] : undefined);\n if (hint) {\n explained.add(k);\n warn(`pixi-effects: ${who}: \"${k}\" is not a property — ${hint}`);\n }\n }\n\n if (spec.type === 'camera') {\n const raw = spec as unknown as Record<string, unknown>;\n for (const p of CAMERA_PROPS) {\n if (p in raw) warn(`pixi-effects: ${who}: \"${p}\" must go inside initial / keyframes, not on the camera itself`);\n }\n for (const k of Object.keys(raw)) {\n const hint = CAMERA_ALIASES[k] ?? LAYER_ALIASES[k];\n if (hint) warn(`pixi-effects: ${who}: \"${k}\" is not a property — ${hint} (inside initial)`);\n }\n for (const k of keys) {\n if (!explained.has(k) && !CAMERA_PROPS.includes(k)) {\n warn(`pixi-effects: ${who}: \"${k}\" has no effect on a camera (use ${CAMERA_PROPS.join(', ')})`);\n }\n }\n return;\n }\n\n if (spec.type === 'audio') {\n if (spec.threeD) warn(`pixi-effects: ${who}: threeD has no effect on audio`);\n return;\n }\n\n if (!spec.threeD) {\n for (const k of NEEDS_THREE_D) {\n if (keys.has(k)) warn(`pixi-effects: ${who}: \"${k}\" needs threeD: true (it is ignored otherwise)`);\n }\n } else {\n for (const k of SKEW_KEYS) {\n if (keys.has(k)) warn(`pixi-effects: ${who}: \"${k}\" is ignored on threeD layers`);\n }\n }\n}\n","import { Container, Rectangle } from 'pixi.js';\nimport { Sequence } from './Base';\nimport { buildSequenceTree } from '../core/Composition';\nimport { CameraSequence } from '../space/CameraSequence';\nimport { findOverlap, pickActiveCamera } from '../space/camera';\nimport { assignDepthOrder } from '../space/depth';\nimport { Layer3D, type SpaceHost } from '../space/Layer3D';\nimport { lintSequence } from '../space/lint';\nimport { describeLayer, lintText, lintTiming } from '../core/lint';\nimport { cameraBasis, homeCamera } from '../space/math';\nimport type { CompositionSequenceSpec, AudioDescriptor, CompositionShape, SequenceSpec } from '../types';\n\nimport type { gsap } from 'gsap';\ntype Timeline = ReturnType<typeof gsap.timeline>;\n\nexport class CompositionSequence extends Sequence {\n declare spec: CompositionSequenceSpec;\n private _innerContainer: Container | null = null;\n private _compositionShape: CompositionShape | null = null;\n _children: Sequence[] = [];\n private _cameras: CameraSequence[] = [];\n private _layers3d: Layer3D[] = [];\n /** Drawn children in stack order (cameras and target-less sequences excluded). */\n private _visual: Array<{ seq: Sequence; layer: Layer3D | null }> = [];\n\n async build(): Promise<void> {\n const width = this.spec.width ?? this.parent?.width ?? this.root.width;\n const height = this.spec.height ?? this.parent?.height ?? this.root.height;\n if (this.duration === undefined) {\n this.duration = this.spec.duration ?? this.parent?.duration ?? this.root.duration;\n }\n const wrapper = new Container();\n wrapper.cullable = true;\n wrapper.cullableChildren = true;\n wrapper.cullArea = new Rectangle(0, 0, width, height);\n\n const inner = new Container();\n inner.cullable = true;\n inner.cullableChildren = true;\n wrapper.addChild(inner);\n\n this.target = wrapper;\n this.intrinsicWidth = width;\n this.intrinsicHeight = height;\n this._innerContainer = inner;\n this._compositionShape = { width, height, duration: this.duration };\n\n for (const s of this.spec.sequences ?? []) {\n lintSequence(s);\n lintTiming(s, this.duration);\n lintText(s);\n }\n\n this._children = await buildSequenceTree(\n this.spec.sequences ?? [],\n this._compositionShape,\n this.root,\n );\n for (const child of this._children) {\n // Cameras are display-less: they only feed the projection pass.\n if (child instanceof CameraSequence) {\n this._cameras.push(child);\n continue;\n }\n if (!child.target) continue;\n\n const maskSpec = (child.spec as { mask?: SequenceSpec }).mask;\n\n // threeD layers never enter the scene graph themselves: their display\n // object is rendered into a texture and a perspective mesh stands in.\n if (child.spec.threeD) {\n const layer = new Layer3D(child, frameOf(child));\n inner.addChild(layer.display);\n this._layers3d.push(layer);\n this._visual.push({ seq: child, layer });\n if (maskSpec) {\n console.warn(`pixi-effects: ${describeLayer(child.spec)}: mask is not supported on threeD layers yet; ignored`);\n }\n continue;\n }\n\n inner.addChild(child.target);\n this._visual.push({ seq: child, layer: null });\n // If this child has a `mask` spec, build the mask sequence in the same\n // composition shape, add its target to the same parent (so its\n // transforms resolve in the same coord space), and wire PIXI's\n // mask channel. PIXI v8 renders mask containers into the stencil /\n // alpha buffer; they don't render as normal children.\n if (maskSpec) {\n const built = await buildSequenceTree([maskSpec], this._compositionShape, this.root);\n const maskSeq = built[0];\n if (maskSeq?.target) {\n inner.addChild(maskSeq.target);\n // PIXI v8 `setMask` accepts an `inverse` flag — that's how we\n // expose `maskInverted` from the spec. Falls back to plain\n // `target.mask = …` for runtimes that don't have setMask\n // (older PIXI builds).\n const inverse = (child.spec as { maskInverted?: boolean }).maskInverted ?? false;\n const t = child.target as Container & {\n setMask?: (opts: { mask: Container | null; inverse?: boolean }) => void;\n mask: Container | null;\n };\n if (typeof t.setMask === 'function') {\n t.setMask({ mask: maskSeq.target, inverse });\n } else {\n t.mask = maskSeq.target;\n }\n child.maskSequence = maskSeq;\n }\n }\n }\n\n if (this._layers3d.length > 0) {\n // Stack order becomes explicit zIndex so threeD layers can be re-sorted\n // by depth each frame without reparenting.\n inner.sortableChildren = true;\n this._visual.forEach((v, i) => {\n (v.layer?.display ?? v.seq.target!).zIndex = i;\n });\n } else if (this._cameras.length > 0) {\n console.warn('pixi-effects: camera has no effect: this composition has no threeD layers');\n }\n\n this.buildFilters();\n }\n\n override bindTimeline(timeline: Timeline, offset = 0): void {\n super.bindTimeline(timeline, offset);\n // Children's `at` is relative to this composition's start, so push them\n // forward by our absolute start time on the global timeline.\n const childOffset = offset + this.at;\n for (const child of this._children) {\n child.bindTimeline(timeline, childOffset);\n // The mask shares the maskee's offset — its `at` is interpreted\n // relative to the composition's start, just like the child itself,\n // so a reveal-from-zero animation lines up naturally.\n child.maskSequence?.bindTimeline(timeline, childOffset);\n }\n const overlap = findOverlap(this._cameras.map(c => c.window()));\n if (overlap) {\n console.warn(`pixi-effects: cameras #${overlap[0] + 1} and #${overlap[1] + 1} overlap in time; the top-most one wins`);\n }\n }\n\n /** Drawn children in stack order, with the display object that stands in for each (the mesh for a threeD layer). */\n layers(): Array<{ seq: Sequence; display: Container; threeD: boolean }> {\n return this._visual.map(v => ({\n seq: v.seq,\n display: (v.layer?.display ?? v.seq.target!) as unknown as Container,\n threeD: v.layer !== null,\n }));\n }\n\n override updateSpace(t: number, host: SpaceHost): void {\n // Inner compositions first: a threeD composition is rendered into its own\n // texture by this level, so its content must already be projected.\n for (const child of this._children) child.updateSpace(t, host);\n if (this._layers3d.length === 0 || !this._compositionShape) return;\n\n const { width, height } = this._compositionShape;\n const compEnd = (this.absoluteStart ?? 0) + (this.duration ?? 0);\n const active = pickActiveCamera(\n this._cameras.map(cam => ({ cam, ...cam.window() })),\n t,\n compEnd,\n );\n const basis = cameraBasis(active ? active.cam.state() : homeCamera(width, height), width, height);\n\n for (const layer of this._layers3d) layer.update(host, basis);\n\n const order = assignDepthOrder(\n this._visual.map((v, i) => ({ stackIndex: i, threeD: v.layer !== null, depth: v.layer?.depth ?? 0 })),\n );\n this._visual.forEach((v, i) => {\n if (v.layer) v.layer.display.zIndex = order[i]!;\n });\n }\n\n override collectAudio(out: AudioDescriptor[], baseTime: number): void {\n super.collectAudio(out, baseTime);\n const childBase = baseTime + this.at;\n for (const child of this._children) child.collectAudio(out, childBase);\n }\n\n override destroy(): void {\n for (const l of this._layers3d) l.destroy();\n this._layers3d = [];\n for (const c of this._children) c.destroy();\n super.destroy();\n }\n}\n\n/** Layer-space rectangle a threeD child projects: a composition's frame, otherwise its content bounds. */\nfunction frameOf(child: Sequence): () => { x: number; y: number; width: number; height: number } {\n if (child instanceof CompositionSequence) {\n return () => ({ x: 0, y: 0, width: child.intrinsicWidth, height: child.intrinsicHeight });\n }\n return () => child.target!.getLocalBounds();\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkZL262ZRM_cjs = require('./chunk-ZL262ZRM.cjs');
|
|
4
|
+
var chunkSIRVULFF_cjs = require('./chunk-SIRVULFF.cjs');
|
|
5
5
|
var PIXI = require('pixi.js');
|
|
6
6
|
var gsap = require('gsap');
|
|
7
7
|
var PixiPlugin = require('gsap/PixiPlugin');
|
|
@@ -617,43 +617,48 @@ function expandTransitions(spec) {
|
|
|
617
617
|
if (toUses > 1) {
|
|
618
618
|
throw new Error(`pixi-effects: ${tag} sequence "${t.to}" is used as \`to\` in more than one transition`);
|
|
619
619
|
}
|
|
620
|
-
const tStart =
|
|
620
|
+
const tStart = chunkSIRVULFF_cjs.resolveAt(t.at, parentDuration);
|
|
621
621
|
const tEnd = tStart + t.duration;
|
|
622
622
|
const fromSeq = fromEntry.seq;
|
|
623
|
-
const fromStart =
|
|
623
|
+
const fromStart = chunkSIRVULFF_cjs.resolveAt(fromSeq.at, parentDuration);
|
|
624
624
|
const fromEnd = fromStart + (fromSeq.duration ?? parentDuration);
|
|
625
625
|
if (tStart < fromStart || tEnd > fromEnd) {
|
|
626
626
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`from\` "${t.from}" (lives [${fromStart}, ${fromEnd}], so it ends at ${fromEnd})`);
|
|
627
627
|
}
|
|
628
628
|
const toSeq = toEntry.seq;
|
|
629
|
-
const toStart =
|
|
629
|
+
const toStart = chunkSIRVULFF_cjs.resolveAt(toSeq.at, parentDuration);
|
|
630
630
|
const toEnd = toStart + (toSeq.duration ?? parentDuration);
|
|
631
631
|
if (tStart < toStart || tEnd > toEnd) {
|
|
632
632
|
throw new Error(`pixi-effects: ${tag} window [${tStart}, ${tEnd}] is not covered by \`to\` "${t.to}" (lives [${toStart}, ${toEnd}], so it starts at ${toStart})`);
|
|
633
633
|
}
|
|
634
|
-
|
|
634
|
+
const abs = { ...t, at: tStart };
|
|
635
|
+
const nFrom = keyframeCount(fromEntry.seq);
|
|
636
|
+
const nTo = keyframeCount(toEntry.seq);
|
|
637
|
+
switch (abs.kind) {
|
|
635
638
|
case "crossfade":
|
|
636
|
-
expandCrossfade(out,
|
|
639
|
+
expandCrossfade(out, abs, fromEntry.seq, toEntry.seq);
|
|
637
640
|
break;
|
|
638
641
|
case "wipe":
|
|
639
|
-
expandMask(out,
|
|
642
|
+
expandMask(out, abs, fromEntry.seq, toEntry.seq, i, wipeMode(abs.direction), abs.smoothing);
|
|
640
643
|
break;
|
|
641
644
|
case "iris":
|
|
642
|
-
expandMask(out,
|
|
645
|
+
expandMask(out, abs, fromEntry.seq, toEntry.seq, i, abs.mode === "out" ? "iris-out" : "iris-in", abs.smoothing);
|
|
643
646
|
break;
|
|
644
647
|
case "slide":
|
|
645
|
-
expandSlide(out,
|
|
648
|
+
expandSlide(out, abs, fromEntry.seq, toEntry.seq);
|
|
646
649
|
break;
|
|
647
650
|
case "dip":
|
|
648
|
-
expandDip(out,
|
|
651
|
+
expandDip(out, abs, fromEntry.seq, toEntry.seq);
|
|
649
652
|
break;
|
|
650
653
|
case "zoom":
|
|
651
|
-
expandZoom(out,
|
|
654
|
+
expandZoom(out, abs, fromEntry.seq, toEntry.seq);
|
|
652
655
|
break;
|
|
653
656
|
case "dissolve":
|
|
654
|
-
expandDissolve(out,
|
|
657
|
+
expandDissolve(out, abs, fromEntry.seq, toEntry.seq, i);
|
|
655
658
|
break;
|
|
656
659
|
}
|
|
660
|
+
rebaseNewKeyframes(fromEntry.seq, nFrom, fromStart);
|
|
661
|
+
rebaseNewKeyframes(toEntry.seq, nTo, toStart);
|
|
657
662
|
}
|
|
658
663
|
delete out.transitions;
|
|
659
664
|
return out;
|
|
@@ -685,6 +690,17 @@ function wrapAsFullComposition(seq, compW, compH) {
|
|
|
685
690
|
sequences: [inner]
|
|
686
691
|
};
|
|
687
692
|
}
|
|
693
|
+
function keyframeCount(seq) {
|
|
694
|
+
return seq.keyframes?.length ?? 0;
|
|
695
|
+
}
|
|
696
|
+
function rebaseNewKeyframes(seq, from, seqStart) {
|
|
697
|
+
const kfs = seq.keyframes;
|
|
698
|
+
if (!kfs) return;
|
|
699
|
+
for (let i = from; i < kfs.length; i++) {
|
|
700
|
+
const kf = kfs[i];
|
|
701
|
+
if (typeof kf.at === "number") kfs[i] = { ...kf, at: kf.at - seqStart };
|
|
702
|
+
}
|
|
703
|
+
}
|
|
688
704
|
function ensureKeyframes(seq) {
|
|
689
705
|
const s = seq;
|
|
690
706
|
if (!s.keyframes) s.keyframes = [];
|
|
@@ -901,6 +917,153 @@ function rejectReservedNameCollision(filters, seqName) {
|
|
|
901
917
|
}
|
|
902
918
|
}
|
|
903
919
|
|
|
920
|
+
// src/core/inspect.ts
|
|
921
|
+
var FAINT = 0.3;
|
|
922
|
+
var intersection = (a, b) => {
|
|
923
|
+
const w = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);
|
|
924
|
+
const h = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);
|
|
925
|
+
return w > 0 && h > 0 ? w * h : 0;
|
|
926
|
+
};
|
|
927
|
+
function inspectScene(root, frame, time, canvas, opts = {}) {
|
|
928
|
+
const layers = [];
|
|
929
|
+
const view = { x: 0, y: 0, width: canvas.width, height: canvas.height };
|
|
930
|
+
const walk = (comp, prefix, insideThreeD, parentVisible) => {
|
|
931
|
+
comp.layers().forEach(({ seq, display, threeD }, i) => {
|
|
932
|
+
const t = seq.target;
|
|
933
|
+
const name = seq.spec.name;
|
|
934
|
+
const label = name ?? `${seq.spec.type}#${i}`;
|
|
935
|
+
const alpha = t?.alpha ?? 1;
|
|
936
|
+
const alive = threeD ? display.visible : t?.renderable ?? true;
|
|
937
|
+
const visible = parentVisible && alive && alpha > 0;
|
|
938
|
+
let bounds = null;
|
|
939
|
+
if (!insideThreeD) {
|
|
940
|
+
const b = display.getBounds();
|
|
941
|
+
bounds = { x: b.x, y: b.y, width: b.width, height: b.height };
|
|
942
|
+
}
|
|
943
|
+
let onCanvas = null;
|
|
944
|
+
if (bounds) {
|
|
945
|
+
const inter = intersection(bounds, view);
|
|
946
|
+
const area = bounds.width * bounds.height;
|
|
947
|
+
onCanvas = inter === 0 && area > 0 ? "none" : inter >= area - 1e-6 ? "full" : "partial";
|
|
948
|
+
if (area === 0) onCanvas = "none";
|
|
949
|
+
}
|
|
950
|
+
const keys = chunkSIRVULFF_cjs.collectPropKeys(seq.spec);
|
|
951
|
+
const moving = (seq.spec.keyframes ?? []).length > 0 && (keys.has("x") || keys.has("y"));
|
|
952
|
+
layers.push({ path: prefix + label, name, type: seq.spec.type, threeD, visible, alpha, moving, bounds, onCanvas });
|
|
953
|
+
if (seq instanceof chunkZL262ZRM_cjs.CompositionSequence) walk(seq, prefix + label + "/", insideThreeD || threeD, visible);
|
|
954
|
+
});
|
|
955
|
+
};
|
|
956
|
+
walk(root, "", false, true);
|
|
957
|
+
const issues = [];
|
|
958
|
+
const texts = layers.filter((l) => l.type === "text" && l.visible && l.alpha >= FAINT && l.bounds);
|
|
959
|
+
for (const l of texts) {
|
|
960
|
+
const b = l.bounds;
|
|
961
|
+
const who = `text layer "${l.path}"`;
|
|
962
|
+
if (b.width < 1 || b.height < 1) {
|
|
963
|
+
issues.push(`${who} has no size (empty text, or not drawn yet)`);
|
|
964
|
+
} else if (l.moving) ; else if (l.onCanvas === "none") {
|
|
965
|
+
issues.push(`${who} is entirely outside the canvas (at ${Math.round(b.x)},${Math.round(b.y)}, ${Math.round(b.width)}\xD7${Math.round(b.height)})`);
|
|
966
|
+
} else if (l.onCanvas === "partial") {
|
|
967
|
+
const over = [];
|
|
968
|
+
if (b.x < 0) over.push(`${Math.round(-b.x)}px beyond the left edge`);
|
|
969
|
+
if (b.x + b.width > canvas.width) over.push(`${Math.round(b.x + b.width - canvas.width)}px beyond the right edge`);
|
|
970
|
+
if (b.y < 0) over.push(`${Math.round(-b.y)}px beyond the top edge`);
|
|
971
|
+
if (b.y + b.height > canvas.height) over.push(`${Math.round(b.y + b.height - canvas.height)}px beyond the bottom edge`);
|
|
972
|
+
issues.push(`${who} is cut off by the canvas edge: ${over.join(", ")}`);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
for (let i = 0; i < texts.length; i++) {
|
|
976
|
+
for (let j = i + 1; j < texts.length; j++) {
|
|
977
|
+
const a = texts[i].bounds, b = texts[j].bounds;
|
|
978
|
+
const smaller = Math.min(a.width * a.height, b.width * b.height);
|
|
979
|
+
if (smaller <= 0) continue;
|
|
980
|
+
const share = intersection(a, b) / smaller;
|
|
981
|
+
if (share > 0.25) issues.push(`text layers "${texts[i].path}" and "${texts[j].path}" overlap by ${Math.round(share * 100)}% of the smaller one`);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
const mode = opts.layers ?? "all";
|
|
985
|
+
const listed = mode === "none" ? [] : mode === "visible" ? layers.filter((l) => l.visible) : layers;
|
|
986
|
+
return { frame, time, canvas, summary: { layers: layers.length, visible: layers.filter((l) => l.visible).length }, issues, layers: listed };
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// src/core/frames.ts
|
|
990
|
+
function pickFrames(lastFrame, count) {
|
|
991
|
+
const last = Math.max(0, Math.floor(lastFrame));
|
|
992
|
+
const n = Math.max(1, Math.floor(count));
|
|
993
|
+
if (n === 1) return [0];
|
|
994
|
+
const out = [];
|
|
995
|
+
for (let i = 0; i < n; i++) {
|
|
996
|
+
const f = Math.round(last * i / (n - 1));
|
|
997
|
+
if (out[out.length - 1] !== f) out.push(f);
|
|
998
|
+
}
|
|
999
|
+
return out;
|
|
1000
|
+
}
|
|
1001
|
+
function sheetLayout(n, columns, cellW, srcW, srcH, labelH) {
|
|
1002
|
+
const cols = Math.max(1, Math.min(Math.floor(columns), n));
|
|
1003
|
+
const rows = Math.ceil(n / cols);
|
|
1004
|
+
const cellH = Math.round(cellW * srcH / srcW);
|
|
1005
|
+
const positions = Array.from({ length: n }, (_, i) => ({ x: i % cols * cellW, y: Math.floor(i / cols) * (cellH + labelH) }));
|
|
1006
|
+
return { cols, rows, cellW, cellH, width: cols * cellW, height: rows * (cellH + labelH), positions };
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// src/core/options.ts
|
|
1010
|
+
function distance(a, b) {
|
|
1011
|
+
const dp = Array.from({ length: a.length + 1 }, (_, i) => [i, ...Array(b.length).fill(0)]);
|
|
1012
|
+
for (let j = 1; j <= b.length; j++) dp[0][j] = j;
|
|
1013
|
+
for (let i = 1; i <= a.length; i++) {
|
|
1014
|
+
for (let j = 1; j <= b.length; j++) {
|
|
1015
|
+
dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
1016
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) dp[i][j] = Math.min(dp[i][j], dp[i - 2][j - 2] + 1);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
return dp[a.length][b.length];
|
|
1020
|
+
}
|
|
1021
|
+
var isSubsequence = (small, big) => {
|
|
1022
|
+
let i = 0;
|
|
1023
|
+
for (const ch of big) if (i < small.length && ch === small[i]) i++;
|
|
1024
|
+
return i === small.length;
|
|
1025
|
+
};
|
|
1026
|
+
var COMMON_ALIASES = {
|
|
1027
|
+
fps: "frameRate",
|
|
1028
|
+
framerate: "frameRate",
|
|
1029
|
+
frame_rate: "frameRate",
|
|
1030
|
+
bg: "background",
|
|
1031
|
+
backgroundcolor: "background",
|
|
1032
|
+
bgcolor: "background",
|
|
1033
|
+
seconds: "duration",
|
|
1034
|
+
length: "duration",
|
|
1035
|
+
time: "duration",
|
|
1036
|
+
w: "width",
|
|
1037
|
+
h: "height",
|
|
1038
|
+
cols: "columns",
|
|
1039
|
+
sweep: "degrees",
|
|
1040
|
+
angle: "degrees"
|
|
1041
|
+
};
|
|
1042
|
+
function suggestName(name, valid) {
|
|
1043
|
+
const n = name.toLowerCase();
|
|
1044
|
+
const alias = COMMON_ALIASES[n];
|
|
1045
|
+
if (alias && valid.includes(alias)) return alias;
|
|
1046
|
+
let best = null;
|
|
1047
|
+
for (const v of valid) {
|
|
1048
|
+
const lv = v.toLowerCase();
|
|
1049
|
+
const d = distance(n, lv);
|
|
1050
|
+
const close = d <= Math.max(1, Math.floor(Math.min(n.length, lv.length) / 3));
|
|
1051
|
+
const abbreviation = n.length >= 3 && isSubsequence(n, lv) || lv.length >= 2 && n.length > lv.length && n.includes(lv);
|
|
1052
|
+
if (!close && !abbreviation) continue;
|
|
1053
|
+
const score = close ? d : 3 + (lv.length - n.length) / 100;
|
|
1054
|
+
if (!best || score < best.score) best = { v, score };
|
|
1055
|
+
}
|
|
1056
|
+
return best ? best.v : null;
|
|
1057
|
+
}
|
|
1058
|
+
function warnUnknownOptions(where, opts, valid) {
|
|
1059
|
+
if (!opts || typeof opts !== "object") return;
|
|
1060
|
+
for (const key of Object.keys(opts)) {
|
|
1061
|
+
if (valid.includes(key)) continue;
|
|
1062
|
+
const guess = suggestName(key, valid);
|
|
1063
|
+
console.warn(`pixi-effects: ${where}: unknown option "${key}"${guess ? ` \u2014 did you mean "${guess}"?` : ""} (valid: ${valid.join(", ")})`);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
904
1067
|
// src/core/Movie.ts
|
|
905
1068
|
PIXI.extensions.add(PIXI.CullerPlugin);
|
|
906
1069
|
gsap.gsap.registerPlugin(PixiPlugin.PixiPlugin);
|
|
@@ -959,6 +1122,7 @@ var Movie = class {
|
|
|
959
1122
|
return this._audioContext;
|
|
960
1123
|
}
|
|
961
1124
|
async init(options = {}) {
|
|
1125
|
+
warnUnknownOptions("movie.init()", options, ["width", "height", "duration", "frameRate", "background", "canvas", "assets", "composition"]);
|
|
962
1126
|
this._initState = "pending";
|
|
963
1127
|
try {
|
|
964
1128
|
this.width = options.width ?? 1920;
|
|
@@ -1010,7 +1174,7 @@ var Movie = class {
|
|
|
1010
1174
|
duration: this.duration,
|
|
1011
1175
|
...userComposition
|
|
1012
1176
|
};
|
|
1013
|
-
const composition = new
|
|
1177
|
+
const composition = new chunkZL262ZRM_cjs.CompositionSequence(rootSeqSpec, null, rootShape);
|
|
1014
1178
|
await composition.build();
|
|
1015
1179
|
this._rootSequence = composition;
|
|
1016
1180
|
if (composition.target) root.addChild(composition.target);
|
|
@@ -1023,7 +1187,7 @@ var Movie = class {
|
|
|
1023
1187
|
this.timeline.progress(1).progress(0);
|
|
1024
1188
|
await this._awaitVideoFrames();
|
|
1025
1189
|
this._updateSpace();
|
|
1026
|
-
this.
|
|
1190
|
+
this._renderNow();
|
|
1027
1191
|
this._initState = "ready";
|
|
1028
1192
|
this.emit("ready");
|
|
1029
1193
|
} catch (err) {
|
|
@@ -1042,7 +1206,7 @@ var Movie = class {
|
|
|
1042
1206
|
this.timeline.time(this.currentFrame / this.frameRate);
|
|
1043
1207
|
await this._awaitVideoFrames();
|
|
1044
1208
|
this._updateSpace();
|
|
1045
|
-
this.
|
|
1209
|
+
this._renderNow();
|
|
1046
1210
|
this.emit("frame", { frame: this.currentFrame, totalFrames: this.totalFrames });
|
|
1047
1211
|
}
|
|
1048
1212
|
async _awaitVideoFrames() {
|
|
@@ -1056,6 +1220,75 @@ var Movie = class {
|
|
|
1056
1220
|
return v.awaitFrameAt(local);
|
|
1057
1221
|
}));
|
|
1058
1222
|
}
|
|
1223
|
+
async snapshot(frame = this.currentFrame, opts = {}) {
|
|
1224
|
+
warnUnknownOptions("movie.snapshot()", opts, ["scale", "type", "as"]);
|
|
1225
|
+
this._requireReady("snapshot");
|
|
1226
|
+
await this.gotoFrame(clampFrame(frame, this.totalFrames), true);
|
|
1227
|
+
const scale = opts.scale ?? 1;
|
|
1228
|
+
const out = document.createElement("canvas");
|
|
1229
|
+
out.width = Math.max(1, Math.round(this.width * scale));
|
|
1230
|
+
out.height = Math.max(1, Math.round(this.height * scale));
|
|
1231
|
+
out.getContext("2d").drawImage(this.app.canvas, 0, 0, out.width, out.height);
|
|
1232
|
+
return encodeCanvas(out, opts.type ?? "image/png", opts.as ?? "blob");
|
|
1233
|
+
}
|
|
1234
|
+
async contactSheet(opts = {}) {
|
|
1235
|
+
warnUnknownOptions("movie.contactSheet()", opts, ["frames", "times", "count", "columns", "cellWidth", "as"]);
|
|
1236
|
+
this._requireReady("contactSheet");
|
|
1237
|
+
const frames = (opts.frames ?? opts.times?.map((t) => Math.round(t * this.frameRate)) ?? pickFrames(this.totalFrames, opts.count ?? 6)).map((f) => clampFrame(f, this.totalFrames));
|
|
1238
|
+
const LABEL_H = 26;
|
|
1239
|
+
const L = sheetLayout(frames.length, opts.columns ?? 3, opts.cellWidth ?? 480, this.width, this.height, LABEL_H);
|
|
1240
|
+
const sheet = document.createElement("canvas");
|
|
1241
|
+
sheet.width = L.width;
|
|
1242
|
+
sheet.height = L.height;
|
|
1243
|
+
const g = sheet.getContext("2d");
|
|
1244
|
+
g.fillStyle = "#10131c";
|
|
1245
|
+
g.fillRect(0, 0, L.width, L.height);
|
|
1246
|
+
const back = this.currentFrame;
|
|
1247
|
+
try {
|
|
1248
|
+
for (let i = 0; i < frames.length; i++) {
|
|
1249
|
+
const f = frames[i];
|
|
1250
|
+
await this.gotoFrame(f, true);
|
|
1251
|
+
const { x, y } = L.positions[i];
|
|
1252
|
+
g.drawImage(this.app.canvas, x, y + LABEL_H, L.cellW, L.cellH);
|
|
1253
|
+
g.fillStyle = "#e8ecf8";
|
|
1254
|
+
g.font = "600 15px system-ui, sans-serif";
|
|
1255
|
+
g.textBaseline = "middle";
|
|
1256
|
+
g.fillText(`frame ${f} \xB7 ${(f / this.frameRate).toFixed(2)}s`, x + 8, y + LABEL_H / 2);
|
|
1257
|
+
}
|
|
1258
|
+
} finally {
|
|
1259
|
+
await this.gotoFrame(back, true);
|
|
1260
|
+
}
|
|
1261
|
+
return encodeCanvas(sheet, "image/png", opts.as ?? "blob");
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Where every layer is drawn at `frame` (canvas pixels, visibility) plus `issues` — text that is off
|
|
1265
|
+
* the canvas, cut by an edge, empty, or overlapping other text. Seeks there and stays there.
|
|
1266
|
+
*/
|
|
1267
|
+
async inspect(frame = this.currentFrame, opts = { layers: "visible" }) {
|
|
1268
|
+
warnUnknownOptions("movie.inspect()", opts, ["layers"]);
|
|
1269
|
+
this._requireReady("inspect");
|
|
1270
|
+
const f = clampFrame(frame, this.totalFrames);
|
|
1271
|
+
await this.gotoFrame(f, true);
|
|
1272
|
+
return inspectScene(this._rootSequence, f, f / this.frameRate, { width: this.width, height: this.height }, opts);
|
|
1273
|
+
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Draw the stage now. PixiJS's CullerPlugin only culls inside `app.render()` (the ticker), and we render
|
|
1276
|
+
* by hand — while seeking and especially during `render()`, which stops the ticker — so without this the
|
|
1277
|
+
* `culled` flags are whatever the last tick left: a layer that is now on screen can stay culled and be
|
|
1278
|
+
* missing from the frame or from the exported video. Cull again (updating transforms: the timeline just
|
|
1279
|
+
* moved things) right before drawing.
|
|
1280
|
+
*/
|
|
1281
|
+
_renderNow() {
|
|
1282
|
+
const app = this.app;
|
|
1283
|
+
if (!app?.renderer) return;
|
|
1284
|
+
PIXI.Culler.shared.cull(app.stage, app.renderer.screen, false);
|
|
1285
|
+
app.renderer.render({ container: app.stage });
|
|
1286
|
+
}
|
|
1287
|
+
_requireReady(what) {
|
|
1288
|
+
if (this._initState !== "ready" || !this._rootSequence || !this.app) {
|
|
1289
|
+
throw new Error(`pixi-effects: movie.${what}() needs a ready movie \u2014 await movie.init(...) first`);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1059
1292
|
/** Projects every `threeD` layer for the current frame (see src/space). */
|
|
1060
1293
|
_updateSpace() {
|
|
1061
1294
|
if (!this._rootSequence || !this.app) return;
|
|
@@ -1141,6 +1374,7 @@ var Movie = class {
|
|
|
1141
1374
|
return this.muted;
|
|
1142
1375
|
}
|
|
1143
1376
|
async render(options) {
|
|
1377
|
+
warnUnknownOptions("movie.render()", options, ["format", "video", "audio"]);
|
|
1144
1378
|
return await exportFrames(this, options);
|
|
1145
1379
|
}
|
|
1146
1380
|
async destroy() {
|
|
@@ -1158,6 +1392,11 @@ var Movie = class {
|
|
|
1158
1392
|
this._initState = "destroyed";
|
|
1159
1393
|
}
|
|
1160
1394
|
};
|
|
1395
|
+
var clampFrame = (f, last) => Math.max(0, Math.min(Math.round(f), last));
|
|
1396
|
+
function encodeCanvas(canvas, type, as) {
|
|
1397
|
+
if (as === "dataURL") return Promise.resolve(canvas.toDataURL(type));
|
|
1398
|
+
return new Promise((resolve, reject) => canvas.toBlob((b) => b ? resolve(b) : reject(new Error("pixi-effects: could not encode the image")), type));
|
|
1399
|
+
}
|
|
1161
1400
|
function safeRun(fn) {
|
|
1162
1401
|
try {
|
|
1163
1402
|
fn();
|
|
@@ -1176,7 +1415,9 @@ function collectVideoSequences(seq, out) {
|
|
|
1176
1415
|
}
|
|
1177
1416
|
|
|
1178
1417
|
// src/presets/kenBurns.ts
|
|
1418
|
+
var KEN_BURNS_KEYS = ["asset", "name", "at", "duration", "fit", "ease", "motion", "origin", "zoom", "direction", "angle", "from", "to"];
|
|
1179
1419
|
function kenBurns(opts) {
|
|
1420
|
+
warnUnknownOptions("kenBurns()", opts, KEN_BURNS_KEYS);
|
|
1180
1421
|
const {
|
|
1181
1422
|
asset,
|
|
1182
1423
|
name,
|
|
@@ -1186,7 +1427,6 @@ function kenBurns(opts) {
|
|
|
1186
1427
|
ease = "sine.inOut"
|
|
1187
1428
|
} = opts;
|
|
1188
1429
|
const baseScale = fit;
|
|
1189
|
-
const baseAt = at ?? 0;
|
|
1190
1430
|
let initial;
|
|
1191
1431
|
let keyframes;
|
|
1192
1432
|
if (opts.motion === "still") {
|
|
@@ -1217,7 +1457,7 @@ function kenBurns(opts) {
|
|
|
1217
1457
|
scale: initialScale
|
|
1218
1458
|
};
|
|
1219
1459
|
keyframes = [
|
|
1220
|
-
{ at:
|
|
1460
|
+
{ at: 0, to: { scale: `${baseScale} * ${toZ}` }, duration, ease }
|
|
1221
1461
|
];
|
|
1222
1462
|
} else if (opts.motion === "rotation") {
|
|
1223
1463
|
const angle = clamp(opts.angle ?? 8, 0, 30);
|
|
@@ -1248,7 +1488,7 @@ function kenBurns(opts) {
|
|
|
1248
1488
|
const tHere = duration * tFrac;
|
|
1249
1489
|
const tPrev = duration * ((i - 1) / (sampleCount - 1));
|
|
1250
1490
|
keyframes.push({
|
|
1251
|
-
at:
|
|
1491
|
+
at: tPrev,
|
|
1252
1492
|
to: { rotation: angleHere, scale: scaleAt(angleHere) },
|
|
1253
1493
|
duration: tHere - tPrev,
|
|
1254
1494
|
ease: i === 1 ? ease : "none"
|
|
@@ -1269,7 +1509,7 @@ function kenBurns(opts) {
|
|
|
1269
1509
|
scale: scaleExpr
|
|
1270
1510
|
};
|
|
1271
1511
|
keyframes = [
|
|
1272
|
-
{ at:
|
|
1512
|
+
{ at: 0, to: { x: xExpr(to[0]), y: yExpr(to[1]) }, duration, ease }
|
|
1273
1513
|
];
|
|
1274
1514
|
}
|
|
1275
1515
|
const spec = {
|
|
@@ -1286,13 +1526,72 @@ function kenBurns(opts) {
|
|
|
1286
1526
|
function clamp(v, lo, hi) {
|
|
1287
1527
|
return Math.max(lo, Math.min(hi, v));
|
|
1288
1528
|
}
|
|
1529
|
+
function parseEase(name) {
|
|
1530
|
+
return gsap.gsap.parseEase(name);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
// src/presets/orbit.ts
|
|
1534
|
+
var ORBIT_KEYS = ["duration", "degrees", "start", "radius", "center", "width", "height", "fov", "ease", "dollyZoom", "at", "name", "stepsPerSecond"];
|
|
1535
|
+
function orbit(opts) {
|
|
1536
|
+
warnUnknownOptions("orbit()", opts, ORBIT_KEYS);
|
|
1537
|
+
const {
|
|
1538
|
+
duration,
|
|
1539
|
+
degrees,
|
|
1540
|
+
width = 1280,
|
|
1541
|
+
height = 720,
|
|
1542
|
+
fov,
|
|
1543
|
+
ease = "sine.inOut",
|
|
1544
|
+
stepsPerSecond = 10
|
|
1545
|
+
} = opts;
|
|
1546
|
+
if (!(duration > 0)) throw new Error(`pixi-effects: orbit duration must be > 0 (got ${duration})`);
|
|
1547
|
+
const dolly = opts.dollyZoom;
|
|
1548
|
+
if (dolly && opts.radius !== void 0) {
|
|
1549
|
+
throw new Error("pixi-effects: orbit() cannot combine `radius` with `dollyZoom` \u2014 the radius follows the animated fov");
|
|
1550
|
+
}
|
|
1551
|
+
const [cx, cy] = opts.center ?? [width / 2, height / 2];
|
|
1552
|
+
const fixedR = opts.radius ?? chunkSIRVULFF_cjs.homeDistance(height, fov ?? chunkSIRVULFF_cjs.DEFAULT_FOV);
|
|
1553
|
+
const start = opts.start ?? -degrees / 2;
|
|
1554
|
+
const steps = Math.max(1, Math.round(duration * stepsPerSecond));
|
|
1555
|
+
const easeFn = parseEase(ease);
|
|
1556
|
+
const dollyEase = dolly ? parseEase(dolly.ease ?? ease) : null;
|
|
1557
|
+
const pos = (i) => {
|
|
1558
|
+
const p = i / steps;
|
|
1559
|
+
const a = (start + degrees * easeFn(p)) * chunkSIRVULFF_cjs.DEG;
|
|
1560
|
+
if (!dolly) return { x: cx + fixedR * Math.sin(a), z: fixedR * Math.cos(a) };
|
|
1561
|
+
const f = dolly.from + (dolly.to - dolly.from) * dollyEase(p);
|
|
1562
|
+
const R = chunkSIRVULFF_cjs.homeDistance(height, f);
|
|
1563
|
+
return { x: cx + R * Math.sin(a), z: R * Math.cos(a), fov: f };
|
|
1564
|
+
};
|
|
1565
|
+
const keyframes = [];
|
|
1566
|
+
for (let i = 0; i < steps; i++) {
|
|
1567
|
+
keyframes.push({ at: duration * i / steps, to: pos(i + 1), duration: duration / steps, ease: "none" });
|
|
1568
|
+
}
|
|
1569
|
+
const p0 = pos(0);
|
|
1570
|
+
const spec = {
|
|
1571
|
+
type: "camera",
|
|
1572
|
+
duration,
|
|
1573
|
+
initial: {
|
|
1574
|
+
x: p0.x,
|
|
1575
|
+
y: cy,
|
|
1576
|
+
z: p0.z,
|
|
1577
|
+
lookAtX: cx,
|
|
1578
|
+
lookAtY: cy,
|
|
1579
|
+
lookAtZ: 0,
|
|
1580
|
+
...p0.fov !== void 0 ? { fov: p0.fov } : fov !== void 0 ? { fov } : {}
|
|
1581
|
+
},
|
|
1582
|
+
keyframes
|
|
1583
|
+
};
|
|
1584
|
+
if (opts.at !== void 0) spec.at = opts.at;
|
|
1585
|
+
if (opts.name !== void 0) spec.name = opts.name;
|
|
1586
|
+
return spec;
|
|
1587
|
+
}
|
|
1289
1588
|
|
|
1290
1589
|
// src/transforms/withFade.ts
|
|
1291
1590
|
function withFade(spec, opts) {
|
|
1292
|
-
|
|
1591
|
+
warnUnknownOptions("withFade()", opts, ["in", "out"]);
|
|
1293
1592
|
if (opts.in != null && opts.in > 0) {
|
|
1294
1593
|
spec.initial = { ...spec.initial ?? {}, alpha: 0 };
|
|
1295
|
-
const kf = { at, to: { alpha: 1 }, duration: opts.in };
|
|
1594
|
+
const kf = { at: 0, to: { alpha: 1 }, duration: opts.in };
|
|
1296
1595
|
spec.keyframes = [...spec.keyframes ?? [], kf];
|
|
1297
1596
|
}
|
|
1298
1597
|
if (opts.out != null && opts.out > 0) {
|
|
@@ -1301,7 +1600,7 @@ function withFade(spec, opts) {
|
|
|
1301
1600
|
"withFade(spec, { out }) requires spec.duration to be set so the fade-out can be anchored to the sequence end. Set spec.duration before passing the spec in."
|
|
1302
1601
|
);
|
|
1303
1602
|
}
|
|
1304
|
-
const kf = { at:
|
|
1603
|
+
const kf = { at: spec.duration - opts.out, to: { alpha: 0 }, duration: opts.out };
|
|
1305
1604
|
spec.keyframes = [...spec.keyframes ?? [], kf];
|
|
1306
1605
|
}
|
|
1307
1606
|
return spec;
|
|
@@ -1309,10 +1608,11 @@ function withFade(spec, opts) {
|
|
|
1309
1608
|
|
|
1310
1609
|
Object.defineProperty(exports, "registerSequenceType", {
|
|
1311
1610
|
enumerable: true,
|
|
1312
|
-
get: function () { return
|
|
1611
|
+
get: function () { return chunkSIRVULFF_cjs.registerSequenceType; }
|
|
1313
1612
|
});
|
|
1314
1613
|
exports.Movie = Movie;
|
|
1315
1614
|
exports.kenBurns = kenBurns;
|
|
1615
|
+
exports.orbit = orbit;
|
|
1316
1616
|
exports.withFade = withFade;
|
|
1317
1617
|
//# sourceMappingURL=index.cjs.map
|
|
1318
1618
|
//# sourceMappingURL=index.cjs.map
|