pixi-effects 0.30.1 → 0.31.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +6 -5
  3. package/ai/chat-template.html +3 -3
  4. package/ai/tools/check.mjs +42 -2
  5. package/ai/tools/render.mjs +15 -2
  6. package/ai/tools/varArgs.mjs +75 -0
  7. package/dist/{Base-CB1_FPZD.d.cts → Base-BKagtWc0.d.cts} +1 -1
  8. package/dist/{Base-Ne74ztNl.d.ts → Base-jRiMHcWT.d.ts} +1 -1
  9. package/dist/Composition-DQCPJPFE.js +7 -0
  10. package/dist/{Composition-RJGA7KDU.js.map → Composition-DQCPJPFE.js.map} +1 -1
  11. package/dist/Composition-V2XYSW6P.cjs +16 -0
  12. package/dist/{Composition-MUKR3FYD.cjs.map → Composition-V2XYSW6P.cjs.map} +1 -1
  13. package/dist/Controller.cjs +42 -1
  14. package/dist/Controller.cjs.map +1 -1
  15. package/dist/Controller.d.cts +10 -2
  16. package/dist/Controller.d.ts +10 -2
  17. package/dist/Controller.js +42 -1
  18. package/dist/Controller.js.map +1 -1
  19. package/dist/{Movie-DdnpLpw1.d.cts → Movie-BH81stkb.d.cts} +90 -3
  20. package/dist/{Movie-C2rZFkrO.d.ts → Movie-CfFPItoL.d.ts} +90 -3
  21. package/dist/{chunk-A3Q3SDSH.js → chunk-BGMCZA36.js} +3 -3
  22. package/dist/{chunk-A3Q3SDSH.js.map → chunk-BGMCZA36.js.map} +1 -1
  23. package/dist/{chunk-ZVUO325O.cjs → chunk-DJ5B7IKT.cjs} +9 -3
  24. package/dist/chunk-DJ5B7IKT.cjs.map +1 -0
  25. package/dist/{chunk-WHNADXXG.cjs → chunk-L73KRFXI.cjs} +61 -61
  26. package/dist/{chunk-WHNADXXG.cjs.map → chunk-L73KRFXI.cjs.map} +1 -1
  27. package/dist/{chunk-ZAXYPXKW.js → chunk-MMTESMJ5.js} +9 -4
  28. package/dist/chunk-MMTESMJ5.js.map +1 -0
  29. package/dist/{chunk-CRQFDY7E.js → chunk-UTIBYMIO.js} +461 -56
  30. package/dist/chunk-UTIBYMIO.js.map +1 -0
  31. package/dist/{chunk-HREBQAY4.cjs → chunk-X3WHETQ3.cjs} +485 -80
  32. package/dist/chunk-X3WHETQ3.cjs.map +1 -0
  33. package/dist/index.cjs +31 -31
  34. package/dist/index.d.cts +5 -5
  35. package/dist/index.d.ts +5 -5
  36. package/dist/index.js +3 -3
  37. package/dist/loader.css +1 -1
  38. package/dist/present.cjs +3 -3
  39. package/dist/present.d.cts +2 -2
  40. package/dist/present.d.ts +2 -2
  41. package/dist/present.js +3 -3
  42. package/dist/three.cjs +5 -5
  43. package/dist/three.d.cts +2 -2
  44. package/dist/three.d.ts +2 -2
  45. package/dist/three.js +1 -1
  46. package/dist/{types-BzIB65Vk.d.cts → types-CK_crNAI.d.cts} +2 -0
  47. package/dist/{types-BzIB65Vk.d.ts → types-CK_crNAI.d.ts} +2 -0
  48. package/docs/api.md +28 -1
  49. package/docs/dsl.md +32 -1
  50. package/llms-full.txt +118 -3
  51. package/package.json +83 -20
  52. package/skills/pixi-effects/SKILL.md +1 -1
  53. package/skills/pixi-effects/reference/cheatsheet.md +3 -0
  54. package/skills/pixi-effects/reference/pitfalls.md +4 -0
  55. package/skills/pixi-effects/reference/recipes.md +52 -0
  56. package/skills/pixi-effects/template.html +6 -6
  57. package/dist/Composition-MUKR3FYD.cjs +0 -16
  58. package/dist/Composition-RJGA7KDU.js +0 -7
  59. package/dist/chunk-CRQFDY7E.js.map +0 -1
  60. package/dist/chunk-HREBQAY4.cjs.map +0 -1
  61. package/dist/chunk-ZAXYPXKW.js.map +0 -1
  62. package/dist/chunk-ZVUO325O.cjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { Application } from 'pixi.js';
2
- import { Z as Stop, c as AssetSpec, k as CompositionSpec } from './types-BzIB65Vk.cjs';
2
+ import { Z as Stop, c as AssetSpec, k as CompositionSpec } from './types-CK_crNAI.cjs';
3
3
 
4
4
  type EaseFn = (p: number) => number;
5
5
 
@@ -417,6 +417,10 @@ interface TimelineSvgOptions {
417
417
  labels?: boolean;
418
418
  }
419
419
 
420
+ /** A variable holds a number (read as an identifier in an expression) or a string (read as `{name}` in any string of the spec). */
421
+ type VarValue = number | string;
422
+ type Vars = Record<string, VarValue>;
423
+
420
424
  /**
421
425
  * How far `movie.init()` is: one number from 0 to 1 for a movie that takes seconds to build, the stage it is in and how many of that stage are done.
422
426
  * The stages run in a fixed order and carry a share of the whole (the shares come from timings of the reel and the gallery); a stage that is never
@@ -467,6 +471,12 @@ interface MovieOptions {
467
471
  canvas?: HTMLCanvasElement;
468
472
  assets?: AssetSpec[];
469
473
  composition?: CompositionSpec;
474
+ /**
475
+ * Named variables: numbers an expression reads as identifiers (`x: 'W/2 + shift'`) and strings that `{name}` stands for anywhere in the
476
+ * composition (`text: '{title}'`, `fillColor: '{accent}'`). Change them later with `movie.setVars()`, which rebuilds the movie at the same time.
477
+ * A name an expression already means (`W`, `t`, `sin`, `PI`, `value` …) is refused.
478
+ */
479
+ vars?: Vars;
470
480
  /**
471
481
  * The poster time in seconds: the moment that stands for the movie before it plays. The canvas shows that frame once the movie is
472
482
  * ready, the playhead stays at 0 and play starts from 0 (like `<video poster>`); `movie.posterImage()` is that picture. A negative
@@ -484,6 +494,8 @@ interface MovieOptions {
484
494
  * the canvas is used. It is faded out once the movie is ready (the poster is on the canvas) and, if `init()` fails, it stops and says so.
485
495
  */
486
496
  loader?: LoaderOption;
497
+ /** Start with `movie.loop` on: playing goes back to the start at the end instead of stopping. Default false (like a `<video>`). */
498
+ loop?: boolean;
487
499
  }
488
500
 
489
501
  interface RenderOptions {
@@ -527,6 +539,24 @@ interface SnapshotOptions {
527
539
  /** Return a `data:` URL string instead of a Blob (handy for scripts that can only return text), or `'imageData'`: the pixels as an `ImageData` (to measure, compare). */
528
540
  as?: 'blob' | 'dataURL' | 'imageData';
529
541
  }
542
+ /** What `movie.rebuild()` may change: the composition itself, variables (a partial set), the size of the movie. */
543
+ interface RebuildOptions {
544
+ composition?: CompositionSpec;
545
+ vars?: Vars;
546
+ width?: number;
547
+ height?: number;
548
+ }
549
+ type RebuildReason = 'vars' | 'resize' | 'rebuild';
550
+ /** What a rebuild did: how long it took, whether the sound was mixed again (`'mixed'`), reused from the last mix (`'reused'`) or there is none, and where the playhead was put back. */
551
+ interface RebuildReport {
552
+ reason: RebuildReason;
553
+ ms: number;
554
+ audio: 'reused' | 'mixed' | 'none';
555
+ frame: number;
556
+ playing: boolean;
557
+ /** True when nothing changed (`setVars` with the values it already has): nothing was rebuilt. */
558
+ unchanged?: boolean;
559
+ }
530
560
  interface ContactSheetOptions {
531
561
  /** Motion blur for these pictures (see `MovieOptions.motionBlur`); overrides the movie's own setting, `false` turns it off. */
532
562
  motionBlur?: MotionBlurSpec;
@@ -569,9 +599,13 @@ interface VolumeEvent {
569
599
  volume: number;
570
600
  muted: boolean;
571
601
  }
602
+ /** `loopchange`: the value of `movie.loop` after the change. */
603
+ interface LoopEvent {
604
+ loop: boolean;
605
+ }
572
606
  /** `error`: something failed in `init()`, `render()` or during playback. The call that failed still rejects / warns as before. */
573
607
  interface MovieErrorEvent {
574
- where: 'init' | 'render' | 'playback';
608
+ where: 'init' | 'render' | 'playback' | 'rebuild';
575
609
  message: string;
576
610
  error: unknown;
577
611
  }
@@ -599,6 +633,7 @@ declare class Movie {
599
633
  private _quiet;
600
634
  private _volume;
601
635
  private _muted;
636
+ private _loop;
602
637
  isPlaying: boolean;
603
638
  currentFrame: number;
604
639
  totalFrames: number;
@@ -616,6 +651,21 @@ declare class Movie {
616
651
  private _feedTimeFilters;
617
652
  private _rootContainer;
618
653
  private _raf;
654
+ /** The variables now, and the names that were declared (a `setVars` of any other name is refused). */
655
+ private _vars;
656
+ private _declared;
657
+ /** The composition as the author wrote it (before `{name}` is replaced): a rebuild starts from it. */
658
+ private _composition;
659
+ /** True once `resize()` was called: the size of the movie then replaces an explicit `width` / `height` of the composition. */
660
+ private _resized;
661
+ private _mixCache;
662
+ private _rebuildRun;
663
+ private _rebuildNext;
664
+ /** > 0 while a rebuild stops and restarts playback: `play` / `pause` are not announced then (a player's button must not flicker). */
665
+ private _silent;
666
+ /** render() / peek() in flight: a rebuild does not swap the composition under them. */
667
+ private _busy;
668
+ private _idleWaiters;
619
669
  /** What went into the mix, and its peak before limiting — kept for inspectAudio(). */
620
670
  private _audioSources;
621
671
  private _mixStats;
@@ -626,10 +676,14 @@ declare class Movie {
626
676
  /** Playback ran off the end (after `pause`). Pausing by hand does not emit it. */
627
677
  on(event: 'ended', fn: () => void): this;
628
678
  on(event: 'volumechange', fn: (e: VolumeEvent) => void): this;
679
+ /** `movie.loop` changed (set by the page, the bar's loop button or `init({ loop })` is not a change). */
680
+ on(event: 'loopchange', fn: (e: LoopEvent) => void): this;
629
681
  on(event: 'error', fn: (e: MovieErrorEvent) => void): this;
630
682
  on(event: 'progress', fn: (e: ProgressEvent) => void): this;
631
683
  /** How far `init()` is while it builds the movie: `{ stage: 'assets' | 'build' | 'sound' | 'frames', loaded, total, progress }`, `progress` 0 to 1. The page's `.pe-loader` shows it by itself. */
632
684
  on(event: 'loadprogress', fn: (e: LoadProgressState) => void): this;
685
+ /** A `rebuild()` (a `setVars()` or a `resize()` too) finished: what it was and what it cost. */
686
+ on(event: 'rebuilt', fn: (e: RebuildReport) => void): this;
633
687
  on(event: 'play', fn: () => void): this;
634
688
  on(event: 'pause', fn: () => void): this;
635
689
  off(event: string, fn: Listener): this;
@@ -655,6 +709,31 @@ declare class Movie {
655
709
  }): Promise<string>;
656
710
  private _ensureAudioContext;
657
711
  init(options?: MovieOptions): Promise<void>;
712
+ /**
713
+ * Build the composition tree for these variables and this size, off stage: `{name}` replaced, the root shape (with the numeric variables for the
714
+ * expressions), transitions expanded, every layer built. Used by `init` and by `rebuild`.
715
+ */
716
+ private _construct;
717
+ /** Make the sound of a built composition: the same mix as last time when the sounds are the same (`'reused'`), else mix it. */
718
+ private _mixSound;
719
+ /** The variables now (a copy; change them with `setVars()`). */
720
+ get vars(): Readonly<Vars>;
721
+ /**
722
+ * Change variables and rebuild at the same time. Only the declared names (`movie.init({ vars })`) are accepted; another name says which one it
723
+ * looks like and is ignored. Values it already has change nothing: no rebuild (`unchanged: true`).
724
+ */
725
+ setVars(changes: Vars): Promise<RebuildReport>;
726
+ /** Make the movie `width` x `height` pixels (the canvas, and `W` / `H` / `GW` / `GH` in every expression) and rebuild at the same time. */
727
+ resize(width: number, height: number): Promise<RebuildReport>;
728
+ /**
729
+ * Build the composition again, with what `change` replaces (variables, the composition, the size), and put the movie back where it was: the
730
+ * same frame, playing or not, the poster if that was shown. The new composition is built first: when that fails the old one stays, `error` is
731
+ * emitted and the promise rejects. The sound is mixed again only when it changed (`audio: 'reused'` otherwise). Calls that arrive while a
732
+ * rebuild runs are joined into one more rebuild (the latest values win), so a slider can call it on every move.
733
+ */
734
+ rebuild(change?: RebuildOptions, reason?: RebuildReason): Promise<RebuildReport>;
735
+ private _runRebuild;
736
+ private _doRebuild;
658
737
  gotoFrame(frame: number, force?: boolean): Promise<void>;
659
738
  /** Run `fn` with `seeking` / `seeked` silenced: the movie is moving its own playhead, not answering a seek. */
660
739
  private _quietly;
@@ -772,6 +851,8 @@ declare class Movie {
772
851
  * then puts the playhead (or the poster) back where it was, whatever `fn` did, and returns what `fn` returned.
773
852
  */
774
853
  peek<T>(fn: () => Promise<T>): Promise<T>;
854
+ /** Run `fn` as the only thing that moves the composition: waits for a rebuild in flight, and holds the next one's swap until `fn` is done. */
855
+ private _exclusive;
775
856
  private _settleUntil;
776
857
  private _cancelUntil;
777
858
  /** The playhead reached the frame `playUntil()` was playing to: land exactly on it, pause, resolve true. */
@@ -783,8 +864,14 @@ declare class Movie {
783
864
  set muted(v: boolean);
784
865
  get muted(): boolean;
785
866
  toggleMute(): boolean;
867
+ /**
868
+ * At the end of an ordinary `play()` the movie goes back to the start and plays on (no `ended`, no `pause` / `play` events at the wrap; the sound
869
+ * starts again). Default false. `playUntil()` and `render()` ignore it. Can be changed at any time; `loopchange` says so.
870
+ */
871
+ set loop(v: boolean);
872
+ get loop(): boolean;
786
873
  render(options?: RenderOptions): Promise<Blob>;
787
874
  destroy(): Promise<void>;
788
875
  }
789
876
 
790
- export { type AudioInspectOptions as A, failLoader as B, type ContactSheetOptions as C, resolveLoader as D, type FontReport as F, type InspectOptions as I, type LayerInfo as L, type MusicEvents as M, type OnionSkinOptions as O, type ProgressEvent as P, type RenderOptions as R, type SnapshotOptions as S, type TimelineData as T, type VolumeEvent as V, type AudioReport as a, type AudioSourceReport as b, type FrameEvent as c, type InspectReport as d, type IssueGroup as e, type LoadProgressState as f, type LoadStage as g, type LoaderOption as h, type MotionBlurOptions as i, type MotionBlurSpec as j, Movie as k, type MovieErrorEvent as l, type MovieOptions as m, type MusicDrumEvents as n, type MusicDrumHit as o, type MusicNote as p, type MusicSummary as q, type MusicTrackEvents as r, type ReviewOptions as s, type ReviewReport as t, type SoundMeasure as u, type TimelineHtmlOptions as v, type TimelineRow as w, type TimelineSvgOptions as x, type TimelineTransition as y, dismissLoader as z };
877
+ export { type AudioInspectOptions as A, type TimelineRow as B, type ContactSheetOptions as C, type TimelineSvgOptions as D, type TimelineTransition as E, type FontReport as F, dismissLoader as G, failLoader as H, type InspectOptions as I, resolveLoader as J, type LayerInfo as L, type MusicEvents as M, type OnionSkinOptions as O, type ProgressEvent as P, type RebuildOptions as R, type SnapshotOptions as S, type TimelineData as T, type VolumeEvent as V, type AudioReport as a, type AudioSourceReport as b, type FrameEvent as c, type InspectReport as d, type IssueGroup as e, type LoadProgressState as f, type LoadStage as g, type LoaderOption as h, type LoopEvent as i, type MotionBlurOptions as j, type MotionBlurSpec as k, Movie as l, type MovieErrorEvent as m, type MovieOptions as n, type MusicDrumEvents as o, type MusicDrumHit as p, type MusicNote as q, type MusicSummary as r, type MusicTrackEvents as s, type RebuildReason as t, type RebuildReport as u, type RenderOptions as v, type ReviewOptions as w, type ReviewReport as x, type SoundMeasure as y, type TimelineHtmlOptions as z };
@@ -1,5 +1,5 @@
1
1
  import { Application } from 'pixi.js';
2
- import { Z as Stop, c as AssetSpec, k as CompositionSpec } from './types-BzIB65Vk.js';
2
+ import { Z as Stop, c as AssetSpec, k as CompositionSpec } from './types-CK_crNAI.js';
3
3
 
4
4
  type EaseFn = (p: number) => number;
5
5
 
@@ -417,6 +417,10 @@ interface TimelineSvgOptions {
417
417
  labels?: boolean;
418
418
  }
419
419
 
420
+ /** A variable holds a number (read as an identifier in an expression) or a string (read as `{name}` in any string of the spec). */
421
+ type VarValue = number | string;
422
+ type Vars = Record<string, VarValue>;
423
+
420
424
  /**
421
425
  * How far `movie.init()` is: one number from 0 to 1 for a movie that takes seconds to build, the stage it is in and how many of that stage are done.
422
426
  * The stages run in a fixed order and carry a share of the whole (the shares come from timings of the reel and the gallery); a stage that is never
@@ -467,6 +471,12 @@ interface MovieOptions {
467
471
  canvas?: HTMLCanvasElement;
468
472
  assets?: AssetSpec[];
469
473
  composition?: CompositionSpec;
474
+ /**
475
+ * Named variables: numbers an expression reads as identifiers (`x: 'W/2 + shift'`) and strings that `{name}` stands for anywhere in the
476
+ * composition (`text: '{title}'`, `fillColor: '{accent}'`). Change them later with `movie.setVars()`, which rebuilds the movie at the same time.
477
+ * A name an expression already means (`W`, `t`, `sin`, `PI`, `value` …) is refused.
478
+ */
479
+ vars?: Vars;
470
480
  /**
471
481
  * The poster time in seconds: the moment that stands for the movie before it plays. The canvas shows that frame once the movie is
472
482
  * ready, the playhead stays at 0 and play starts from 0 (like `<video poster>`); `movie.posterImage()` is that picture. A negative
@@ -484,6 +494,8 @@ interface MovieOptions {
484
494
  * the canvas is used. It is faded out once the movie is ready (the poster is on the canvas) and, if `init()` fails, it stops and says so.
485
495
  */
486
496
  loader?: LoaderOption;
497
+ /** Start with `movie.loop` on: playing goes back to the start at the end instead of stopping. Default false (like a `<video>`). */
498
+ loop?: boolean;
487
499
  }
488
500
 
489
501
  interface RenderOptions {
@@ -527,6 +539,24 @@ interface SnapshotOptions {
527
539
  /** Return a `data:` URL string instead of a Blob (handy for scripts that can only return text), or `'imageData'`: the pixels as an `ImageData` (to measure, compare). */
528
540
  as?: 'blob' | 'dataURL' | 'imageData';
529
541
  }
542
+ /** What `movie.rebuild()` may change: the composition itself, variables (a partial set), the size of the movie. */
543
+ interface RebuildOptions {
544
+ composition?: CompositionSpec;
545
+ vars?: Vars;
546
+ width?: number;
547
+ height?: number;
548
+ }
549
+ type RebuildReason = 'vars' | 'resize' | 'rebuild';
550
+ /** What a rebuild did: how long it took, whether the sound was mixed again (`'mixed'`), reused from the last mix (`'reused'`) or there is none, and where the playhead was put back. */
551
+ interface RebuildReport {
552
+ reason: RebuildReason;
553
+ ms: number;
554
+ audio: 'reused' | 'mixed' | 'none';
555
+ frame: number;
556
+ playing: boolean;
557
+ /** True when nothing changed (`setVars` with the values it already has): nothing was rebuilt. */
558
+ unchanged?: boolean;
559
+ }
530
560
  interface ContactSheetOptions {
531
561
  /** Motion blur for these pictures (see `MovieOptions.motionBlur`); overrides the movie's own setting, `false` turns it off. */
532
562
  motionBlur?: MotionBlurSpec;
@@ -569,9 +599,13 @@ interface VolumeEvent {
569
599
  volume: number;
570
600
  muted: boolean;
571
601
  }
602
+ /** `loopchange`: the value of `movie.loop` after the change. */
603
+ interface LoopEvent {
604
+ loop: boolean;
605
+ }
572
606
  /** `error`: something failed in `init()`, `render()` or during playback. The call that failed still rejects / warns as before. */
573
607
  interface MovieErrorEvent {
574
- where: 'init' | 'render' | 'playback';
608
+ where: 'init' | 'render' | 'playback' | 'rebuild';
575
609
  message: string;
576
610
  error: unknown;
577
611
  }
@@ -599,6 +633,7 @@ declare class Movie {
599
633
  private _quiet;
600
634
  private _volume;
601
635
  private _muted;
636
+ private _loop;
602
637
  isPlaying: boolean;
603
638
  currentFrame: number;
604
639
  totalFrames: number;
@@ -616,6 +651,21 @@ declare class Movie {
616
651
  private _feedTimeFilters;
617
652
  private _rootContainer;
618
653
  private _raf;
654
+ /** The variables now, and the names that were declared (a `setVars` of any other name is refused). */
655
+ private _vars;
656
+ private _declared;
657
+ /** The composition as the author wrote it (before `{name}` is replaced): a rebuild starts from it. */
658
+ private _composition;
659
+ /** True once `resize()` was called: the size of the movie then replaces an explicit `width` / `height` of the composition. */
660
+ private _resized;
661
+ private _mixCache;
662
+ private _rebuildRun;
663
+ private _rebuildNext;
664
+ /** > 0 while a rebuild stops and restarts playback: `play` / `pause` are not announced then (a player's button must not flicker). */
665
+ private _silent;
666
+ /** render() / peek() in flight: a rebuild does not swap the composition under them. */
667
+ private _busy;
668
+ private _idleWaiters;
619
669
  /** What went into the mix, and its peak before limiting — kept for inspectAudio(). */
620
670
  private _audioSources;
621
671
  private _mixStats;
@@ -626,10 +676,14 @@ declare class Movie {
626
676
  /** Playback ran off the end (after `pause`). Pausing by hand does not emit it. */
627
677
  on(event: 'ended', fn: () => void): this;
628
678
  on(event: 'volumechange', fn: (e: VolumeEvent) => void): this;
679
+ /** `movie.loop` changed (set by the page, the bar's loop button or `init({ loop })` is not a change). */
680
+ on(event: 'loopchange', fn: (e: LoopEvent) => void): this;
629
681
  on(event: 'error', fn: (e: MovieErrorEvent) => void): this;
630
682
  on(event: 'progress', fn: (e: ProgressEvent) => void): this;
631
683
  /** How far `init()` is while it builds the movie: `{ stage: 'assets' | 'build' | 'sound' | 'frames', loaded, total, progress }`, `progress` 0 to 1. The page's `.pe-loader` shows it by itself. */
632
684
  on(event: 'loadprogress', fn: (e: LoadProgressState) => void): this;
685
+ /** A `rebuild()` (a `setVars()` or a `resize()` too) finished: what it was and what it cost. */
686
+ on(event: 'rebuilt', fn: (e: RebuildReport) => void): this;
633
687
  on(event: 'play', fn: () => void): this;
634
688
  on(event: 'pause', fn: () => void): this;
635
689
  off(event: string, fn: Listener): this;
@@ -655,6 +709,31 @@ declare class Movie {
655
709
  }): Promise<string>;
656
710
  private _ensureAudioContext;
657
711
  init(options?: MovieOptions): Promise<void>;
712
+ /**
713
+ * Build the composition tree for these variables and this size, off stage: `{name}` replaced, the root shape (with the numeric variables for the
714
+ * expressions), transitions expanded, every layer built. Used by `init` and by `rebuild`.
715
+ */
716
+ private _construct;
717
+ /** Make the sound of a built composition: the same mix as last time when the sounds are the same (`'reused'`), else mix it. */
718
+ private _mixSound;
719
+ /** The variables now (a copy; change them with `setVars()`). */
720
+ get vars(): Readonly<Vars>;
721
+ /**
722
+ * Change variables and rebuild at the same time. Only the declared names (`movie.init({ vars })`) are accepted; another name says which one it
723
+ * looks like and is ignored. Values it already has change nothing: no rebuild (`unchanged: true`).
724
+ */
725
+ setVars(changes: Vars): Promise<RebuildReport>;
726
+ /** Make the movie `width` x `height` pixels (the canvas, and `W` / `H` / `GW` / `GH` in every expression) and rebuild at the same time. */
727
+ resize(width: number, height: number): Promise<RebuildReport>;
728
+ /**
729
+ * Build the composition again, with what `change` replaces (variables, the composition, the size), and put the movie back where it was: the
730
+ * same frame, playing or not, the poster if that was shown. The new composition is built first: when that fails the old one stays, `error` is
731
+ * emitted and the promise rejects. The sound is mixed again only when it changed (`audio: 'reused'` otherwise). Calls that arrive while a
732
+ * rebuild runs are joined into one more rebuild (the latest values win), so a slider can call it on every move.
733
+ */
734
+ rebuild(change?: RebuildOptions, reason?: RebuildReason): Promise<RebuildReport>;
735
+ private _runRebuild;
736
+ private _doRebuild;
658
737
  gotoFrame(frame: number, force?: boolean): Promise<void>;
659
738
  /** Run `fn` with `seeking` / `seeked` silenced: the movie is moving its own playhead, not answering a seek. */
660
739
  private _quietly;
@@ -772,6 +851,8 @@ declare class Movie {
772
851
  * then puts the playhead (or the poster) back where it was, whatever `fn` did, and returns what `fn` returned.
773
852
  */
774
853
  peek<T>(fn: () => Promise<T>): Promise<T>;
854
+ /** Run `fn` as the only thing that moves the composition: waits for a rebuild in flight, and holds the next one's swap until `fn` is done. */
855
+ private _exclusive;
775
856
  private _settleUntil;
776
857
  private _cancelUntil;
777
858
  /** The playhead reached the frame `playUntil()` was playing to: land exactly on it, pause, resolve true. */
@@ -783,8 +864,14 @@ declare class Movie {
783
864
  set muted(v: boolean);
784
865
  get muted(): boolean;
785
866
  toggleMute(): boolean;
867
+ /**
868
+ * At the end of an ordinary `play()` the movie goes back to the start and plays on (no `ended`, no `pause` / `play` events at the wrap; the sound
869
+ * starts again). Default false. `playUntil()` and `render()` ignore it. Can be changed at any time; `loopchange` says so.
870
+ */
871
+ set loop(v: boolean);
872
+ get loop(): boolean;
786
873
  render(options?: RenderOptions): Promise<Blob>;
787
874
  destroy(): Promise<void>;
788
875
  }
789
876
 
790
- export { type AudioInspectOptions as A, failLoader as B, type ContactSheetOptions as C, resolveLoader as D, type FontReport as F, type InspectOptions as I, type LayerInfo as L, type MusicEvents as M, type OnionSkinOptions as O, type ProgressEvent as P, type RenderOptions as R, type SnapshotOptions as S, type TimelineData as T, type VolumeEvent as V, type AudioReport as a, type AudioSourceReport as b, type FrameEvent as c, type InspectReport as d, type IssueGroup as e, type LoadProgressState as f, type LoadStage as g, type LoaderOption as h, type MotionBlurOptions as i, type MotionBlurSpec as j, Movie as k, type MovieErrorEvent as l, type MovieOptions as m, type MusicDrumEvents as n, type MusicDrumHit as o, type MusicNote as p, type MusicSummary as q, type MusicTrackEvents as r, type ReviewOptions as s, type ReviewReport as t, type SoundMeasure as u, type TimelineHtmlOptions as v, type TimelineRow as w, type TimelineSvgOptions as x, type TimelineTransition as y, dismissLoader as z };
877
+ export { type AudioInspectOptions as A, type TimelineRow as B, type ContactSheetOptions as C, type TimelineSvgOptions as D, type TimelineTransition as E, type FontReport as F, dismissLoader as G, failLoader as H, type InspectOptions as I, resolveLoader as J, type LayerInfo as L, type MusicEvents as M, type OnionSkinOptions as O, type ProgressEvent as P, type RebuildOptions as R, type SnapshotOptions as S, type TimelineData as T, type VolumeEvent as V, type AudioReport as a, type AudioSourceReport as b, type FrameEvent as c, type InspectReport as d, type IssueGroup as e, type LoadProgressState as f, type LoadStage as g, type LoaderOption as h, type LoopEvent as i, type MotionBlurOptions as j, type MotionBlurSpec as k, Movie as l, type MovieErrorEvent as m, type MovieOptions as n, type MusicDrumEvents as o, type MusicDrumHit as p, type MusicNote as q, type MusicSummary as r, type MusicTrackEvents as s, type RebuildReason as t, type RebuildReport as u, type RenderOptions as v, type ReviewOptions as w, type ReviewReport as x, type SoundMeasure as y, type TimelineHtmlOptions as z };
@@ -1,4 +1,4 @@
1
- import { MAX_CASTERS, Sequence, timeRemapOf, contentLength, remapOf, buildSequenceTree, CameraSequence, LightSequence, layerInitialZ, createTimeline, bindClock, clockTable, NullSequence, lightLevel, homeCamera, cameraBasis, packLights, projectPoint, NEAR, blurRadius, MANY_BLURRED, focusProblems, MAX_LIGHTS, projectLayer, layerToWorld, FALLOFFS, LIGHT_PROPS, LIGHT_KINDS, MIN_BLUR, MAX_BLUR, DEG, SHADOW_TAPS } from './chunk-ZAXYPXKW.js';
1
+ import { MAX_CASTERS, Sequence, timeRemapOf, contentLength, remapOf, buildSequenceTree, CameraSequence, LightSequence, layerInitialZ, createTimeline, bindClock, clockTable, NullSequence, lightLevel, homeCamera, cameraBasis, packLights, projectPoint, NEAR, blurRadius, MANY_BLURRED, focusProblems, MAX_LIGHTS, projectLayer, layerToWorld, FALLOFFS, LIGHT_PROPS, LIGHT_KINDS, MIN_BLUR, MAX_BLUR, DEG, SHADOW_TAPS } from './chunk-MMTESMJ5.js';
2
2
  import { maxConcurrentAdvanced, MANY_ADVANCED, applyBlendMode, isAdvancedBlend, blendFilterFor } from './chunk-4KB3GUEK.js';
3
3
  import { describeLayer, lintTiming, lintText, lintKeys, summarizeWarnings, collectPropKeys } from './chunk-RCVZX2JP.js';
4
4
  import { suggestName } from './chunk-BXOCEZ4U.js';
@@ -1723,5 +1723,5 @@ function frameOf(child) {
1723
1723
  }
1724
1724
 
1725
1725
  export { CompositionSequence, maskSourceOf };
1726
- //# sourceMappingURL=chunk-A3Q3SDSH.js.map
1727
- //# sourceMappingURL=chunk-A3Q3SDSH.js.map
1726
+ //# sourceMappingURL=chunk-BGMCZA36.js.map
1727
+ //# sourceMappingURL=chunk-BGMCZA36.js.map