narraleaf-react 0.31.4 → 0.33.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.
@@ -21,11 +21,13 @@ export declare const DisplayableActionTypes: {
21
21
  readonly action: "displayable:action";
22
22
  readonly applyTransform: "displayable:applyTransform";
23
23
  readonly applyTransition: "displayable:applyTransition";
24
+ readonly applyLoop: "displayable:applyLoop";
25
+ readonly stopLoop: "displayable:stopLoop";
24
26
  readonly init: "displayable:init";
25
27
  readonly bringToFront: "displayable:bringToFront";
26
28
  };
27
29
  export type DisplayableActionContentType<TransitionType extends Transition = Transition> = {
28
- [K in typeof DisplayableActionTypes[keyof typeof DisplayableActionTypes]]: K extends "displayable:applyTransform" ? [Transform] : K extends "displayable:applyTransition" ? [TransitionType, ((transition: TransitionType) => TransitionType)?] : K extends "displayable:init" ? [scene: Scene | null, layer: Layer | null, isElement?: boolean] : K extends "displayable:bringToFront" ? [] : any;
30
+ [K in typeof DisplayableActionTypes[keyof typeof DisplayableActionTypes]]: K extends "displayable:applyTransform" ? [Transform] : K extends "displayable:applyTransition" ? [TransitionType, ((transition: TransitionType) => TransitionType)?] : K extends "displayable:applyLoop" ? [Transform, TransformDefinitions.LoopOptions?] : K extends "displayable:stopLoop" ? [TransformDefinitions.LoopStopOptions?] : K extends "displayable:init" ? [scene: Scene | null, layer: Layer | null, isElement?: boolean] : K extends "displayable:bringToFront" ? [] : any;
29
31
  };
30
32
  export declare const CharacterActionTypes: {
31
33
  readonly say: "character:say";
@@ -147,6 +149,7 @@ export type LayerActionContentType = {
147
149
  };
148
150
  export declare const VideoActionTypes: {
149
151
  readonly action: "video:action";
152
+ readonly preload: "video:preload";
150
153
  readonly show: "video:show";
151
154
  readonly hide: "video:hide";
152
155
  readonly play: "video:play";
@@ -156,10 +159,11 @@ export declare const VideoActionTypes: {
156
159
  readonly seek: "video:seek";
157
160
  };
158
161
  export type VideoActionContentType = {
159
- [K in typeof VideoActionTypes[keyof typeof VideoActionTypes]]: K extends "video:action" ? any : K extends "video:show" | "video:hide" | "video:play" | "video:pause" | "video:stop" | "video:resume" ? [] : K extends "video:seek" ? [number] : any;
162
+ [K in typeof VideoActionTypes[keyof typeof VideoActionTypes]]: K extends "video:action" ? any : K extends "video:preload" | "video:show" | "video:hide" | "video:play" | "video:pause" | "video:stop" | "video:resume" ? [] : K extends "video:seek" ? [number] : any;
160
163
  };
161
164
  export declare const VfxActionTypes: {
162
165
  readonly action: "vfx:action";
166
+ readonly preload: "vfx:preload";
163
167
  readonly show: "vfx:show";
164
168
  readonly hide: "vfx:hide";
165
169
  readonly pause: "vfx:pause";
@@ -167,7 +171,7 @@ export declare const VfxActionTypes: {
167
171
  readonly setRate: "vfx:setRate";
168
172
  };
169
173
  export type VfxActionContentType = {
170
- [K in typeof VfxActionTypes[keyof typeof VfxActionTypes]]: K extends "vfx:action" ? any : K extends "vfx:show" | "vfx:hide" ? [VfxFadeOptions?] : K extends "vfx:pause" | "vfx:resume" ? [] : K extends "vfx:setRate" ? [number] : any;
174
+ [K in typeof VfxActionTypes[keyof typeof VfxActionTypes]]: K extends "vfx:action" ? any : K extends "vfx:show" | "vfx:hide" ? [VfxFadeOptions?] : K extends "vfx:preload" | "vfx:pause" | "vfx:resume" ? [] : K extends "vfx:setRate" ? [number] : any;
171
175
  };
172
176
  export declare const PuppetActionTypes: {
173
177
  readonly action: "puppet:action";
@@ -11,16 +11,44 @@ import { Layer } from "../../elements/layer";
11
11
  import { LogicAction } from "../../action/logicAction";
12
12
  import { ActionExecutionInjection, ExecutedActionResult } from "../../action/action";
13
13
  import { Story } from "../../elements/story";
14
+ import type { TransformDefinitions } from "../../elements/transform/type";
14
15
  export declare class DisplayableAction<T extends Values<typeof DisplayableActionTypes> = Values<typeof DisplayableActionTypes>, Self extends Displayable<any, any, any> = Displayable<any, any>, TransitionType extends Transition = Transition> extends TypedAction<DisplayableActionContentType<TransitionType>, T, Self> {
15
16
  static ActionTypes: {
16
17
  readonly action: "displayable:action";
17
18
  readonly applyTransform: "displayable:applyTransform";
18
19
  readonly applyTransition: "displayable:applyTransition";
20
+ readonly applyLoop: "displayable:applyLoop";
21
+ readonly stopLoop: "displayable:stopLoop";
19
22
  readonly init: "displayable:init";
20
23
  readonly bringToFront: "displayable:bringToFront";
21
24
  };
22
25
  executeAction(gameState: GameState, injection: ActionExecutionInjection): ExecutedActionResult;
23
26
  applyTransform(state: GameState, element: Displayable<any, any>, transform: Transform, injection: ActionExecutionInjection, onFinished?: () => void): Awaitable<CalledActionResult, CalledActionResult>;
27
+ /**
28
+ * Start a looping transform on the element, and let the story carry straight on.
29
+ *
30
+ * The one action here that resolves without waiting for anything, because there is nothing to
31
+ * wait for: the motion repeats until something ends it. Nothing is attached to a timeline and
32
+ * nothing is left unsettled on the stack — a loop is a property the element carries (see
33
+ * {@link Displayable.loop}), so it is the element's binding, not this action, that a save and a
34
+ * remount read.
35
+ */
36
+ applyLoop(state: GameState, element: Displayable<any, any>, transform: Transform, options: TransformDefinitions.LoopOptions | undefined, injection: ActionExecutionInjection): Awaitable<CalledActionResult>;
37
+ /**
38
+ * End the element's looping transform and ease it back to the pose it kept underneath.
39
+ *
40
+ * Unlike {@link DisplayableAction.applyLoop} this *is* awaited — the way back has a duration,
41
+ * even when that duration is zero.
42
+ */
43
+ stopLoop(state: GameState, element: Displayable<any, any>, options: TransformDefinitions.LoopStopOptions | undefined, injection: ActionExecutionInjection): Awaitable<CalledActionResult>;
44
+ /**
45
+ * Put an element's loop binding back to what it was, and make the running motion agree.
46
+ *
47
+ * Both halves are needed and neither is enough: the binding is what a save and a remount read,
48
+ * the motion is what the player sees. Undoing past a `loop()` has to stop a motion that is
49
+ * running right now; undoing past a `stopLoop()` has to start one that is not.
50
+ */
51
+ private static restoreLoop;
24
52
  applyTransition(state: GameState, element: Displayable<any, any>, transition: TransitionType, injection: ActionExecutionInjection, onFinished?: () => void): Awaitable<CalledActionResult, CalledActionResult>;
25
53
  initDisplayable(state: GameState, scene: Scene | null, element: Displayable<any, any>, layer: Layer | null, isElement: boolean | undefined, injection: ActionExecutionInjection): Awaitable<CalledActionResult>;
26
54
  /**
@@ -10,6 +10,7 @@ import { Story } from "../../elements/story";
10
10
  export declare class VfxAction<T extends Values<typeof VfxActionTypes> = Values<typeof VfxActionTypes>> extends TypedAction<VfxActionContentType, T, Vfx> {
11
11
  static ActionTypes: {
12
12
  readonly action: "vfx:action";
13
+ readonly preload: "vfx:preload";
13
14
  readonly show: "vfx:show";
14
15
  readonly hide: "vfx:hide";
15
16
  readonly pause: "vfx:pause";
@@ -10,6 +10,7 @@ import { Story } from "../../elements/story";
10
10
  export declare class VideoAction<T extends Values<typeof VideoActionTypes> = Values<typeof VideoActionTypes>> extends TypedAction<VideoActionContentType, T, Video> {
11
11
  static ActionTypes: {
12
12
  readonly action: "video:action";
13
+ readonly preload: "video:preload";
13
14
  readonly show: "video:show";
14
15
  readonly hide: "video:hide";
15
16
  readonly play: "video:play";
@@ -1,6 +1,6 @@
1
1
  import { LogicAction } from "../action/logicAction";
2
2
  import { TransformDefinitions } from "../elements/transform/type";
3
- import { Displayable } from "../elements/displayable/displayable";
3
+ import { Displayable, DisplayableLoopRaw } from "../elements/displayable/displayable";
4
4
  import { EventfulDisplayable } from "../../player/elements/displayable/type";
5
5
  import { Chained, Proxied } from "../action/chain";
6
6
  /**
@@ -14,6 +14,7 @@ import { Chained, Proxied } from "../action/chain";
14
14
  export type ICameraUserConfig = TransformDefinitions.CameraTransformProps;
15
15
  export type CameraDataRaw = {
16
16
  transformState: Record<string, any>;
17
+ loop?: DisplayableLoopRaw | null;
17
18
  };
18
19
  /**
19
20
  * A stage-wide camera.
@@ -5,6 +5,28 @@ import { LogicAction } from "../../action/logicAction";
5
5
  import { EventfulDisplayable } from "../../../player/elements/displayable/type";
6
6
  import type { TransformDefinitions } from "../../elements/transform/type";
7
7
  import type { ImageSrc } from "../../types";
8
+ /**
9
+ * A looping transform as it goes into a save.
10
+ *
11
+ * The transform itself is **not** here, and cannot be: its easing may be a function, and a function
12
+ * does not survive a round trip through JSON. What is stored instead is the id of the action that
13
+ * started the loop — the transform is authored data hanging off that action's content node, so the
14
+ * story itself still holds it, and loading resolves the id back to it through the same action map
15
+ * the stack model is restored with. A save whose action the story no longer has simply loses the
16
+ * loop rather than failing to load.
17
+ *
18
+ * Public, unlike the rest of the loop plumbing, because every displayable's `*DataRaw` names it and
19
+ * those are public. An internal-tagged type reached from a public signature is deleted from the
20
+ * emitted declarations while the signature that uses it stays behind naming something that is no
21
+ * longer declared, and only the consumer's `skipLibCheck` hides the result.
22
+ *
23
+ * (Do not write that tag in prose here: `stripInternal` matches it anywhere in the comment, so
24
+ * merely describing the hazard is enough to cause it.)
25
+ */
26
+ export type DisplayableLoopRaw = {
27
+ actionId: string;
28
+ options: TransformDefinitions.LoopOptions;
29
+ };
8
30
  export declare abstract class Displayable<StateData extends Record<string, any>, Self extends Displayable<any, any, any>, TransformType extends TransformDefinitions.Types = TransformDefinitions.Types> extends Actionable<StateData, Self> implements EventfulDisplayable {
9
31
  /**
10
32
  * Set Image Position
@@ -179,6 +201,60 @@ export declare abstract class Displayable<StateData extends Record<string, any>,
179
201
  * ```
180
202
  */
181
203
  transform(transform: Transform<TransformType>): Proxied<Self, Chained<LogicAction.Actions, Self>>;
204
+ /**
205
+ * Play a transform on this element over and over until something stops it.
206
+ *
207
+ * **The line does not wait.** This is the one difference from {@link Displayable.transform}, and
208
+ * the only one worth remembering: `transform()` is a step of the story and the next line waits
209
+ * for it to finish, while `loop()` is a property the element carries — it is set, the story
210
+ * moves on, and the motion keeps running underneath everything that follows.
211
+ *
212
+ * An element carries **one** transform at a time, so anything else applied to it takes the
213
+ * element back: `transform()`, `pos()`, `zoom()`, `show()`, `hide()` and the rest all end the
214
+ * loop and move on from wherever it had got to. What does *not* end it: the player skipping or
215
+ * fast-forwarding, a transition changing the picture, changing scene, or saving and loading —
216
+ * a loaded save puts the loop back.
217
+ *
218
+ * The pose the element had when the loop started is what it returns to, and the only thing a
219
+ * save records; the frames in between are never written down.
220
+ *
221
+ * The transform has to be committed, exactly as for {@link Displayable.transform} — a staged
222
+ * change that was never `commit()`ed is not part of it.
223
+ *
224
+ * @param transform - The motion to repeat. For anything that should not snap on each repeat,
225
+ * either bring it back to where it started or pass `{repeatType: "mirror"}`.
226
+ * @param options - See {@link TransformDefinitions.LoopOptions}.
227
+ * @chainable
228
+ * @example
229
+ * ```ts
230
+ * const breathe = Transform.create()
231
+ * .scaleY(1.015)
232
+ * .commit({ duration: 1900, ease: "easeInOut" });
233
+ *
234
+ * scene.action([
235
+ * yuko.loop(breathe, { repeatType: "mirror" }),
236
+ * yuko.say`...`, // plays while she keeps breathing
237
+ * yuko.stopLoop({ duration: 300 }),
238
+ * ]);
239
+ * ```
240
+ */
241
+ loop(transform: Transform<TransformType>, options?: TransformDefinitions.LoopOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
242
+ /**
243
+ * End the element's looping transform and put it back to the pose it had before the loop
244
+ * started.
245
+ *
246
+ * Unlike {@link Displayable.loop}, this **is** something the line waits for — there is a
247
+ * definite end to wait for. With no duration the element is back in place on the same frame.
248
+ *
249
+ * A no-op on an element that is not looping.
250
+ *
251
+ * @chainable
252
+ * @example
253
+ * ```ts
254
+ * yuko.stopLoop({ duration: 300, ease: "easeOut" });
255
+ * ```
256
+ */
257
+ stopLoop(options?: TransformDefinitions.LoopStopOptions): Proxied<Self, Chained<LogicAction.Actions, Self>>;
182
258
  /**
183
259
  * Bring the Displayable to the front of the layer it is on.
184
260
  *
@@ -3,7 +3,7 @@ import { Color, ImageSrc } from "../../types";
3
3
  import { LogicAction } from "../../game";
4
4
  import { FlexibleTuple, SelectElementFromEach } from "../../../../util/data";
5
5
  import { Chained, Proxied } from "../../action/chain";
6
- import { Displayable } from "../../elements/displayable/displayable";
6
+ import { Displayable, DisplayableLoopRaw } from "../../elements/displayable/displayable";
7
7
  import { EventfulDisplayable } from "../../../player/elements/displayable/type";
8
8
  import { ImageTransition } from "../../elements/transition/transitions/image/imageTransition";
9
9
  import { Layer } from "../../elements/layer";
@@ -46,6 +46,7 @@ export interface IImageUserConfig<Tag extends TagGroupDefinition | null = TagGro
46
46
  export type ImageDataRaw = {
47
47
  state: Record<string, any>;
48
48
  transformState: Record<string, any>;
49
+ loop?: DisplayableLoopRaw | null;
49
50
  };
50
51
  export type TagGroupDefinition = string[][];
51
52
  export type TagSrcResolver<T extends TagGroupDefinition> = (...tags: SelectElementFromEach<T>) => string;
@@ -1,5 +1,5 @@
1
1
  import type { TransformDefinitions } from "../../elements/transform/type";
2
- import { Displayable } from "../../elements/displayable/displayable";
2
+ import { Displayable, DisplayableLoopRaw } from "../../elements/displayable/displayable";
3
3
  import { EventfulDisplayable } from "../../../player/elements/displayable/type";
4
4
  import { Chained, Proxied } from "../../action/chain";
5
5
  import { LogicAction } from "../../action/logicAction";
@@ -80,6 +80,7 @@ export type PuppetCommandOptions = {
80
80
  export type PuppetDataRaw = {
81
81
  state: Record<string, any>;
82
82
  transformState: Record<string, any>;
83
+ loop?: DisplayableLoopRaw | null;
83
84
  };
84
85
  /**
85
86
  * A displayable whose interior is drawn by a backend the host registered.
@@ -2,7 +2,7 @@ import { Color } from "../../types";
2
2
  import { Chained, Proxied } from "../../action/chain";
3
3
  import { LogicAction } from "../../action/logicAction";
4
4
  import type { TransformDefinitions } from "../../elements/transform/type";
5
- import { Displayable } from "../../elements/displayable/displayable";
5
+ import { Displayable, DisplayableLoopRaw } from "../../elements/displayable/displayable";
6
6
  import { EventfulDisplayable } from "../../../player/elements/displayable/type";
7
7
  import { Layer } from "../../elements/layer";
8
8
  export type TextConfig = {
@@ -52,6 +52,7 @@ export interface ITextUserConfig extends TransformDefinitions.TextTransformProps
52
52
  export type TextDataRaw = {
53
53
  state: Record<string, any>;
54
54
  transformState: Record<string, any>;
55
+ loop?: DisplayableLoopRaw | null;
55
56
  };
56
57
  export declare class Text extends Displayable<TextDataRaw, Text, TransformDefinitions.TextTransformProps> implements EventfulDisplayable {
57
58
  constructor(config: Partial<ITextUserConfig>);
@@ -1,6 +1,6 @@
1
1
  import { LogicAction } from "../action/logicAction";
2
2
  import { TransformDefinitions } from "../elements/transform/type";
3
- import { Displayable } from "../elements/displayable/displayable";
3
+ import { Displayable, DisplayableLoopRaw } from "../elements/displayable/displayable";
4
4
  import { EventfulDisplayable } from "../../player/elements/displayable/type";
5
5
  import { Image } from "../elements/displayable/image";
6
6
  import { Text } from "../elements/displayable/text";
@@ -16,6 +16,7 @@ export interface ILayerUserConfig extends TransformDefinitions.ImageTransformPro
16
16
  export type LayerDataRaw = {
17
17
  state: Record<string, any>;
18
18
  transformState: Record<string, any>;
19
+ loop?: DisplayableLoopRaw | null;
19
20
  };
20
21
  export declare class Layer extends Displayable<LayerDataRaw, Layer, TransformDefinitions.ImageTransformProps> implements EventfulDisplayable {
21
22
  /**
@@ -24,6 +24,13 @@ export type TransformCompanion = {
24
24
  el: Element;
25
25
  project: (props: Partial<TransformDefinitions.Types>) => CSSProps;
26
26
  };
27
+ /**
28
+ * A running looping transform. The only thing a caller can do with one is end it — see
29
+ * {@link Transform.startLoop}.
30
+ */
31
+ export type TransformLoopHandle = {
32
+ stop: () => void;
33
+ };
27
34
  /**
28
35
  * The same thing before the elements are known — what a React host holds, resolved to
29
36
  * {@link TransformCompanion} at the moment the animation is built.
@@ -13,10 +13,50 @@ export declare namespace TransformDefinitions {
13
13
  /**@deprecated */
14
14
  sync?: boolean;
15
15
  };
16
+ /**
17
+ * How a repeat plays each time round.
18
+ *
19
+ * - `"loop"` — start over from the first pose. The jump back is instant, so a sequence that
20
+ * does not return to where it began shows a snap on every repeat.
21
+ * - `"reverse"` — play backwards, then forwards again. No snap.
22
+ * - `"mirror"` — like `"reverse"`, with the easing mirrored too, so an `easeIn` going out is an
23
+ * `easeOut` coming back. This is what a breathing or floating motion wants.
24
+ */
25
+ type RepeatType = "loop" | "reverse" | "mirror";
16
26
  type TransformConfig = {
17
27
  sync: boolean;
18
28
  repeat?: number;
19
29
  repeatDelay?: number;
30
+ repeatType?: RepeatType;
31
+ };
32
+ /**
33
+ * How a looping transform repeats — see {@link Displayable.loop}.
34
+ *
35
+ * There is no "how many times" here on purpose: a loop runs until something stops it. For a
36
+ * bounded number of repeats use `transform.repeat(n)`, which the line waits for, or
37
+ * `Control.repeat`.
38
+ *
39
+ * This is written into the save as-is, so everything in it has to stay plain JSON.
40
+ */
41
+ type LoopOptions = {
42
+ /**@default "loop" */
43
+ repeatType?: RepeatType;
44
+ /**
45
+ * Milliseconds to hold the last pose before the next repeat starts.
46
+ * @default 0
47
+ */
48
+ repeatDelay?: number;
49
+ };
50
+ /**
51
+ * How an element eases out of its looping transform — see {@link Displayable.stopLoop}.
52
+ */
53
+ type LoopStopOptions = {
54
+ /**
55
+ * Milliseconds spent returning to the pose the element had before the loop started.
56
+ * @default 0
57
+ */
58
+ duration?: number;
59
+ ease?: EasingDefinition;
20
60
  };
21
61
  type VisualEffectTransformProps = {
22
62
  maskImage?: React.CSSProperties["maskImage"];
@@ -26,6 +26,22 @@ export type VfxConfig = {
26
26
  export type VfxFadeOptions = {
27
27
  duration?: number;
28
28
  easing?: TransformDefinitions.EasingDefinition;
29
+ /**
30
+ * Opacity to fade in to, for this showing only. Defaults to `config.opacity`.
31
+ *
32
+ * The overlay's own opacity is a property of the material — how strong that rain IS — while this
33
+ * is a property of the moment: the same rain reading faintly behind a memory and at full strength
34
+ * in the storm. Read by `show` only; a `hide` always fades to zero.
35
+ */
36
+ opacity?: number;
37
+ /**
38
+ * Playback speed for this showing only. Defaults to `config.playbackRate`.
39
+ *
40
+ * Every `show` restates the speed, so an override lasts exactly as long as the showing that
41
+ * asked for it and the next `show` is back to the configured rate. Like
42
+ * {@link Vfx.setPlaybackRate}, it is not persisted: a loaded save plays at `config.playbackRate`.
43
+ */
44
+ rate?: number;
29
45
  };
30
46
  export type VfxState = {
31
47
  display: boolean;
@@ -58,15 +74,38 @@ export declare class Vfx extends Actionable<VfxStateRaw> {
58
74
  src: string;
59
75
  });
60
76
  /**
61
- * Add the overlay to the stage, fade it in, and start looping playback.
77
+ * Put the overlay on the stage without showing it: the video element is created and starts
78
+ * buffering, at zero opacity and paused.
79
+ *
80
+ * This is what makes a later {@link show} instant. A video that is not in the document has not
81
+ * begun to load, let alone decode, so the first frame of an overlay shown from nothing arrives
82
+ * whenever the decoder gets there — and `show` waits for it rather than fading in an empty
83
+ * rectangle. Declaring the overlay early moves that wait somewhere the player is not looking.
84
+ *
85
+ * Resolves immediately: nothing is waited for, because the point is to stop the story from
86
+ * waiting later. Calling it on an overlay already on stage does nothing.
87
+ * @chainable
88
+ */
89
+ preload(): Proxied<Vfx, Chained<LogicAction.Actions>>;
90
+ /**
91
+ * Fade the overlay in and start looping playback, putting it on the stage first if
92
+ * {@link preload} has not already.
62
93
  *
63
94
  * The action waits for the fade-in to finish. Calling it while the overlay is
64
95
  * already shown is idempotent (the fade-in is re-applied).
96
+ *
97
+ * `options.opacity` and `options.rate` apply to this showing only; both fall back to the
98
+ * overlay's configured values, so a plain `show()` after an overridden one is back to normal.
65
99
  * @chainable
66
100
  */
67
101
  show(options?: VfxFadeOptions): Proxied<Vfx, Chained<LogicAction.Actions>>;
68
102
  /**
69
- * Fade the overlay out, then stop playback and remove it from the stage.
103
+ * Fade the overlay out and stop playback. It stays on the stage, invisible and paused.
104
+ *
105
+ * A paused video decodes nothing, so a hidden overlay costs no frame time — and keeping the
106
+ * element means the next {@link show} has a decoder already holding the clip instead of starting
107
+ * over. Both halves of the same decision: stop the work, keep the warmth. Only a new game or a
108
+ * load clears the stage.
70
109
  *
71
110
  * The action waits for the fade-out to finish. Calling it while the overlay is
72
111
  * not shown is a no-op (a weak warning is logged).
@@ -75,6 +114,11 @@ export declare class Vfx extends Actionable<VfxStateRaw> {
75
114
  hide(options?: VfxFadeOptions): Proxied<Vfx, Chained<LogicAction.Actions>>;
76
115
  /**
77
116
  * Freeze the overlay on its current frame.
117
+ *
118
+ * A freeze is explicit state, not a side effect of being invisible: it survives a
119
+ * {@link hide}/{@link show} pair, so an overlay paused and then hidden comes back still frozen
120
+ * and only {@link resume} starts it moving again. `hide` stops playback of its own accord and
121
+ * does not touch this.
78
122
  * @chainable
79
123
  */
80
124
  pause(): Proxied<Vfx, Chained<LogicAction.Actions>>;
@@ -21,6 +21,17 @@ export declare class Video extends Actionable<VideoStateRaw> {
21
21
  * ```
22
22
  */
23
23
  constructor(config: Partial<VideoConfig>);
24
+ /**
25
+ * Put the video element on the stage without showing it, so it can start buffering.
26
+ *
27
+ * A video that is not in the document has not begun to load. Declaring it ahead of the line
28
+ * that shows or plays it is what turns "the movie starts" into something immediate rather
29
+ * than a wait of unknown length on the player's connection.
30
+ *
31
+ * Resolves immediately, and does nothing to an element already on stage.
32
+ * @chainable
33
+ */
34
+ preload(): Proxied<Video, Chained<LogicAction.Actions>>;
24
35
  /**
25
36
  * Show the video element.
26
37
  * @chainable
@@ -2,7 +2,7 @@ import React, { ErrorInfo } from "react";
2
2
  import { IDialogProps, SayElementProps } from "../elements/say/type";
3
3
  import { IUserMenuProps, MenuElementProps } from "../elements/menu/type";
4
4
  import { Story } from "../../nlcore/elements/story";
5
- import clsx from "clsx";
5
+ import type { ClassValue } from "clsx";
6
6
  import { Game, type GameLifecycleEventContext } from "../../nlcore/game";
7
7
  import { GameState } from "../gameState";
8
8
  import { Storable } from "../../nlcore/elements/persistent/storable";
@@ -33,7 +33,7 @@ export interface PlayerProps {
33
33
  story?: Story;
34
34
  width?: string | number;
35
35
  height?: string | number;
36
- className?: clsx.ClassValue;
36
+ className?: ClassValue;
37
37
  /**
38
38
  * Once the Player is initialized.
39
39
  *
@@ -3,6 +3,7 @@ import { Image } from "../nlcore/elements/displayable/image";
3
3
  import { EventDispatcher } from "../../util/data";
4
4
  import { ImageEvents } from "./elements/image/Image";
5
5
  import { Transform } from "../nlcore/elements/transform/transform";
6
+ import type { TransformDefinitions } from "../nlcore/elements/transform/type";
6
7
  import { Transition } from "../nlcore/elements/transition/transition";
7
8
  import { Layer } from "../nlcore/elements/layer";
8
9
  import { Camera } from "../nlcore/elements/camera";
@@ -36,12 +37,16 @@ export type ExposedState = {
36
37
  events: EventDispatcher<ImageEvents>;
37
38
  initDisplayable: (onResolve: () => void) => Timeline;
38
39
  applyTransform: (transform: Transform, onResolve: () => void) => Timeline;
40
+ applyLoop: (transform: Transform, options?: TransformDefinitions.LoopOptions) => void;
41
+ stopLoop: (options: TransformDefinitions.LoopStopOptions | undefined, onResolve: () => void) => Timeline;
39
42
  applyTransition: (transition: Transition<any>, onResolve: () => void) => Timeline;
40
43
  updateStyleSync: () => void;
41
44
  };
42
45
  [ExposedStateType.text]: {
43
46
  initDisplayable: (onResolve: () => void) => Timeline;
44
47
  applyTransform: (transform: Transform, onResolve: () => void) => Timeline;
48
+ applyLoop: (transform: Transform, options?: TransformDefinitions.LoopOptions) => void;
49
+ stopLoop: (options: TransformDefinitions.LoopStopOptions | undefined, onResolve: () => void) => Timeline;
45
50
  applyTransition: (transition: Transition<any>, onResolve: () => void) => Timeline;
46
51
  updateStyleSync: () => void;
47
52
  flush: () => void;
@@ -49,18 +54,24 @@ export type ExposedState = {
49
54
  [ExposedStateType.layer]: {
50
55
  initDisplayable: (onResolve: () => void) => Timeline;
51
56
  applyTransform: (transform: Transform, onResolve: () => void) => Timeline;
57
+ applyLoop: (transform: Transform, options?: TransformDefinitions.LoopOptions) => void;
58
+ stopLoop: (options: TransformDefinitions.LoopStopOptions | undefined, onResolve: () => void) => Timeline;
52
59
  applyTransition: (transition: Transition<any>, onResolve: () => void) => Timeline;
53
60
  updateStyleSync: () => void;
54
61
  };
55
62
  [ExposedStateType.camera]: {
56
63
  initDisplayable: (onResolve: () => void) => Timeline;
57
64
  applyTransform: (transform: Transform, onResolve: () => void) => Timeline;
65
+ applyLoop: (transform: Transform, options?: TransformDefinitions.LoopOptions) => void;
66
+ stopLoop: (options: TransformDefinitions.LoopStopOptions | undefined, onResolve: () => void) => Timeline;
58
67
  applyTransition: (transition: Transition<any>, onResolve: () => void) => Timeline;
59
68
  updateStyleSync: () => void;
60
69
  };
61
70
  [ExposedStateType.puppet]: {
62
71
  initDisplayable: (onResolve: () => void) => Timeline;
63
72
  applyTransform: (transform: Transform, onResolve: () => void) => Timeline;
73
+ applyLoop: (transform: Transform, options?: TransformDefinitions.LoopOptions) => void;
74
+ stopLoop: (options: TransformDefinitions.LoopStopOptions | undefined, onResolve: () => void) => Timeline;
64
75
  applyTransition: (transition: Transition<any>, onResolve: () => void) => Timeline;
65
76
  updateStyleSync: () => void;
66
77
  flush: () => void;