pixi-effects 0.34.0 → 0.35.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.
@@ -2645,6 +2645,10 @@ var Movie = class {
2645
2645
  _silent = 0;
2646
2646
  /** render() / peek() in flight: a rebuild does not swap the composition under them. */
2647
2647
  _busy = 0;
2648
+ /** > 0 while the movie is moving its scene to another moment (a seek, a motion-blurred frame, the poster): a thumbnail does not start then. */
2649
+ _moving = 0;
2650
+ /** The thumbnail being drawn, if any: a seek waits for it (it has the scene on another moment for a few microtasks). */
2651
+ _thumbRun = null;
2648
2652
  _idleWaiters = [];
2649
2653
  /** What went into the mix, and its peak before limiting — kept for inspectAudio(). */
2650
2654
  _audioSources = [];
@@ -2692,6 +2696,7 @@ var Movie = class {
2692
2696
  if (this._posterFrame === null || !this.timeline) return;
2693
2697
  const back = this.currentFrame;
2694
2698
  this.currentFrame = this._posterFrame;
2699
+ this._moving++;
2695
2700
  try {
2696
2701
  this.timeline.time(this._timeOf(this._posterFrame));
2697
2702
  await this._awaitVideoFrames();
@@ -2699,6 +2704,7 @@ var Movie = class {
2699
2704
  this._renderNow();
2700
2705
  } finally {
2701
2706
  this.currentFrame = back;
2707
+ this._moving--;
2702
2708
  }
2703
2709
  this._atPoster = true;
2704
2710
  }
@@ -3085,12 +3091,18 @@ var Movie = class {
3085
3091
  this.emit("error", { where, message: error instanceof Error ? error.message : String(error), error });
3086
3092
  }
3087
3093
  async _goto(frame) {
3088
- this._atPoster = false;
3089
- this.currentFrame = Math.max(0, Math.min(frame, this.totalFrames));
3090
- this.timeline.time(this._timeOf(this.currentFrame));
3091
- await this._awaitVideoFrames();
3092
- this._updateSpace();
3093
- this._renderNow();
3094
+ if (this._thumbRun) await this._thumbRun;
3095
+ this._moving++;
3096
+ try {
3097
+ this._atPoster = false;
3098
+ this.currentFrame = Math.max(0, Math.min(frame, this.totalFrames));
3099
+ this.timeline.time(this._timeOf(this.currentFrame));
3100
+ await this._awaitVideoFrames();
3101
+ this._updateSpace();
3102
+ this._renderNow();
3103
+ } finally {
3104
+ this._moving--;
3105
+ }
3094
3106
  this.emit("frame", { frame: this.currentFrame, totalFrames: this.totalFrames });
3095
3107
  }
3096
3108
  /**
@@ -3138,6 +3150,69 @@ var Movie = class {
3138
3150
  if (o.as === "imageData") return out.getContext("2d").getImageData(0, 0, out.width, out.height);
3139
3151
  return encodeCanvas(out, o.type, o.as, o.quality);
3140
3152
  }
3153
+ /**
3154
+ * Why `thumbnail()` is off for this movie: `'variables'` (it declares `vars`: the picture depends on them and changes when they do) or `'video'` (a video
3155
+ * layer: its frame must be waited for, which would seek the playing video). `null`: it works.
3156
+ */
3157
+ get thumbnailsOff() {
3158
+ if (this._declared.size > 0) return "variables";
3159
+ if (!this._rootSequence) return null;
3160
+ const found = [];
3161
+ collectVideoSequences(this._rootSequence, found);
3162
+ return found.some((v) => v.spec?.type === "video") ? "video" : null;
3163
+ }
3164
+ /**
3165
+ * A small picture of any frame, drawn WITHOUT moving the playhead or changing what is on the canvas, so it can be made while the movie plays or is
3166
+ * paused (a seek-bar preview). The scene is put on that moment, drawn, copied, and put back, all within the microtasks of one task: the browser never
3167
+ * shows the in-between. Gives `null` when it cannot be made right now: the movie has thumbnails off (see `thumbnailsOff`), is moving somewhere else
3168
+ * (a seek, a render, a peek), or is another thumbnail's turn. It is the picture `snapshot()` gives at that size (without motion blur).
3169
+ */
3170
+ async thumbnail(frame, opts = {}) {
3171
+ chunkTWZNOUM7_cjs.warnUnknownOptions("movie.thumbnail()", opts, ["width", "scale"]);
3172
+ this._requireReady("thumbnail");
3173
+ if (opts.width !== void 0 && !(opts.width > 0 && opts.width <= this.width * 4)) throw new Error(`pixi-effects: movie.thumbnail(): width must be above 0 and at most ${this.width * 4} px, got ${opts.width}`);
3174
+ if (opts.scale !== void 0 && !(opts.scale > 0 && opts.scale <= 4)) throw new Error(`pixi-effects: movie.thumbnail(): scale must be above 0 and at most 4, got ${opts.scale}`);
3175
+ if (this.thumbnailsOff || this._moving > 0 || this._busy > 0 || this._thumbRun) return null;
3176
+ const w = Math.max(1, Math.round(opts.width ?? (opts.scale !== void 0 ? this.width * opts.scale : 160)));
3177
+ const h = Math.max(1, Math.round(w * this.height / this.width));
3178
+ let done;
3179
+ this._thumbRun = new Promise((r) => {
3180
+ done = r;
3181
+ });
3182
+ try {
3183
+ return await this._drawThumbnail(clampFrame(frame, this.totalFrames), w, h);
3184
+ } finally {
3185
+ this._thumbRun = null;
3186
+ done();
3187
+ }
3188
+ }
3189
+ async _drawThumbnail(frame, w, h) {
3190
+ const stage = this.app.canvas;
3191
+ const out = document.createElement("canvas");
3192
+ out.width = w;
3193
+ out.height = h;
3194
+ const keep = this.timeline.time();
3195
+ const t = this._timeOf(frame);
3196
+ this._nominalTime = t;
3197
+ try {
3198
+ this.timeline.time(t);
3199
+ await this._awaitVideoFrames(t);
3200
+ this._updateSpace(t);
3201
+ this._renderNow();
3202
+ out.getContext("2d").drawImage(stage, 0, 0, w, h);
3203
+ } finally {
3204
+ this._nominalTime = keep;
3205
+ try {
3206
+ this.timeline.time(keep);
3207
+ await this._awaitVideoFrames(keep);
3208
+ this._updateSpace(keep);
3209
+ this._renderNow();
3210
+ } finally {
3211
+ this._nominalTime = null;
3212
+ }
3213
+ }
3214
+ return out;
3215
+ }
3141
3216
  async onionSkin(opts = {}) {
3142
3217
  chunkTWZNOUM7_cjs.warnUnknownOptions("movie.onionSkin()", opts, ["from", "to", "count", "scale", "as", "motionBlur"]);
3143
3218
  this._requireReady("onionSkin");
@@ -3316,9 +3391,11 @@ var Movie = class {
3316
3391
  async _exposeFrame(frame, mb, target, settle) {
3317
3392
  const g = target.getContext("2d");
3318
3393
  const stage = this.app.canvas;
3394
+ if (this._thumbRun) await this._thumbRun;
3319
3395
  this._atPoster = false;
3320
3396
  const times = blurTimes(frame, this.frameRate, mb, Math.max(0, this.duration - END_MARGIN));
3321
3397
  this._nominalTime = this._timeOf(Math.max(0, Math.min(frame, this.totalFrames)));
3398
+ this._moving++;
3322
3399
  try {
3323
3400
  for (let k = 0; k < times.length; k++) {
3324
3401
  const t = times[k];
@@ -3332,6 +3409,7 @@ var Movie = class {
3332
3409
  }
3333
3410
  } finally {
3334
3411
  this._nominalTime = null;
3412
+ this._moving--;
3335
3413
  }
3336
3414
  g.globalAlpha = 1;
3337
3415
  if (settle) await this._goto(frame);
@@ -4644,5 +4722,5 @@ exports.splitText = splitText;
4644
4722
  exports.stagger = stagger;
4645
4723
  exports.wiggle = wiggle;
4646
4724
  exports.withFade = withFade;
4647
- //# sourceMappingURL=chunk-FVZEBYLW.cjs.map
4648
- //# sourceMappingURL=chunk-FVZEBYLW.cjs.map
4725
+ //# sourceMappingURL=chunk-7TTCPHAV.cjs.map
4726
+ //# sourceMappingURL=chunk-7TTCPHAV.cjs.map