narraleaf-react 0.47.0 → 0.47.2
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/built-in.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Gallery as L,DevTools as S}from"narraleaf-react";import{Control as r,Image as b,Layer as T,Transform as h}from"narraleaf-react";var d=new WeakMap;function y(e,t={}){let n=d.get(e);if(n)return n;let o=new T(t.name??"[[Effect Layer of "+e.config.name+"]]",{zIndex:t.zIndex??1e3});return e.config.layers.push(o),d.set(e,o),o}function k(e,t={}){let{closeDuration:n=180,hold:o=100,openDuration:p=220,easing:i="easeInOut",color:l="#000"}=t,f=y(e),a=u("[[Blink Top of "+e.config.name+"]]",l,f),s=u("[[Blink Bottom of "+e.config.name+"]]",l,f);return r.do([r.all([a.transform(c([[{opacity:1,clipPath:"inset(0 0 100% 0)"},{duration:0}],[{clipPath:"inset(0 0 50% 0)"},{duration:n,ease:i}]])),s.transform(c([[{opacity:1,clipPath:"inset(100% 0 0 0)"},{duration:0}],[{clipPath:"inset(50% 0 0 0)"},{duration:n,ease:i}]]))]),...o>0?[r.sleep(o)]:[],r.all([a.transform(c([[{clipPath:"inset(0 0 50% 0)"},{duration:0}],[{clipPath:"inset(0 0 100% 0)"},{duration:p,ease:i}],[{opacity:0,clipPath:"inset(0 0 100% 0)"},{duration:0}]])),s.transform(c([[{clipPath:"inset(50% 0 0 0)"},{duration:0}],[{clipPath:"inset(100% 0 0 0)"},{duration:p,ease:i}],[{opacity:0,clipPath:"inset(100% 0 0 0)"},{duration:0}]]))]),r.all([r.do([a.opacity(0,0),a.clearClip({duration:0})]),r.do([s.opacity(0,0),s.clearClip({duration:0})])])])}function E(e,t={}){let{duration:n=300,opacity:o=.72,color:p="#000",inner:i="44%",outer:l="78%",hold:f=600,easing:a="easeInOut"}=t,s=y(e),m=u("[[Vignette of "+e.config.name+"]]",p,s),g=`radial-gradient(circle at center, transparent ${i}, black ${l})`;return r.do([m.transform(c([[{opacity:0,maskImage:g,maskSize:"100% 100%",maskPosition:"
|
|
1
|
+
import{Gallery as L,DevTools as S}from"narraleaf-react";import{Control as r,Image as b,Layer as T,Transform as h}from"narraleaf-react";var d=new WeakMap;function y(e,t={}){let n=d.get(e);if(n)return n;let o=new T(t.name??"[[Effect Layer of "+e.config.name+"]]",{zIndex:t.zIndex??1e3});return e.config.layers.push(o),d.set(e,o),o}function k(e,t={}){let{closeDuration:n=180,hold:o=100,openDuration:p=220,easing:i="easeInOut",color:l="#000"}=t,f=y(e),a=u("[[Blink Top of "+e.config.name+"]]",l,f),s=u("[[Blink Bottom of "+e.config.name+"]]",l,f);return r.do([r.all([a.transform(c([[{opacity:1,clipPath:"inset(0 0 100% 0)"},{duration:0}],[{clipPath:"inset(0 0 50% 0)"},{duration:n,ease:i}]])),s.transform(c([[{opacity:1,clipPath:"inset(100% 0 0 0)"},{duration:0}],[{clipPath:"inset(50% 0 0 0)"},{duration:n,ease:i}]]))]),...o>0?[r.sleep(o)]:[],r.all([a.transform(c([[{clipPath:"inset(0 0 50% 0)"},{duration:0}],[{clipPath:"inset(0 0 100% 0)"},{duration:p,ease:i}],[{opacity:0,clipPath:"inset(0 0 100% 0)"},{duration:0}]])),s.transform(c([[{clipPath:"inset(50% 0 0 0)"},{duration:0}],[{clipPath:"inset(100% 0 0 0)"},{duration:p,ease:i}],[{opacity:0,clipPath:"inset(100% 0 0 0)"},{duration:0}]]))]),r.all([r.do([a.opacity(0,0),a.clearClip({duration:0})]),r.do([s.opacity(0,0),s.clearClip({duration:0})])])])}function E(e,t={}){let{duration:n=300,opacity:o=.72,color:p="#000",inner:i="44%",outer:l="78%",hold:f=600,easing:a="easeInOut"}=t,s=y(e),m=u("[[Vignette of "+e.config.name+"]]",p,s),g=`radial-gradient(circle at center, transparent ${i}, black ${l})`;return r.do([m.transform(c([[{opacity:0,maskImage:g,maskSize:"100% 100%",maskPosition:"50% 50%",maskRepeat:"no-repeat",maskMode:"alpha"},{duration:0}],[{opacity:o},{duration:n,ease:a}]])),...f>0?[r.sleep(f)]:[],m.transform(c([[{opacity:0},{duration:n,ease:a}]])),m.clearMask({duration:0})])}function u(e,t,n){return new b({name:e,src:t,autoFit:!0,opacity:0,layer:n})}function c(e){return new h(e.map(([t,n])=>({props:t,options:n})))}export{S as DevTools,L as Gallery,k as blink,y as effectLayer,E as vignette};
|
|
@@ -46,12 +46,20 @@ export declare class SceneAction<T extends typeof SceneActionTypes[keyof typeof
|
|
|
46
46
|
* Waits until the previous BGM has completely faded out (if any) before
|
|
47
47
|
* resolving, ensuring seamless audio transition when jumping between scenes.
|
|
48
48
|
*
|
|
49
|
-
* A **suspended** scene starts nothing
|
|
49
|
+
* A **suspended** scene starts nothing, and neither does a scene whose music a load has
|
|
50
|
+
* already put back and left playing. This is the one place every path that starts a scene's
|
|
50
51
|
* music passes through, and it has to be the guard, because the call that reaches it is not
|
|
51
52
|
* always the one that asked: `getExposedStateAsync` waits on a component that is not mounted
|
|
52
53
|
* yet, and a stage remount - which is what loading a save performs - fires those waiting
|
|
53
54
|
* callbacks all over again. A caller parked behind a scene call therefore came back from a save
|
|
54
55
|
* with its music playing over the scene it had called.
|
|
56
|
+
*
|
|
57
|
+
* The same reason makes the second refusal necessary rather than something the load could sort
|
|
58
|
+
* out for itself. Every host applies a save as `newGame().deserialize(saved)`, and `newGame()`
|
|
59
|
+
* mounts the entry scene *first*: the callback that starts its music is armed before the load
|
|
60
|
+
* has run at all, and comes back once the load has finished restoring the audio. Whatever the
|
|
61
|
+
* load arms or declines to arm, that one is already in flight - so the refusal has to be here,
|
|
62
|
+
* where the order the callbacks were armed in cannot matter.
|
|
55
63
|
*/
|
|
56
64
|
static initBackgroundMusic(scene: Scene, exposed: ExposedState[ExposedStateType.scene], state?: GameState): Promise<void>;
|
|
57
65
|
static createSceneSnapshot(scene: Scene, state: GameState): SceneSnapshot;
|
|
@@ -93,6 +93,20 @@ export declare class Timeline {
|
|
|
93
93
|
setGuard(guard: GameStateGuard): this;
|
|
94
94
|
protected catSettled(): [resolved: Timeline[], cancelled: Timeline[]];
|
|
95
95
|
protected onTimelineRegistered(callback: () => void): this;
|
|
96
|
+
/**
|
|
97
|
+
* Work out the status again, after the awaitable or one of the children has settled.
|
|
98
|
+
*
|
|
99
|
+
* A settled timeline keeps the status it settled with. Children still settle after it -
|
|
100
|
+
* aborting a timeline aborts its children, and each of them reports back here - and that is
|
|
101
|
+
* the abort running its course, not a second outcome.
|
|
102
|
+
*
|
|
103
|
+
* A resolved awaitable is not an aborted one, although its skip controller says it is:
|
|
104
|
+
* `Awaitable.resolve` retires the controller with `cancel()`, which leaves `isAborted()` true.
|
|
105
|
+
* Reading the controller alone called a timeline cancelled the moment its awaitable resolved
|
|
106
|
+
* while a child was still running - a transform or transition action, whose own awaitable
|
|
107
|
+
* resolves one step before the animation it waits for, or a line whose voice outlives it - and
|
|
108
|
+
* then refused the `resolved` the child brought when it finished.
|
|
109
|
+
*/
|
|
96
110
|
private resolveStatus;
|
|
97
111
|
private emitEvents;
|
|
98
112
|
/**
|
|
@@ -79,6 +79,20 @@ export declare class AudioManager {
|
|
|
79
79
|
* whether the reference was really taken, which a release has to wait for.
|
|
80
80
|
*/
|
|
81
81
|
private retained;
|
|
82
|
+
/**
|
|
83
|
+
* What the most recent load put on the wire, keyed by the clip it put there.
|
|
84
|
+
*
|
|
85
|
+
* Written the moment {@link AudioManager.fromData} is handed a record - before any of the
|
|
86
|
+
* fetching and decoding it starts - because the question it answers is asked by callers that
|
|
87
|
+
* run a turn or two later and must not depend on having lost a race with the restore.
|
|
88
|
+
*
|
|
89
|
+
* An entry stands until something else takes the clip over: every other transport that starts
|
|
90
|
+
* or ends a clip drops it, so the answer can only be "yes" while the load really is the reason
|
|
91
|
+
* that clip is where it is. The value is whether the record wanted the clip *running* - a
|
|
92
|
+
* stopped or paused one is restored just as faithfully, but it is not something a scene start
|
|
93
|
+
* would be taking away.
|
|
94
|
+
*/
|
|
95
|
+
private restoredByLoad;
|
|
82
96
|
private globalVolume;
|
|
83
97
|
private sound;
|
|
84
98
|
private ready;
|
|
@@ -252,6 +266,25 @@ export declare class AudioManager {
|
|
|
252
266
|
fromData(data: AudioManagerDataRaw, elementMap: Map<string, LogicAction.GameElement>): this;
|
|
253
267
|
soundFromData(sound: SoundElement, data: AudioDataRaw): void;
|
|
254
268
|
isManaged(sound: SoundElement): boolean;
|
|
269
|
+
/**
|
|
270
|
+
* Whether the most recent load is the reason `sound` is on the wire, and left it running.
|
|
271
|
+
*
|
|
272
|
+
* The question a scene has to ask before it starts its own background music: the clip the save
|
|
273
|
+
* restored *is* that music already, playing at the position the player saved, and starting it
|
|
274
|
+
* again is a cross-fade of the track into itself - which stops it and plays it from the top.
|
|
275
|
+
* That throws the saved position away, and the stop lands while the restored element's `play()`
|
|
276
|
+
* is still pending, which the browser reports as an `AbortError`.
|
|
277
|
+
*
|
|
278
|
+
* Answered from the record rather than from the live token on purpose. A restore takes several
|
|
279
|
+
* turns to fetch and start a clip, and a scene mounting can get here first; reading
|
|
280
|
+
* `isPlaying()` would then say "nothing is playing" and the scene would start the very clip the
|
|
281
|
+
* load is in the middle of putting back. The record is written synchronously, so this is true
|
|
282
|
+
* from the instant the load is asked for.
|
|
283
|
+
*
|
|
284
|
+
* A record that says the clip is stopped or paused is not "running": the save wants silence
|
|
285
|
+
* there, and a scene that would have started music still does.
|
|
286
|
+
*/
|
|
287
|
+
isRunningFromLoad(sound: SoundElement): boolean;
|
|
255
288
|
/**
|
|
256
289
|
* Fetch and decode a sound into the audio cache without playing it, so the first `play()` of
|
|
257
290
|
* this source starts on the same frame it is asked to instead of after a fetch and a decode.
|