pixi-effects 0.8.0 → 0.9.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 +7 -0
- package/README.md +6 -6
- package/ai/SKILL.md +6 -5
- package/ai/reference/cheatsheet.md +4 -0
- package/ai/template.html +4 -3
- package/ai/tools/check.mjs +8 -0
- package/dist/Controller.d.cts +1 -1
- package/dist/Controller.d.ts +1 -1
- package/dist/{Movie-HF3pSGjQ.d.ts → Movie-QMlFyHkf.d.ts} +25 -0
- package/dist/{Movie-CQOhUmko.d.cts → Movie-qGHp15c_.d.cts} +25 -0
- package/dist/index.cjs +60 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +60 -4
- package/dist/index.js.map +1 -1
- package/docs/api.md +16 -0
- package/llms-full.txt +26 -5
- package/package.json +4 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FrameEvent, I as InspectOptions, c as InspectReport, L as LayerInfo, M as Movie, d as MovieErrorEvent, e as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, f as SoundMeasure, T as TimelineData, g as TimelineHtmlOptions, h as TimelineRow, i as TimelineSvgOptions, j as TimelineTransition, V as VolumeEvent } from './Movie-
|
|
1
|
+
export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FrameEvent, I as InspectOptions, c as InspectReport, L as LayerInfo, M as Movie, d as MovieErrorEvent, e as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, f as SoundMeasure, T as TimelineData, g as TimelineHtmlOptions, h as TimelineRow, i as TimelineSvgOptions, j as TimelineTransition, V as VolumeEvent } from './Movie-qGHp15c_.cjs';
|
|
2
2
|
import { S as Sequence } from './Base-CSIulyIq.cjs';
|
|
3
3
|
import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, b as SequenceCommon } from './types-oJijbn-K.cjs';
|
|
4
4
|
export { A as ArcShapeSpec, c as AssetSpec, d as AudioAssetSpec, e as AudioSequenceSpec, f as AudioSfxSpec, g as ChromaKeyFilterSpec, h as CircleShapeSpec, i as CompositionSequenceSpec, j as CompositionSpec, k as CrossfadeTransition, l as CustomFilterSpec, D as DipTransition, m as DissolveTransition, E as EllipseShapeSpec, n as Expr, F as FilterSpec, G as GradientSpec, o as IrisTransition, K as Keyframe, L as LineShapeSpec, P as PathShapeSpec, p as PolygonShapeSpec, q as PropValue, r as Props, R as RectShapeSpec, s as SfxKnobs, t as SfxOptions, u as SfxPreset, v as SfxVoice, w as ShapeSequenceSpec, x as SlideTransition, T as TextSequenceSpec, y as TransitionCommon, z as TransitionSpec, V as VideoSequenceSpec, W as WipeTransition, Z as ZoomTransition } from './types-oJijbn-K.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FrameEvent, I as InspectOptions, c as InspectReport, L as LayerInfo, M as Movie, d as MovieErrorEvent, e as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, f as SoundMeasure, T as TimelineData, g as TimelineHtmlOptions, h as TimelineRow, i as TimelineSvgOptions, j as TimelineTransition, V as VolumeEvent } from './Movie-
|
|
1
|
+
export { A as AudioInspectOptions, a as AudioReport, b as AudioSourceReport, C as ContactSheetOptions, F as FrameEvent, I as InspectOptions, c as InspectReport, L as LayerInfo, M as Movie, d as MovieErrorEvent, e as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, f as SoundMeasure, T as TimelineData, g as TimelineHtmlOptions, h as TimelineRow, i as TimelineSvgOptions, j as TimelineTransition, V as VolumeEvent } from './Movie-QMlFyHkf.js';
|
|
2
2
|
import { S as Sequence } from './Base-DVgwyIUj.js';
|
|
3
3
|
import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, b as SequenceCommon } from './types-oJijbn-K.js';
|
|
4
4
|
export { A as ArcShapeSpec, c as AssetSpec, d as AudioAssetSpec, e as AudioSequenceSpec, f as AudioSfxSpec, g as ChromaKeyFilterSpec, h as CircleShapeSpec, i as CompositionSequenceSpec, j as CompositionSpec, k as CrossfadeTransition, l as CustomFilterSpec, D as DipTransition, m as DissolveTransition, E as EllipseShapeSpec, n as Expr, F as FilterSpec, G as GradientSpec, o as IrisTransition, K as Keyframe, L as LineShapeSpec, P as PathShapeSpec, p as PolygonShapeSpec, q as PropValue, r as Props, R as RectShapeSpec, s as SfxKnobs, t as SfxOptions, u as SfxPreset, v as SfxVoice, w as ShapeSequenceSpec, x as SlideTransition, T as TextSequenceSpec, y as TransitionCommon, z as TransitionSpec, V as VideoSequenceSpec, W as WipeTransition, Z as ZoomTransition } from './types-oJijbn-K.js';
|
package/dist/index.js
CHANGED
|
@@ -1429,6 +1429,21 @@ function startWhenRunning(ctx, start, gesture) {
|
|
|
1429
1429
|
}
|
|
1430
1430
|
var GESTURES = ["pointerdown", "mousedown", "touchend", "keydown"];
|
|
1431
1431
|
|
|
1432
|
+
// src/core/poster.ts
|
|
1433
|
+
function normalizePoster(poster, duration, frameRate) {
|
|
1434
|
+
if (poster === void 0 || poster === null) return { seconds: null, frame: null };
|
|
1435
|
+
if (typeof poster !== "number" || !Number.isFinite(poster)) {
|
|
1436
|
+
console.warn(`pixi-effects: movie.init({ poster }): ${JSON.stringify(poster)} is not a time in seconds; ignored`);
|
|
1437
|
+
return { seconds: null, frame: null };
|
|
1438
|
+
}
|
|
1439
|
+
let seconds = poster < 0 ? Math.max(0, duration + poster) : poster;
|
|
1440
|
+
if (seconds > duration) {
|
|
1441
|
+
console.warn(`pixi-effects: movie.init({ poster }): the poster time ${poster} s is past the end of the movie (${duration} s); using the last frame`);
|
|
1442
|
+
seconds = duration;
|
|
1443
|
+
}
|
|
1444
|
+
return { seconds, frame: Math.round(seconds * frameRate) };
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1432
1447
|
// src/core/Movie.ts
|
|
1433
1448
|
extensions.add(CullerPlugin);
|
|
1434
1449
|
gsap.registerPlugin(PixiPlugin);
|
|
@@ -1442,6 +1457,11 @@ var Movie = class {
|
|
|
1442
1457
|
audioSource = null;
|
|
1443
1458
|
gainNode = null;
|
|
1444
1459
|
_cancelAudioStart = null;
|
|
1460
|
+
/** The poster time in seconds (`movie.init({ poster })`), or null. */
|
|
1461
|
+
poster = null;
|
|
1462
|
+
_posterFrame = null;
|
|
1463
|
+
/** The canvas shows the poster picture while the playhead is still at frame 0 (like `<video poster>`): the first seek or play replaces it. */
|
|
1464
|
+
_atPoster = false;
|
|
1445
1465
|
/** > 0 while the movie moves its own playhead (playback, render, snapshot, contactSheet): those are not the seeks `seeking` / `seeked` report. */
|
|
1446
1466
|
_quiet = 0;
|
|
1447
1467
|
_volume = 1;
|
|
@@ -1485,6 +1505,36 @@ var Movie = class {
|
|
|
1485
1505
|
get isReady() {
|
|
1486
1506
|
return this._initState === "ready";
|
|
1487
1507
|
}
|
|
1508
|
+
/** The poster time as a frame number, or null. */
|
|
1509
|
+
get posterFrame() {
|
|
1510
|
+
return this._posterFrame;
|
|
1511
|
+
}
|
|
1512
|
+
/** Draw the poster frame on the canvas and leave the playhead where it is (frame 0): the picture before the movie plays. */
|
|
1513
|
+
async _showPoster() {
|
|
1514
|
+
if (this._posterFrame === null || !this.timeline) return;
|
|
1515
|
+
const back = this.currentFrame;
|
|
1516
|
+
this.currentFrame = this._posterFrame;
|
|
1517
|
+
try {
|
|
1518
|
+
this.timeline.time(this._posterFrame / this.frameRate);
|
|
1519
|
+
await this._awaitVideoFrames();
|
|
1520
|
+
this._updateSpace();
|
|
1521
|
+
this._renderNow();
|
|
1522
|
+
} finally {
|
|
1523
|
+
this.currentFrame = back;
|
|
1524
|
+
}
|
|
1525
|
+
this._atPoster = true;
|
|
1526
|
+
}
|
|
1527
|
+
async posterImage(opts = {}) {
|
|
1528
|
+
this._requireReady("posterImage");
|
|
1529
|
+
const back = this.currentFrame, wasAtPoster = this._atPoster;
|
|
1530
|
+
try {
|
|
1531
|
+
return await this.snapshot(this._posterFrame ?? 0, opts);
|
|
1532
|
+
} finally {
|
|
1533
|
+
this.currentFrame = back;
|
|
1534
|
+
if (wasAtPoster) await this._showPoster();
|
|
1535
|
+
else await this._quietly(() => this.gotoFrame(back, true));
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1488
1538
|
_ensureAudioContext() {
|
|
1489
1539
|
if (!this._audioContext) {
|
|
1490
1540
|
const Ctx = window.AudioContext ?? window.webkitAudioContext;
|
|
@@ -1493,7 +1543,7 @@ var Movie = class {
|
|
|
1493
1543
|
return this._audioContext;
|
|
1494
1544
|
}
|
|
1495
1545
|
async init(options = {}) {
|
|
1496
|
-
warnUnknownOptions("movie.init()", options, ["width", "height", "duration", "frameRate", "background", "canvas", "assets", "composition"]);
|
|
1546
|
+
warnUnknownOptions("movie.init()", options, ["width", "height", "duration", "frameRate", "background", "canvas", "assets", "composition", "poster"]);
|
|
1497
1547
|
this._initState = "pending";
|
|
1498
1548
|
try {
|
|
1499
1549
|
this.width = options.width ?? 1920;
|
|
@@ -1501,6 +1551,9 @@ var Movie = class {
|
|
|
1501
1551
|
this.duration = options.duration ?? 10;
|
|
1502
1552
|
this.frameRate = options.frameRate ?? 30;
|
|
1503
1553
|
this.totalFrames = Math.round(this.duration * this.frameRate);
|
|
1554
|
+
const poster = normalizePoster(options.poster, this.duration, this.frameRate);
|
|
1555
|
+
this.poster = poster.seconds;
|
|
1556
|
+
this._posterFrame = poster.frame;
|
|
1504
1557
|
this.background = options.background ?? "#000000";
|
|
1505
1558
|
this.timeline = gsap.timeline({ paused: true, defaults: { ease: "none" } });
|
|
1506
1559
|
this.timeline.add(gsap.to({}, { duration: this.duration }));
|
|
@@ -1564,6 +1617,7 @@ var Movie = class {
|
|
|
1564
1617
|
this._updateSpace();
|
|
1565
1618
|
this._renderNow();
|
|
1566
1619
|
this._initState = "ready";
|
|
1620
|
+
if (this._posterFrame !== null) await this._showPoster();
|
|
1567
1621
|
this.emit("ready");
|
|
1568
1622
|
} catch (err) {
|
|
1569
1623
|
try {
|
|
@@ -1577,7 +1631,7 @@ var Movie = class {
|
|
|
1577
1631
|
}
|
|
1578
1632
|
async gotoFrame(frame, force = false) {
|
|
1579
1633
|
if (this._initState !== "ready") return;
|
|
1580
|
-
if (!force && this.currentFrame === frame) return;
|
|
1634
|
+
if (!force && !this._atPoster && this.currentFrame === frame) return;
|
|
1581
1635
|
if (this._quiet > 0) return this._goto(frame);
|
|
1582
1636
|
const target = Math.max(0, Math.min(frame, this.totalFrames));
|
|
1583
1637
|
this.emit("seeking", { frame: target, totalFrames: this.totalFrames });
|
|
@@ -1597,6 +1651,7 @@ var Movie = class {
|
|
|
1597
1651
|
this.emit("error", { where, message: error instanceof Error ? error.message : String(error), error });
|
|
1598
1652
|
}
|
|
1599
1653
|
async _goto(frame) {
|
|
1654
|
+
this._atPoster = false;
|
|
1600
1655
|
this.currentFrame = Math.max(0, Math.min(frame, this.totalFrames));
|
|
1601
1656
|
this.timeline.time(this.currentFrame / this.frameRate);
|
|
1602
1657
|
await this._awaitVideoFrames();
|
|
@@ -1638,7 +1693,7 @@ var Movie = class {
|
|
|
1638
1693
|
const g = sheet.getContext("2d");
|
|
1639
1694
|
g.fillStyle = "#10131c";
|
|
1640
1695
|
g.fillRect(0, 0, L.width, L.height);
|
|
1641
|
-
const back = this.currentFrame;
|
|
1696
|
+
const back = this.currentFrame, wasAtPoster = this._atPoster;
|
|
1642
1697
|
try {
|
|
1643
1698
|
for (let i = 0; i < frames.length; i++) {
|
|
1644
1699
|
const f = frames[i];
|
|
@@ -1651,7 +1706,8 @@ var Movie = class {
|
|
|
1651
1706
|
g.fillText(`frame ${f} \xB7 ${(f / this.frameRate).toFixed(2)}s`, x + 8, y + LABEL_H / 2);
|
|
1652
1707
|
}
|
|
1653
1708
|
} finally {
|
|
1654
|
-
|
|
1709
|
+
if (wasAtPoster) await this._showPoster();
|
|
1710
|
+
else await this._quietly(() => this.gotoFrame(back, true));
|
|
1655
1711
|
}
|
|
1656
1712
|
return encodeCanvas(sheet, "image/png", opts.as ?? "blob");
|
|
1657
1713
|
}
|