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/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, d as LoaderOption, M as MotionBlurOptions, e as MotionBlurSpec, f as Movie, g as MovieErrorEvent, h as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, i as SoundMeasure, j as StopEvent, k as StopImage, l as StopImagesOptions, T as TimelineData, m as TimelineHtmlOptions, n as TimelineRow, o as TimelineSvgOptions, p as TimelineTransition, V as VolumeEvent, q as dismissLoader, r as failLoader, s as resolveLoader } from './Movie-Tl5dRLJl.cjs';
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, d as LoaderOption, M as MotionBlurOptions, e as MotionBlurSpec, f as Movie, g as MovieErrorEvent, h as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, i as SoundMeasure, j as StopEvent, k as StopImage, l as StopImagesOptions, T as TimelineData, m as TimelineHtmlOptions, n as TimelineRow, o as TimelineSvgOptions, p as TimelineTransition, V as VolumeEvent, q as dismissLoader, r as failLoader, s as resolveLoader } from './Movie-qmgOU4in.cjs';
2
2
  import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, P as Props, b as TransitionSpec, c as CompositionSpec, d as SequenceCommon } from './types-CBSiUKau.cjs';
3
3
  export { A as ArcShapeSpec, e as AssetSpec, f as AudioAssetSpec, g as AudioSequenceSpec, h as AudioSfxSpec, i as ChromaKeyFilterSpec, j as CircleShapeSpec, k as CompositionSequenceSpec, l as CrossfadeTransition, m as CustomFilterSpec, D as DipTransition, n as DissolveTransition, E as EllipseShapeSpec, o as Expr, F as FilterSpec, G as GradientSpec, p as IrisTransition, L as LineShapeSpec, N as NullSequenceSpec, q as PathShapeSpec, r as PolygonShapeSpec, s as PropValue, R as RectShapeSpec, t as SfxKnobs, u as SfxOptions, v as SfxPreset, w as SfxVoice, x as ShapeSequenceSpec, y as SlideTransition, z as Stop, B as StopSpec, H as TransitionCommon, V as VideoSequenceSpec, W as WipeTransition, Z as ZoomTransition, J as normalizeStops, M as pictureStops } from './types-CBSiUKau.cjs';
4
4
  import { S as Sequence } from './Base-C6ZnJ9pD.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, d as LoaderOption, M as MotionBlurOptions, e as MotionBlurSpec, f as Movie, g as MovieErrorEvent, h as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, i as SoundMeasure, j as StopEvent, k as StopImage, l as StopImagesOptions, T as TimelineData, m as TimelineHtmlOptions, n as TimelineRow, o as TimelineSvgOptions, p as TimelineTransition, V as VolumeEvent, q as dismissLoader, r as failLoader, s as resolveLoader } from './Movie-DnR4H1OO.js';
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, d as LoaderOption, M as MotionBlurOptions, e as MotionBlurSpec, f as Movie, g as MovieErrorEvent, h as MovieOptions, P as ProgressEvent, R as RenderOptions, S as SnapshotOptions, i as SoundMeasure, j as StopEvent, k as StopImage, l as StopImagesOptions, T as TimelineData, m as TimelineHtmlOptions, n as TimelineRow, o as TimelineSvgOptions, p as TimelineTransition, V as VolumeEvent, q as dismissLoader, r as failLoader, s as resolveLoader } from './Movie-BwT6XtGz.js';
2
2
  import { S as SequenceSpec, C as CompositionShape, I as ImageSequenceSpec, a as CameraSequenceSpec, K as Keyframe, T as TextSequenceSpec, P as Props, b as TransitionSpec, c as CompositionSpec, d as SequenceCommon } from './types-CBSiUKau.js';
3
3
  export { A as ArcShapeSpec, e as AssetSpec, f as AudioAssetSpec, g as AudioSequenceSpec, h as AudioSfxSpec, i as ChromaKeyFilterSpec, j as CircleShapeSpec, k as CompositionSequenceSpec, l as CrossfadeTransition, m as CustomFilterSpec, D as DipTransition, n as DissolveTransition, E as EllipseShapeSpec, o as Expr, F as FilterSpec, G as GradientSpec, p as IrisTransition, L as LineShapeSpec, N as NullSequenceSpec, q as PathShapeSpec, r as PolygonShapeSpec, s as PropValue, R as RectShapeSpec, t as SfxKnobs, u as SfxOptions, v as SfxPreset, w as SfxVoice, x as ShapeSequenceSpec, y as SlideTransition, z as Stop, B as StopSpec, H as TransitionCommon, V as VideoSequenceSpec, W as WipeTransition, Z as ZoomTransition, J as normalizeStops, M as pictureStops } from './types-CBSiUKau.js';
4
4
  import { S as Sequence } from './Base-CQOlB2VH.js';
package/dist/index.js CHANGED
@@ -1628,6 +1628,16 @@ function pictureStops(stops, opts = {}) {
1628
1628
  }
1629
1629
  return picks;
1630
1630
  }
1631
+ function changedFraction(a, b, threshold = 12) {
1632
+ const n = Math.min(a.length, b.length) >> 2;
1633
+ if (n === 0) return 0;
1634
+ let changed = 0;
1635
+ for (let i = 0; i < n; i++) {
1636
+ const k = i << 2;
1637
+ 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++;
1638
+ }
1639
+ return changed / n;
1640
+ }
1631
1641
 
1632
1642
  // src/core/loader.ts
1633
1643
  var FADE_FALLBACK_MS = 900;
@@ -1915,18 +1925,28 @@ var Movie = class {
1915
1925
  this._requireReady("snapshot");
1916
1926
  return this._captureFrame(clampFrame(frame, this.totalFrames), { scale: opts.scale ?? 1, type: opts.type ?? "image/png", as: opts.as ?? "blob", motionBlur: opts.motionBlur });
1917
1927
  }
1918
- /** Seek to `frame` (quietly, and stay there) and encode the canvas as a picture. */
1919
- async _captureFrame(frame, o) {
1920
- const mb = this._blurFor(o.motionBlur, "a picture");
1928
+ /** Seek to `frame` (quietly, and stay there) and draw the canvas on a new canvas of `scale` times its size. */
1929
+ async _frameCanvas(frame, scale, motionBlur) {
1930
+ const mb = this._blurFor(motionBlur, "a picture");
1921
1931
  let source = this.app.canvas;
1922
1932
  if (mb) {
1923
1933
  source = this._blurCanvas();
1924
1934
  await this._quietly(() => this._exposeFrame(frame, mb, source, true));
1925
1935
  } else await this._quietly(() => this.gotoFrame(frame, true));
1926
1936
  const out = document.createElement("canvas");
1927
- out.width = Math.max(1, Math.round(this.width * o.scale));
1928
- out.height = Math.max(1, Math.round(this.height * o.scale));
1937
+ out.width = Math.max(1, Math.round(this.width * scale));
1938
+ out.height = Math.max(1, Math.round(this.height * scale));
1929
1939
  out.getContext("2d").drawImage(source, 0, 0, out.width, out.height);
1940
+ return out;
1941
+ }
1942
+ /** The pixels of `frame`, small (about 320 px wide) and without motion blur, to compare pictures. */
1943
+ async _framePixels(frame) {
1944
+ const c = await this._frameCanvas(frame, Math.min(1, 320 / Math.max(1, this.width)), false);
1945
+ return c.getContext("2d").getImageData(0, 0, c.width, c.height).data;
1946
+ }
1947
+ /** Seek to `frame` (quietly, and stay there) and encode the canvas as a picture. */
1948
+ async _captureFrame(frame, o) {
1949
+ const out = await this._frameCanvas(frame, o.scale, o.motionBlur);
1930
1950
  return encodeCanvas(out, o.type, o.as, o.quality);
1931
1951
  }
1932
1952
  async stopImages(opts = {}) {
@@ -1956,6 +1976,40 @@ var Movie = class {
1956
1976
  }
1957
1977
  return out;
1958
1978
  }
1979
+ /**
1980
+ * Look at every stop: is the picture there still changing? A stop is compared with the picture `lookback` frames before it (default 3):
1981
+ * when more than `tolerance` (default 0.4 %) of the picture differs, the audience, a page overview and a PDF all see a half-finished
1982
+ * animation. `issues` says which stop, which page and what to do; leaves the playhead where it was.
1983
+ */
1984
+ async inspectStops(opts = {}) {
1985
+ warnUnknownOptions("movie.inspectStops()", opts, ["lookback", "tolerance"]);
1986
+ this._requireReady("inspectStops");
1987
+ const out = { stops: [], issues: [] };
1988
+ if (this.stops.length === 0) return out;
1989
+ const lookback = Math.max(1, Math.round(opts.lookback ?? 3));
1990
+ const tolerance = opts.tolerance ?? 4e-3;
1991
+ this.pause();
1992
+ const back = this.currentFrame, wasAtPoster = this._atPoster;
1993
+ try {
1994
+ for (const stop of this.stops) {
1995
+ const before = Math.max(0, stop.frame - lookback);
1996
+ let moving = 0;
1997
+ if (before < stop.frame) {
1998
+ const now = await this._framePixels(stop.frame);
1999
+ moving = changedFraction(now, await this._framePixels(before));
2000
+ }
2001
+ const settled = moving <= tolerance;
2002
+ out.stops.push({ index: stop.index, page: stop.page, at: stop.at, frame: stop.frame, moving, settled });
2003
+ if (!settled) {
2004
+ 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\`.`);
2005
+ }
2006
+ }
2007
+ } finally {
2008
+ if (wasAtPoster) await this._showPoster();
2009
+ else await this._quietly(() => this.gotoFrame(back, true));
2010
+ }
2011
+ return out;
2012
+ }
1959
2013
  /**
1960
2014
  * 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`;
1961
2015
  * `which: 'stops'` makes a page of every stop that is not `pdf: false`), each a