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.
- package/dist/game/nlcore/action/actionTypes.d.ts +7 -3
- package/dist/game/nlcore/action/actions/displayableAction.d.ts +28 -0
- package/dist/game/nlcore/action/actions/vfxAction.d.ts +1 -0
- package/dist/game/nlcore/action/actions/videoAction.d.ts +1 -0
- package/dist/game/nlcore/elements/camera.d.ts +2 -1
- package/dist/game/nlcore/elements/displayable/displayable.d.ts +76 -0
- package/dist/game/nlcore/elements/displayable/image.d.ts +2 -1
- package/dist/game/nlcore/elements/displayable/puppet.d.ts +2 -1
- package/dist/game/nlcore/elements/displayable/text.d.ts +2 -1
- package/dist/game/nlcore/elements/layer.d.ts +2 -1
- package/dist/game/nlcore/elements/transform/transform.d.ts +7 -0
- package/dist/game/nlcore/elements/transform/type.d.ts +40 -0
- package/dist/game/nlcore/elements/vfx.d.ts +46 -2
- package/dist/game/nlcore/elements/video.d.ts +11 -0
- package/dist/game/player/elements/type.d.ts +2 -2
- package/dist/game/player/type.d.ts +11 -0
- package/dist/main.js +47 -48
- package/package.json +2 -2
|
@@ -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
|
-
*
|
|
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
|
|
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
|
|
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?:
|
|
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;
|