pixi-effects 0.13.0 → 0.14.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 +20 -0
- package/README.md +5 -5
- package/ai/SKILL.md +1 -1
- package/ai/reference/cheatsheet.md +1 -0
- package/ai/reference/pitfalls.md +1 -1
- package/ai/template.html +5 -5
- package/ai/tools/check.mjs +15 -2
- package/dist/Controller.cjs +2 -3
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.d.cts +2 -2
- package/dist/Controller.d.ts +2 -2
- package/dist/Controller.js +2 -3
- package/dist/Controller.js.map +1 -1
- package/dist/{Movie-DnR4H1OO.d.ts → Movie-BwT6XtGz.d.ts} +23 -0
- package/dist/{Movie-Tl5dRLJl.d.cts → Movie-qmgOU4in.d.cts} +23 -0
- package/dist/Presenter.d.cts +1 -1
- package/dist/Presenter.d.ts +1 -1
- package/dist/index.cjs +59 -5
- 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 +59 -5
- package/dist/index.js.map +1 -1
- package/dist/loader.css +1 -1
- package/docs/api.md +4 -0
- package/llms-full.txt +7 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1648,6 +1648,16 @@ function pictureStops(stops, opts = {}) {
|
|
|
1648
1648
|
}
|
|
1649
1649
|
return picks;
|
|
1650
1650
|
}
|
|
1651
|
+
function changedFraction(a, b, threshold = 12) {
|
|
1652
|
+
const n = Math.min(a.length, b.length) >> 2;
|
|
1653
|
+
if (n === 0) return 0;
|
|
1654
|
+
let changed = 0;
|
|
1655
|
+
for (let i = 0; i < n; i++) {
|
|
1656
|
+
const k = i << 2;
|
|
1657
|
+
if (Math.abs(a[k] - b[k]) > threshold || Math.abs(a[k + 1] - b[k + 1]) > threshold || Math.abs(a[k + 2] - b[k + 2]) > threshold) changed++;
|
|
1658
|
+
}
|
|
1659
|
+
return changed / n;
|
|
1660
|
+
}
|
|
1651
1661
|
|
|
1652
1662
|
// src/core/loader.ts
|
|
1653
1663
|
var FADE_FALLBACK_MS = 900;
|
|
@@ -1935,18 +1945,28 @@ var Movie = class {
|
|
|
1935
1945
|
this._requireReady("snapshot");
|
|
1936
1946
|
return this._captureFrame(clampFrame(frame, this.totalFrames), { scale: opts.scale ?? 1, type: opts.type ?? "image/png", as: opts.as ?? "blob", motionBlur: opts.motionBlur });
|
|
1937
1947
|
}
|
|
1938
|
-
/** Seek to `frame` (quietly, and stay there) and
|
|
1939
|
-
async
|
|
1940
|
-
const mb = this._blurFor(
|
|
1948
|
+
/** Seek to `frame` (quietly, and stay there) and draw the canvas on a new canvas of `scale` times its size. */
|
|
1949
|
+
async _frameCanvas(frame, scale, motionBlur) {
|
|
1950
|
+
const mb = this._blurFor(motionBlur, "a picture");
|
|
1941
1951
|
let source = this.app.canvas;
|
|
1942
1952
|
if (mb) {
|
|
1943
1953
|
source = this._blurCanvas();
|
|
1944
1954
|
await this._quietly(() => this._exposeFrame(frame, mb, source, true));
|
|
1945
1955
|
} else await this._quietly(() => this.gotoFrame(frame, true));
|
|
1946
1956
|
const out = document.createElement("canvas");
|
|
1947
|
-
out.width = Math.max(1, Math.round(this.width *
|
|
1948
|
-
out.height = Math.max(1, Math.round(this.height *
|
|
1957
|
+
out.width = Math.max(1, Math.round(this.width * scale));
|
|
1958
|
+
out.height = Math.max(1, Math.round(this.height * scale));
|
|
1949
1959
|
out.getContext("2d").drawImage(source, 0, 0, out.width, out.height);
|
|
1960
|
+
return out;
|
|
1961
|
+
}
|
|
1962
|
+
/** The pixels of `frame`, small (about 320 px wide) and without motion blur, to compare pictures. */
|
|
1963
|
+
async _framePixels(frame) {
|
|
1964
|
+
const c = await this._frameCanvas(frame, Math.min(1, 320 / Math.max(1, this.width)), false);
|
|
1965
|
+
return c.getContext("2d").getImageData(0, 0, c.width, c.height).data;
|
|
1966
|
+
}
|
|
1967
|
+
/** Seek to `frame` (quietly, and stay there) and encode the canvas as a picture. */
|
|
1968
|
+
async _captureFrame(frame, o) {
|
|
1969
|
+
const out = await this._frameCanvas(frame, o.scale, o.motionBlur);
|
|
1950
1970
|
return encodeCanvas(out, o.type, o.as, o.quality);
|
|
1951
1971
|
}
|
|
1952
1972
|
async stopImages(opts = {}) {
|
|
@@ -1976,6 +1996,40 @@ var Movie = class {
|
|
|
1976
1996
|
}
|
|
1977
1997
|
return out;
|
|
1978
1998
|
}
|
|
1999
|
+
/**
|
|
2000
|
+
* Look at every stop: is the picture there still changing? A stop is compared with the picture `lookback` frames before it (default 3):
|
|
2001
|
+
* when more than `tolerance` (default 0.4 %) of the picture differs, the audience, a page overview and a PDF all see a half-finished
|
|
2002
|
+
* animation. `issues` says which stop, which page and what to do; leaves the playhead where it was.
|
|
2003
|
+
*/
|
|
2004
|
+
async inspectStops(opts = {}) {
|
|
2005
|
+
chunkUQBGW5DO_cjs.warnUnknownOptions("movie.inspectStops()", opts, ["lookback", "tolerance"]);
|
|
2006
|
+
this._requireReady("inspectStops");
|
|
2007
|
+
const out = { stops: [], issues: [] };
|
|
2008
|
+
if (this.stops.length === 0) return out;
|
|
2009
|
+
const lookback = Math.max(1, Math.round(opts.lookback ?? 3));
|
|
2010
|
+
const tolerance = opts.tolerance ?? 4e-3;
|
|
2011
|
+
this.pause();
|
|
2012
|
+
const back = this.currentFrame, wasAtPoster = this._atPoster;
|
|
2013
|
+
try {
|
|
2014
|
+
for (const stop of this.stops) {
|
|
2015
|
+
const before = Math.max(0, stop.frame - lookback);
|
|
2016
|
+
let moving = 0;
|
|
2017
|
+
if (before < stop.frame) {
|
|
2018
|
+
const now = await this._framePixels(stop.frame);
|
|
2019
|
+
moving = changedFraction(now, await this._framePixels(before));
|
|
2020
|
+
}
|
|
2021
|
+
const settled = moving <= tolerance;
|
|
2022
|
+
out.stops.push({ index: stop.index, page: stop.page, at: stop.at, frame: stop.frame, moving, settled });
|
|
2023
|
+
if (!settled) {
|
|
2024
|
+
out.issues.push(`stop ${stop.index + 1}${stop.page ? ` (page "${stop.page}")` : ""} at ${stop.at.toFixed(1)} s: the picture is still changing there (${moving < 0.1 ? (moving * 100).toFixed(1) : Math.round(moving * 100)}% of it changed in the last ${stop.frame - before} frames), so the audience, the page overview and a PDF see it mid-animation. Move the stop to after the animation has finished, or flag a settled stop of the page with \`pdf: true\`.`);
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
} finally {
|
|
2028
|
+
if (wasAtPoster) await this._showPoster();
|
|
2029
|
+
else await this._quietly(() => this.gotoFrame(back, true));
|
|
2030
|
+
}
|
|
2031
|
+
return out;
|
|
2032
|
+
}
|
|
1979
2033
|
/**
|
|
1980
2034
|
* The deck as a PDF: one page per page of the talk (the page's last stop, fully built, unless a stop says `pdf: true` or `pdf: false`;
|
|
1981
2035
|
* `which: 'stops'` makes a page of every stop that is not `pdf: false`), each a
|