narraleaf-react 0.1.3 → 0.1.4
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/README.md +5 -33
- package/dist/game/nlcore/action/actionTypes.d.ts +3 -1
- package/dist/game/nlcore/action/actions/imageAction.d.ts +1 -0
- package/dist/game/nlcore/action/actions.d.ts +3 -0
- package/dist/game/nlcore/action/logicAction.d.ts +1 -1
- package/dist/game/nlcore/elements/image.d.ts +14 -10
- package/dist/game/nlcore/elements/scene.d.ts +2 -2
- package/dist/game/nlcore/gameTypes.d.ts +32 -0
- package/dist/game/player/elements/player/SizeUpdateAnnouncer.d.ts +4 -0
- package/dist/game/player/gameState.d.ts +2 -6
- package/dist/game/player/lib/ErrorBoundary.d.ts +1 -1
- package/dist/game/player/provider/ratio.d.ts +3 -0
- package/dist/main.js +30678 -6
- package/dist/main.js.map +1 -0
- package/dist/util/data.d.ts +3 -0
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
3
|
# NarraLeaf-React
|
|
4
4
|
|
|
5
|
-
English | [简体中文](
|
|
5
|
+
English | [简体中文](docs/README.zh-CN.md)
|
|
6
6
|
|
|
7
7
|
A React visual novel player framework
|
|
8
8
|
|
|
@@ -34,7 +34,7 @@ Read more in [🛠React.NarraLeaf.com](https://react.narraleaf.com)
|
|
|
34
34
|
### Example
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
npx create-react-app
|
|
37
|
+
npx create-react-app nlr-app --template my-first-narraleaf-app
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
to start
|
|
@@ -43,39 +43,11 @@ to start
|
|
|
43
43
|
npm start
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
### Performance
|
|
47
|
-
|
|
48
|
-
Please enable image cache for a better performance.
|
|
49
|
-
Narraleaf-React tries to cache the images before showing them, but it is recommended to enable cache on your server.
|
|
50
|
-
|
|
51
|
-
for NextJS, add this to your `next.config.js`:
|
|
52
|
-
|
|
53
|
-
```js
|
|
54
|
-
/** @type {import('next').NextConfig} */
|
|
55
|
-
const nextConfig = {
|
|
56
|
-
async headers() {
|
|
57
|
-
return [
|
|
58
|
-
{
|
|
59
|
-
source: '/YOUR_IMAGE_ENDPOINT/(.*)', // ex: /static/images/(.*)
|
|
60
|
-
headers: [
|
|
61
|
-
{
|
|
62
|
-
key: 'Cache-Control',
|
|
63
|
-
value: 'public, max-age=31536000, immutable',
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export default nextConfig;
|
|
72
|
-
```
|
|
73
|
-
|
|
74
46
|
## License
|
|
75
47
|
|
|
76
48
|
> NarraLeaf-React is licensed under the MPL License.
|
|
77
|
-
>
|
|
78
|
-
> We updated the license to MPL on 2024-9-24.
|
|
49
|
+
>
|
|
50
|
+
> We updated the license to MPL on 2024-9-24.
|
|
79
51
|
|
|
80
52
|
## Contributing
|
|
81
53
|
|
|
@@ -11,6 +11,7 @@ import type { Sound } from "../elements/sound";
|
|
|
11
11
|
import type { Script } from "../elements/script";
|
|
12
12
|
import { Sentence } from "../elements/character/sentence";
|
|
13
13
|
import type { TransformDefinitions } from "../elements/transform/type";
|
|
14
|
+
import { Image } from "../elements/image";
|
|
14
15
|
export declare const CharacterActionTypes: {
|
|
15
16
|
readonly say: "character:say";
|
|
16
17
|
readonly action: "character:action";
|
|
@@ -56,9 +57,10 @@ export declare const ImageActionTypes: {
|
|
|
56
57
|
readonly setTransition: "image:setTransition";
|
|
57
58
|
readonly applyTransition: "image:applyTransition";
|
|
58
59
|
readonly flush: "image:flush";
|
|
60
|
+
readonly initWearable: "image:initWearable";
|
|
59
61
|
};
|
|
60
62
|
export type ImageActionContentType = {
|
|
61
|
-
[K in typeof ImageActionTypes[keyof typeof ImageActionTypes]]: K extends "image:setSrc" ? [string] : K extends "image:setPosition" ? [CommonDisplayable["position"], Transform<TransformDefinitions.ImageTransformProps>] : K extends "image:show" ? [void, Transform<TransformDefinitions.ImageTransformProps>] : K extends "image:hide" ? [void, Transform<TransformDefinitions.ImageTransformProps>] : K extends "image:applyTransform" ? [void, Transform<TransformDefinitions.ImageTransformProps>, string] : K extends "image:init" ? [Scene?] : K extends "image:dispose" ? [] : K extends "image:setTransition" ? [ITransition | null] : K extends "image:applyTransition" ? [ITransition] : K extends "image:flush" ? [] : any;
|
|
63
|
+
[K in typeof ImageActionTypes[keyof typeof ImageActionTypes]]: K extends "image:setSrc" ? [string] : K extends "image:setPosition" ? [CommonDisplayable["position"], Transform<TransformDefinitions.ImageTransformProps>] : K extends "image:show" ? [void, Transform<TransformDefinitions.ImageTransformProps>] : K extends "image:hide" ? [void, Transform<TransformDefinitions.ImageTransformProps>] : K extends "image:applyTransform" ? [void, Transform<TransformDefinitions.ImageTransformProps>, string] : K extends "image:init" ? [Scene?] : K extends "image:dispose" ? [] : K extends "image:setTransition" ? [ITransition | null] : K extends "image:applyTransition" ? [ITransition] : K extends "image:flush" ? [] : K extends "image:initWearable" ? [Image] : any;
|
|
62
64
|
};
|
|
63
65
|
export declare const ConditionActionTypes: {
|
|
64
66
|
readonly action: "condition:action";
|
|
@@ -17,6 +17,7 @@ export declare class ImageAction<T extends typeof ImageActionTypes[keyof typeof
|
|
|
17
17
|
readonly setTransition: "image:setTransition";
|
|
18
18
|
readonly applyTransition: "image:applyTransition";
|
|
19
19
|
readonly flush: "image:flush";
|
|
20
|
+
readonly initWearable: "image:initWearable";
|
|
20
21
|
};
|
|
21
22
|
executeAction(state: GameState): CalledActionResult | Awaitable<CalledActionResult, any>;
|
|
22
23
|
}
|
|
@@ -2,8 +2,11 @@ import { ContentNode } from "../action/tree/actionTree";
|
|
|
2
2
|
import { LogicAction } from "../action/logicAction";
|
|
3
3
|
import { Action } from "../action/action";
|
|
4
4
|
import { Chained, Proxied } from "../action/chain";
|
|
5
|
+
import { Awaitable } from "../../../util/data";
|
|
6
|
+
import { CalledActionResult } from "../gameTypes";
|
|
5
7
|
export declare class TypedAction<ContentType extends Record<string, any> = Record<string, any>, T extends keyof ContentType & string = keyof ContentType & string, Callee extends LogicAction.GameElement = LogicAction.GameElement> extends Action<ContentType[T], Callee, T> {
|
|
6
8
|
callee: Callee;
|
|
7
9
|
constructor(callee: Proxied<Callee, Chained<LogicAction.Actions, Callee>>, type: T, contentNode: ContentNode<ContentType[T]>);
|
|
8
10
|
unknownType(): void;
|
|
11
|
+
resolveAwaitable<T extends CalledActionResult = any>(handler: (resolve: ((value: T) => void), awaitable: Awaitable<CalledActionResult, T>) => Promise<void> | void, awaitable?: Awaitable<CalledActionResult, T>): Awaitable<CalledActionResult, T>;
|
|
9
12
|
}
|
|
@@ -22,7 +22,7 @@ import { ControlAction } from "../action/actions/controlAction";
|
|
|
22
22
|
import { Text } from "../elements/text";
|
|
23
23
|
import { TextAction } from "../action/actions/textAction";
|
|
24
24
|
export declare namespace LogicAction {
|
|
25
|
-
type Displayable = Text;
|
|
25
|
+
type Displayable = Text | Image;
|
|
26
26
|
type GameElement = Character | Scene | Story | Image | Condition | Script | Menu | Sound | Control | Text;
|
|
27
27
|
type Actions = (TypedAction | CharacterAction | ConditionAction | ImageAction | SceneAction | ScriptAction | StoryAction | MenuAction | SoundAction | ControlAction | TextAction);
|
|
28
28
|
type ActionTypes = Values<typeof CharacterActionTypes> | Values<typeof ConditionActionTypes> | Values<typeof ImageActionTypes> | Values<typeof SceneActionTypes> | Values<typeof ScriptActionTypes> | Values<typeof StoryActionTypes> | Values<typeof MenuActionTypes> | Values<typeof SoundAction.ActionTypes> | Values<typeof ControlAction.ActionTypes> | Values<typeof TextAction.ActionTypes>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import type { TransformDefinitions } from "../elements/transform/type";
|
|
3
2
|
import { Actionable } from "../action/actionable";
|
|
4
3
|
import { Transform } from "./transform/transform";
|
|
@@ -11,25 +10,21 @@ export type ImageConfig = {
|
|
|
11
10
|
src: string | StaticImageData;
|
|
12
11
|
display: boolean;
|
|
13
12
|
disposed?: boolean;
|
|
13
|
+
wearables: Image[];
|
|
14
|
+
isWearable?: boolean;
|
|
14
15
|
} & CommonDisplayable;
|
|
15
16
|
export type ImageDataRaw = {
|
|
16
17
|
state: Record<string, any>;
|
|
17
18
|
};
|
|
18
19
|
export type ImageEventTypes = {
|
|
19
|
-
"event:image.init": [];
|
|
20
|
-
"event:image.mount": [];
|
|
21
|
-
"event:image.unmount": [];
|
|
22
|
-
"event:image.ready": [React.MutableRefObject<HTMLDivElement | null>];
|
|
23
|
-
"event:image.elementLoaded": [];
|
|
24
|
-
"event:image.flush": [];
|
|
25
|
-
"event:image.flushComponent": [];
|
|
26
20
|
"event:displayable.applyTransition": [ITransition];
|
|
27
21
|
"event:displayable.applyTransform": [Transform];
|
|
28
22
|
"event:displayable.init": [];
|
|
23
|
+
"event:wearable.create": [Image];
|
|
29
24
|
};
|
|
30
25
|
export declare class Image extends Actionable<ImageDataRaw, Image> implements EventfulDisplayable {
|
|
31
|
-
constructor(name: string, config:
|
|
32
|
-
constructor(config
|
|
26
|
+
constructor(name: string, config: Partial<ImageConfig>);
|
|
27
|
+
constructor(config?: DeepPartial<ImageConfig>);
|
|
33
28
|
/**
|
|
34
29
|
* Dispose the image
|
|
35
30
|
*
|
|
@@ -109,5 +104,14 @@ export declare class Image extends Actionable<ImageDataRaw, Image> implements Ev
|
|
|
109
104
|
hide(): Proxied<Image, Chained<LogicAction.Actions>>;
|
|
110
105
|
hide(transform: Transform<TransformDefinitions.ImageTransformProps>): Proxied<Image, Chained<LogicAction.Actions>>;
|
|
111
106
|
hide(transform: Partial<TransformDefinitions.CommonTransformProps>): Proxied<Image, Chained<LogicAction.Actions>>;
|
|
107
|
+
/**
|
|
108
|
+
* Add a wearable to the image
|
|
109
|
+
* @param children - Wearable image or images
|
|
110
|
+
*/
|
|
111
|
+
addWearable(children: Image | Image[]): this;
|
|
112
|
+
/**
|
|
113
|
+
* Bind this image to a parent image as a wearable
|
|
114
|
+
*/
|
|
115
|
+
bindWearable(parent: Image): this;
|
|
112
116
|
copy(): Image;
|
|
113
117
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Constructable } from "../action/constructable";
|
|
2
2
|
import { Awaitable } from "../../../util/data";
|
|
3
|
-
import {
|
|
3
|
+
import { color, EventfulDisplayable, ImageColor, ImageSrc, StaticImageData } from "../types";
|
|
4
4
|
import { LogicAction } from "../action/logicAction";
|
|
5
5
|
import { Transform } from "../elements/transform/transform";
|
|
6
6
|
import { IImageTransition, ITransition } from "../elements/transition/type";
|
|
@@ -38,7 +38,7 @@ type ChainedScene = Proxied<Scene, Chained<LogicAction.Actions>>;
|
|
|
38
38
|
export type SceneDataRaw = {
|
|
39
39
|
state: {
|
|
40
40
|
backgroundMusic?: SoundDataRaw | null;
|
|
41
|
-
background?:
|
|
41
|
+
background?: color | StaticImageData | null;
|
|
42
42
|
};
|
|
43
43
|
backgroundImageState?: ImageDataRaw | null;
|
|
44
44
|
};
|
|
@@ -22,6 +22,9 @@ export interface SavedGame {
|
|
|
22
22
|
}
|
|
23
23
|
export type GameConfig = {
|
|
24
24
|
player: {
|
|
25
|
+
/**
|
|
26
|
+
* The id of the container element for the game
|
|
27
|
+
*/
|
|
25
28
|
contentContainerId: string;
|
|
26
29
|
/**
|
|
27
30
|
* The aspect ratio of the game
|
|
@@ -38,10 +41,14 @@ export type GameConfig = {
|
|
|
38
41
|
minHeight: number;
|
|
39
42
|
/**
|
|
40
43
|
* Base width of the player in pixels, Image scale will be calculated based on this value
|
|
44
|
+
*
|
|
45
|
+
* For 16/9, recommended value is 1920
|
|
41
46
|
*/
|
|
42
47
|
width: number;
|
|
43
48
|
/**
|
|
44
49
|
* Base height of the player in pixels, Image scale will be calculated based on this value
|
|
50
|
+
*
|
|
51
|
+
* For 16/9, recommended value is 1080
|
|
45
52
|
*/
|
|
46
53
|
height: number;
|
|
47
54
|
/**
|
|
@@ -89,25 +96,47 @@ export type GameConfig = {
|
|
|
89
96
|
*/
|
|
90
97
|
slowLoadWarning: boolean;
|
|
91
98
|
slowLoadThreshold: number;
|
|
99
|
+
/**
|
|
100
|
+
* If true, when you press [GameConfig.player.skipKey], the game will skip the image transform
|
|
101
|
+
*/
|
|
92
102
|
allowSkipTransform: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* If true, when you press [GameConfig.player.skipKey], the game will skip the image transition
|
|
105
|
+
*/
|
|
93
106
|
allowSkipTransition: boolean;
|
|
94
107
|
};
|
|
95
108
|
menu: {
|
|
96
109
|
use: MenuComponent;
|
|
97
110
|
};
|
|
98
111
|
background: {
|
|
112
|
+
/**
|
|
113
|
+
* If true, when you press [GameConfig.player.skipKey], the game will skip the background transform
|
|
114
|
+
*/
|
|
99
115
|
allowSkipTransform: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* If true, when you press [GameConfig.player.skipKey], the game will skip the background transition
|
|
118
|
+
*/
|
|
100
119
|
allowSkipTransition: boolean;
|
|
101
120
|
};
|
|
102
121
|
text: {
|
|
122
|
+
/**
|
|
123
|
+
* If true, when you press [GameConfig.player.skipKey], the game will skip the text transform
|
|
124
|
+
*/
|
|
103
125
|
allowSkipTransform: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* If true, when you press [GameConfig.player.skipKey], the game will skip the text transition
|
|
128
|
+
*/
|
|
104
129
|
allowSkipTransition: boolean;
|
|
105
130
|
/**
|
|
106
131
|
* Base width of the dialog in pixels
|
|
132
|
+
*
|
|
133
|
+
* For 16/9, recommended value is 1920
|
|
107
134
|
*/
|
|
108
135
|
width: number;
|
|
109
136
|
/**
|
|
110
137
|
* Base height of the dialog in pixels
|
|
138
|
+
*
|
|
139
|
+
* For 16/9, recommended value is 1080 * 0.2
|
|
111
140
|
*/
|
|
112
141
|
height: number;
|
|
113
142
|
};
|
|
@@ -157,6 +186,9 @@ export type GameConfig = {
|
|
|
157
186
|
debug: boolean;
|
|
158
187
|
trace: boolean;
|
|
159
188
|
};
|
|
189
|
+
/**
|
|
190
|
+
* If true, the game will show the inspector when you hover over the element
|
|
191
|
+
*/
|
|
160
192
|
inspector: boolean;
|
|
161
193
|
};
|
|
162
194
|
};
|
|
@@ -16,7 +16,6 @@ import { Text, TextEventTypes } from "../nlcore/elements/text";
|
|
|
16
16
|
type PlayerStateElement = {
|
|
17
17
|
texts: Clickable<TextElement>[];
|
|
18
18
|
menus: Clickable<MenuElement, Choice>[];
|
|
19
|
-
images: Image[];
|
|
20
19
|
displayable: LogicAction.Displayable[];
|
|
21
20
|
};
|
|
22
21
|
export type PlayerState = {
|
|
@@ -31,7 +30,7 @@ export type PlayerStateData = {
|
|
|
31
30
|
scenes: {
|
|
32
31
|
sceneId: string;
|
|
33
32
|
elements: {
|
|
34
|
-
|
|
33
|
+
displayable: string[];
|
|
35
34
|
};
|
|
36
35
|
}[];
|
|
37
36
|
};
|
|
@@ -65,10 +64,6 @@ export declare class GameState {
|
|
|
65
64
|
scene: Scene;
|
|
66
65
|
ele: PlayerStateElement;
|
|
67
66
|
} | null;
|
|
68
|
-
findElementByImage(image: Image): {
|
|
69
|
-
scene: Scene;
|
|
70
|
-
ele: PlayerStateElement;
|
|
71
|
-
} | null;
|
|
72
67
|
findElementByDisplayable(displayable: LogicAction.Displayable): {
|
|
73
68
|
scene: Scene;
|
|
74
69
|
ele: PlayerStateElement;
|
|
@@ -87,6 +82,7 @@ export declare class GameState {
|
|
|
87
82
|
createText(id: string, sentence: Sentence, afterClick?: () => void, scene?: Scene): void;
|
|
88
83
|
createMenu(menu: MenuData, afterChoose?: (choice: Choice) => void, scene?: Scene): void;
|
|
89
84
|
createImage(image: Image, scene?: Scene): this;
|
|
85
|
+
createWearable(parent: Image, image: Image): Promise<any>;
|
|
90
86
|
disposeImage(image: Image, scene?: Scene): this;
|
|
91
87
|
createDisplayable(displayable: LogicAction.Displayable, scene?: Scene): this;
|
|
92
88
|
disposeDisplayable(displayable: LogicAction.Displayable, scene?: Scene): this;
|
|
@@ -23,6 +23,6 @@ export declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, E
|
|
|
23
23
|
errorInfo: null;
|
|
24
24
|
};
|
|
25
25
|
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
26
|
-
render(): string | number | boolean | React.
|
|
26
|
+
render(): string | number | boolean | Iterable<React.ReactNode> | React.JSX.Element | null | undefined;
|
|
27
27
|
}
|
|
28
28
|
export {};
|
|
@@ -12,6 +12,7 @@ type AspectRatioEvents = {
|
|
|
12
12
|
"event:aspectRatio.update": [width: number, height: number];
|
|
13
13
|
"event:aspectRatio.pause": [];
|
|
14
14
|
"event:aspectRatio.resume": [];
|
|
15
|
+
"event:aspectRatio.requestUpdate": [];
|
|
15
16
|
};
|
|
16
17
|
declare class AspectRatio {
|
|
17
18
|
static EventTypes: {
|
|
@@ -37,6 +38,8 @@ declare class AspectRatio {
|
|
|
37
38
|
pause(): void;
|
|
38
39
|
resume(): void;
|
|
39
40
|
onUpdate(callback: (width: number, height: number) => void): () => void;
|
|
41
|
+
requestUpdate(): void;
|
|
42
|
+
onRequestedUpdate(callback: () => void): () => void;
|
|
40
43
|
private triggerUpdate;
|
|
41
44
|
}
|
|
42
45
|
export declare function RatioProvider({ children }: {
|