narraleaf-react 1.0.1 → 1.1.1
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 +2 -1
- package/dist/game/nlcore/action/actions/videoAction.d.ts +21 -0
- package/dist/game/nlcore/common/elements.d.ts +1 -0
- package/dist/game/nlcore/elements/video.d.ts +44 -4
- package/dist/game/player/gameState.d.ts +41 -0
- package/dist/game/player/lib/visibilityFader.d.ts +1 -0
- package/dist/game/player/type.d.ts +7 -3
- package/dist/main.js +47 -46
- package/package.json +1 -1
- package/dist/game/player/lib/useElementVisibility.d.ts +0 -5
|
@@ -16,6 +16,7 @@ import type { Transition } from "../elements/transition/transition";
|
|
|
16
16
|
import type { ImageTransition } from "../elements/transition/transitions/image/imageTransition";
|
|
17
17
|
import type { Layer } from "../elements/layer";
|
|
18
18
|
import type { VfxFadeOptions } from "../elements/vfx";
|
|
19
|
+
import type { VideoFadeOptions } from "../elements/video";
|
|
19
20
|
import type { PuppetCommandOptions } from "../elements/displayable/puppet";
|
|
20
21
|
export declare const DisplayableActionTypes: {
|
|
21
22
|
readonly action: "displayable:action";
|
|
@@ -162,7 +163,7 @@ export declare const VideoActionTypes: {
|
|
|
162
163
|
readonly seek: "video:seek";
|
|
163
164
|
};
|
|
164
165
|
export type VideoActionContentType = {
|
|
165
|
-
[K in typeof VideoActionTypes[keyof typeof VideoActionTypes]]: K extends "video:action" ? any : K extends "video:
|
|
166
|
+
[K in typeof VideoActionTypes[keyof typeof VideoActionTypes]]: K extends "video:action" ? any : K extends "video:show" | "video:hide" ? [VideoFadeOptions?] : K extends "video:preload" | "video:play" | "video:pause" | "video:stop" | "video:resume" ? [] : K extends "video:seek" ? [number] : any;
|
|
166
167
|
};
|
|
167
168
|
export declare const VfxActionTypes: {
|
|
168
169
|
readonly action: "vfx:action";
|
|
@@ -20,7 +20,28 @@ export declare class VideoAction<T extends Values<typeof VideoActionTypes> = Val
|
|
|
20
20
|
readonly seek: "video:seek";
|
|
21
21
|
};
|
|
22
22
|
executeAction(gameState: GameState, injection: ActionExecutionInjection): Awaitable<CalledActionResult>;
|
|
23
|
+
/**
|
|
24
|
+
* A transport row - pause, resume, seek, stop - aimed at a clip that is no longer on the stage.
|
|
25
|
+
*
|
|
26
|
+
* There is nothing to talk to, and nothing it could have done: a clip that has left has stopped,
|
|
27
|
+
* and the next show puts it back from the start. Which side of the clip leaving such a row lands
|
|
28
|
+
* on is not always the author's to decide - a clip played without waiting for it leaves when it
|
|
29
|
+
* ends, at a moment set by how fast the player reads - so a row that would have worked a click
|
|
30
|
+
* earlier must not stop the story a click later. The same answer `hide` gives.
|
|
31
|
+
*/
|
|
32
|
+
private skipOffStage;
|
|
23
33
|
private changeStateBase;
|
|
34
|
+
/**
|
|
35
|
+
* {@link changeStateBase} for a fade, which the player can walk away from halfway.
|
|
36
|
+
*
|
|
37
|
+
* Aborting the action - stepping back, loading a save, starting a new game - abandons the fade
|
|
38
|
+
* where it stands, and the element goes back to showing what `video.state.display` says: the undo
|
|
39
|
+
* that follows the abort then decides what that is. The handler is told through `signal`, so the
|
|
40
|
+
* part of it that records the change never runs for a change that did not happen.
|
|
41
|
+
*/
|
|
42
|
+
private changeStateFading;
|
|
43
|
+
/** Whether a show or hide was asked to fade, rather than to happen at once. */
|
|
44
|
+
private static fades;
|
|
24
45
|
private changeState;
|
|
25
46
|
private changeStateAsync;
|
|
26
47
|
stringify(_story: Story, _seen: Set<LogicAction.Actions>, _strict: boolean): string;
|
|
@@ -23,6 +23,7 @@ import { Puppet } from "../elements/displayable/puppet";
|
|
|
23
23
|
import { NVLToken } from "../elements/nvl";
|
|
24
24
|
export { Character, Narrator, Condition, Control, Image, Lambda, Menu, NVLToken, Scene, Script, Sentence, Sound, Story, Transform, Word, Text, Pause, TextEvent, Persistent, Service, Layer, Camera, Video, Vfx, Puppet, };
|
|
25
25
|
export type { VfxConfig, VfxBlendMode, VfxFadeOptions } from "../elements/vfx";
|
|
26
|
+
export type { VideoFadeOptions } from "../elements/video";
|
|
26
27
|
export type { IPuppetUserConfig, PuppetConfig, PuppetCommandOptions, } from "../elements/displayable/puppet";
|
|
27
28
|
export type { PuppetBackend, PuppetDescription, PuppetInstance, PuppetMountContext, PuppetSize, PuppetState, PuppetStatus, } from "../game/puppet/puppetBackend";
|
|
28
29
|
export type { LayeredDefinition, LayerGroupDefinition, LayerResolver, LayerSlot, LayerTagsOf, LayerVariants, } from "../elements/displayable/image";
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { Actionable } from "../action/actionable";
|
|
2
2
|
import { Chained, Proxied } from "../action/chain";
|
|
3
3
|
import { LogicAction } from "../game";
|
|
4
|
+
import type { TransformDefinitions } from "../elements/transform/type";
|
|
4
5
|
export type VideoConfig = {
|
|
5
6
|
src: string;
|
|
6
7
|
muted: boolean;
|
|
7
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* How {@link Video.show} or {@link Video.hide} fades the clip in or out.
|
|
11
|
+
*
|
|
12
|
+
* Omitted, or with no positive `duration`, the clip appears or disappears at once - which is what
|
|
13
|
+
* `show()` and `hide()` have always done.
|
|
14
|
+
*/
|
|
15
|
+
export type VideoFadeOptions = {
|
|
16
|
+
/** How long the fade takes, in milliseconds. */
|
|
17
|
+
duration?: number;
|
|
18
|
+
/**
|
|
19
|
+
* The curve of the fade: a named easing (`"linear"`, `"easeIn"`, `"easeOut"`, `"easeInOut"`) or a
|
|
20
|
+
* cubic-bezier as four numbers. Linear when omitted. A named easing with no CSS equivalent falls
|
|
21
|
+
* back to `"ease"`, as it does for a `Vfx` fade.
|
|
22
|
+
*/
|
|
23
|
+
easing?: TransformDefinitions.EasingDefinition;
|
|
24
|
+
};
|
|
8
25
|
export type VideoState = {
|
|
9
26
|
display: boolean;
|
|
10
27
|
};
|
|
@@ -33,15 +50,38 @@ export declare class Video extends Actionable<VideoStateRaw> {
|
|
|
33
50
|
*/
|
|
34
51
|
preload(): Proxied<Video, Chained<LogicAction.Actions>>;
|
|
35
52
|
/**
|
|
36
|
-
* Show the video element.
|
|
53
|
+
* Show the video element, putting it on the stage first if it is not there yet.
|
|
54
|
+
*
|
|
55
|
+
* With `options.duration`, the clip fades in over that many milliseconds and the action waits for
|
|
56
|
+
* the fade to finish; it starts once the clip can present a frame, so what fades in is the picture
|
|
57
|
+
* and not an empty rectangle. Without it the clip appears at once.
|
|
37
58
|
* @chainable
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* video.show({duration: 500});
|
|
62
|
+
* ```
|
|
38
63
|
*/
|
|
39
|
-
show(): Proxied<Video, Chained<LogicAction.Actions>>;
|
|
64
|
+
show(options?: VideoFadeOptions): Proxied<Video, Chained<LogicAction.Actions>>;
|
|
40
65
|
/**
|
|
41
|
-
* Hide the video element.
|
|
66
|
+
* Hide the video element and take it off the stage.
|
|
67
|
+
*
|
|
68
|
+
* With `options.duration`, the clip fades out over that many milliseconds - holding whatever frame
|
|
69
|
+
* it is on, which after {@link play} is its last - and leaves the stage once the fade is over; the
|
|
70
|
+
* action waits for that. Without it the clip disappears at once.
|
|
71
|
+
*
|
|
72
|
+
* A clip that is not on the stage has nothing to hide, and the call does nothing.
|
|
42
73
|
* @chainable
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* // A cutscene that clears itself away when it ends
|
|
77
|
+
* scene.action([
|
|
78
|
+
* video.show(),
|
|
79
|
+
* video.play(),
|
|
80
|
+
* video.hide({duration: 600}),
|
|
81
|
+
* ]);
|
|
82
|
+
* ```
|
|
43
83
|
*/
|
|
44
|
-
hide(): Proxied<Video, Chained<LogicAction.Actions>>;
|
|
84
|
+
hide(options?: VideoFadeOptions): Proxied<Video, Chained<LogicAction.Actions>>;
|
|
45
85
|
/**
|
|
46
86
|
* Play the video and wait until it finishes.
|
|
47
87
|
* @chainable
|
|
@@ -133,6 +133,14 @@ export type PlayerStateData = {
|
|
|
133
133
|
* { [layerName]: [displayableId][] }
|
|
134
134
|
*/
|
|
135
135
|
layers: Record<string, string[]>;
|
|
136
|
+
/**
|
|
137
|
+
* The ids of the clips this scene put on the stage. Their state is in
|
|
138
|
+
* {@link PlayerStateData.videos}; this says which scene each one leaves with.
|
|
139
|
+
*
|
|
140
|
+
* Written only when the scene has any. Absent in saves written before clips belonged to
|
|
141
|
+
* scenes, and a clip no scene names is given to the scene the story is running in.
|
|
142
|
+
*/
|
|
143
|
+
videos?: string[];
|
|
136
144
|
};
|
|
137
145
|
}[];
|
|
138
146
|
audio: AudioManagerDataRaw;
|
|
@@ -156,6 +164,14 @@ export type PlayerStateElementSnapshot = {
|
|
|
156
164
|
* scene that is on the stage and one that is on the stage waiting for a call to return.
|
|
157
165
|
*/
|
|
158
166
|
suspended?: boolean;
|
|
167
|
+
/**
|
|
168
|
+
* The clips this scene had on the stage, each with its state, in stage order.
|
|
169
|
+
*
|
|
170
|
+
* A clip is drawn over the scene rather than inside one of its layers, but it belongs to the
|
|
171
|
+
* scene that put it there all the same, and leaves with it. Absent in snapshots taken before
|
|
172
|
+
* clips belonged to scenes; read as none.
|
|
173
|
+
*/
|
|
174
|
+
videos?: [Video, VideoStateRaw][];
|
|
159
175
|
};
|
|
160
176
|
export type PlayerAction = CalledActionResult;
|
|
161
177
|
interface StageUtils {
|
|
@@ -210,6 +226,16 @@ export declare class GameState {
|
|
|
210
226
|
* See {@link VideoWarmQueue}.
|
|
211
227
|
*/
|
|
212
228
|
private readonly videoWarmQueue;
|
|
229
|
+
/**
|
|
230
|
+
* Which scene each of the story's clips belongs to: the one running when the clip went on.
|
|
231
|
+
*
|
|
232
|
+
* A clip is not on one of the scene's layers - it is a sibling of the scene's root, so that a clip
|
|
233
|
+
* the preloader warmed can be taken over without being remounted - so nothing about where it sits
|
|
234
|
+
* says whose it is. And it has to be somebody's, because a scene takes everything it put on the
|
|
235
|
+
* stage with it when it leaves. Kept beside {@link PlayerState.videos} rather than in it, because
|
|
236
|
+
* the stage order of clips is not grouped by scene.
|
|
237
|
+
*/
|
|
238
|
+
private videoOwners;
|
|
213
239
|
private videoMissingReporter;
|
|
214
240
|
/** Sources already reported as unwarmed, so one clip in a loop does not report every pass. */
|
|
215
241
|
private readonly reportedUnwarmedVideos;
|
|
@@ -547,6 +573,21 @@ export declare class GameState {
|
|
|
547
573
|
* excluded explicitly rather than by trusting that route to stay closed.
|
|
548
574
|
*/
|
|
549
575
|
private resetLayers;
|
|
576
|
+
/**
|
|
577
|
+
* The clip half of leaving a scene: every clip the scene put on the stage leaves with it, and
|
|
578
|
+
* goes back to its authored state, exactly as the sprites on its layers do in
|
|
579
|
+
* {@link resetLayers}.
|
|
580
|
+
*
|
|
581
|
+
* Without this a clip outlived its scene, and since a clip paints over its scene's sprites, one
|
|
582
|
+
* that stopped on its last frame covered the whole of the next scene - where nothing could take it
|
|
583
|
+
* down, because a host that names stage objects per scene cannot even name it.
|
|
584
|
+
*
|
|
585
|
+
* Every path that takes a scene off the stage comes through here - a plain jump's exit, a call
|
|
586
|
+
* returning, a jump giving up the callers parked behind it, stepping back over a scene's entrance
|
|
587
|
+
* - and each of them snapshots the scene first (see {@link createElementSnapshot}), so the clips
|
|
588
|
+
* come back with it when the step is undone.
|
|
589
|
+
*/
|
|
590
|
+
private releaseVideosOf;
|
|
550
591
|
private syncNvlDerivedState;
|
|
551
592
|
private emitNvlStateChange;
|
|
552
593
|
private resolveNvlAdvance;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,7 +11,7 @@ import { Text } from "../nlcore/elements/displayable/text";
|
|
|
11
11
|
import { Displayable } from "../nlcore/elements/displayable/displayable";
|
|
12
12
|
import { Scene } from "../nlcore/elements/scene";
|
|
13
13
|
import { Sound } from "../nlcore/elements/sound";
|
|
14
|
-
import { Video } from "../nlcore/elements/video";
|
|
14
|
+
import { Video, VideoFadeOptions } from "../nlcore/elements/video";
|
|
15
15
|
import { Vfx, VfxFadeOptions } from "../nlcore/elements/vfx";
|
|
16
16
|
import { Puppet } from "../nlcore/elements/displayable/puppet";
|
|
17
17
|
import { Timeline } from "./Tasks";
|
|
@@ -80,8 +80,12 @@ export type ExposedState = {
|
|
|
80
80
|
setBackgroundMusic: (music: Sound | null, fade: number) => Promise<void>;
|
|
81
81
|
};
|
|
82
82
|
[ExposedStateType.video]: {
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
/** Resolves once the clip is showing: at once, or when a fade in ends, is skipped or is abandoned. */
|
|
84
|
+
show: (options?: VideoFadeOptions) => Promise<void>;
|
|
85
|
+
/** Resolves once the clip is hidden: at once, or when a fade out ends, is skipped or is abandoned. */
|
|
86
|
+
hide: (options?: VideoFadeOptions) => Promise<void>;
|
|
87
|
+
/** Abandon a fade in flight and show the clip as `video.state.display` says. */
|
|
88
|
+
cancelFade: () => void;
|
|
85
89
|
play: () => Promise<void>;
|
|
86
90
|
pause: () => void;
|
|
87
91
|
resume: () => Promise<void>;
|