effect-motion 0.2.0 → 0.3.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/Camera.d.ts +50 -28
- package/dist/Camera.js +71 -19
- package/dist/CameraHelpers.d.ts +70 -0
- package/dist/CameraHelpers.js +239 -0
- package/dist/CanvasExporter.d.ts +12 -0
- package/dist/CanvasExporter.js +40 -0
- package/dist/Color.d.ts +428 -0
- package/dist/Color.js +535 -0
- package/dist/EffectMotionError.d.ts +10 -0
- package/dist/EffectMotionError.js +6 -0
- package/dist/Entity.d.ts +9 -8
- package/dist/Entity.js +1 -4
- package/dist/Fonts.d.ts +10 -0
- package/dist/Fonts.js +16 -0
- package/dist/Images.d.ts +33 -0
- package/dist/Images.js +24 -0
- package/dist/Instance.d.ts +4 -4
- package/dist/Motion.d.ts +24 -7
- package/dist/Motion.js +54 -9
- package/dist/Phaser.d.ts +1 -1
- package/dist/Phaser.js +13 -9
- package/dist/Physics.d.ts +3 -3
- package/dist/Physics.js +4 -4
- package/dist/PngExporter.d.ts +6 -0
- package/dist/PngExporter.js +85 -0
- package/dist/Projection.d.ts +225 -0
- package/dist/Projection.js +473 -0
- package/dist/Renderer.d.ts +102 -53
- package/dist/Renderer.js +369 -78
- package/dist/Runner.d.ts +126 -42
- package/dist/Runner.js +42 -17
- package/dist/Scene.d.ts +88 -59
- package/dist/Scene.js +24 -15
- package/dist/Shapes.d.ts +11 -0
- package/dist/Shapes.js +11 -0
- package/dist/demo.d.ts +3 -186
- package/dist/demo.js +24 -35
- package/dist/index.d.ts +14 -13
- package/dist/index.js +14 -13
- package/dist/particles/Particle.d.ts +4 -3
- package/dist/particles/ParticleField.d.ts +11 -48
- package/dist/particles/ParticleField.js +5 -4
- package/dist/particles/constructors.d.ts +8 -7
- package/dist/particles/constructors.js +2 -2
- package/dist/particles/index.d.ts +5 -6
- package/dist/particles/index.js +5 -6
- package/dist/particles/overLife.d.ts +1 -1
- package/dist/particles/overLife.js +1 -1
- package/dist/particles/simulate.d.ts +2 -2
- package/dist/particles/simulate.js +6 -6
- package/dist/particles/step.d.ts +2 -2
- package/dist/particles/step.js +5 -3
- package/dist/render/dof.d.ts +27 -0
- package/dist/render/dof.js +37 -0
- package/dist/render/paint.d.ts +30 -0
- package/dist/render/paint.js +36 -0
- package/dist/render/shapes.d.ts +42 -0
- package/dist/render/shapes.js +310 -0
- package/dist/shapes/Circle.d.ts +10 -15
- package/dist/shapes/Circle.js +2 -2
- package/dist/shapes/Ellipse.d.ts +10 -16
- package/dist/shapes/Ellipse.js +2 -2
- package/dist/shapes/Group.d.ts +5 -39
- package/dist/shapes/Group.js +4 -4
- package/dist/shapes/Hud.d.ts +38 -0
- package/dist/shapes/Hud.js +35 -0
- package/dist/shapes/Image.d.ts +45 -0
- package/dist/shapes/Image.js +28 -0
- package/dist/shapes/Line.d.ts +12 -12
- package/dist/shapes/Line.js +11 -6
- package/dist/shapes/Path.d.ts +87 -18
- package/dist/shapes/Path.js +25 -6
- package/dist/shapes/Rect.d.ts +33 -23
- package/dist/shapes/Rect.js +14 -2
- package/dist/shapes/Shape2D.d.ts +13 -4
- package/dist/shapes/Shape2D.js +16 -5
- package/dist/shapes/Shapes.d.ts +11 -0
- package/dist/shapes/Shapes.js +11 -0
- package/dist/shapes/Square.d.ts +10 -15
- package/dist/shapes/Square.js +2 -2
- package/dist/shapes/Text.d.ts +10 -19
- package/dist/shapes/Text.js +2 -2
- package/package.json +14 -4
- package/dist/particles/render.d.ts +0 -13
- package/dist/particles/render.js +0 -33
- package/dist/shapes/Layer.d.ts +0 -9
- package/dist/shapes/Layer.js +0 -23
- package/dist/shapes/index.d.ts +0 -10
- package/dist/shapes/index.js +0 -10
- package/dist/svg/SvgDomRenderer.d.ts +0 -28
- package/dist/svg/SvgDomRenderer.js +0 -50
- package/dist/svg/SvgNode.d.ts +0 -13
- package/dist/svg/SvgNode.js +0 -18
- package/dist/svg/SvgRenderer.d.ts +0 -22
- package/dist/svg/SvgRenderer.js +0 -20
- package/dist/svg/camera.d.ts +0 -21
- package/dist/svg/camera.js +0 -43
- package/dist/svg/index.d.ts +0 -6
- package/dist/svg/index.js +0 -6
- package/dist/svg/layers.d.ts +0 -18
- package/dist/svg/layers.js +0 -13
- package/dist/svg/shapes.d.ts +0 -1089
- package/dist/svg/shapes.js +0 -119
package/dist/Scene.d.ts
CHANGED
|
@@ -7,31 +7,24 @@ import type * as Schedule from "effect/Schedule";
|
|
|
7
7
|
import type * as Schema from "effect/Schema";
|
|
8
8
|
import type * as Scope from "effect/Scope";
|
|
9
9
|
import * as Stream from "effect/Stream";
|
|
10
|
-
import type * as
|
|
11
|
-
import type * as
|
|
12
|
-
import * as
|
|
13
|
-
import * as
|
|
10
|
+
import type * as Camera from "./Camera.js";
|
|
11
|
+
import type * as Color from "./Color.js";
|
|
12
|
+
import type * as Entity from "./Entity.js";
|
|
13
|
+
import type * as Instance from "./Instance.js";
|
|
14
|
+
import * as Phaser from "./Phaser.js";
|
|
15
|
+
import * as Runner from "./Runner.js";
|
|
14
16
|
export declare const TypeId: "~motion/Scene";
|
|
15
|
-
export interface Scene<E, R
|
|
17
|
+
export interface Scene<E = never, R = never> {
|
|
16
18
|
readonly [TypeId]: typeof TypeId;
|
|
17
19
|
readonly runner: Effect.Effect<void, E, R | Scope.Scope>;
|
|
18
|
-
readonly "~entities": Entities;
|
|
19
20
|
/** tooling-facing metadata; never read by the runtime */
|
|
20
21
|
readonly annotations: Context.Context<never>;
|
|
21
|
-
annotate<I, S>(key: Context.Key<I, S>, value: S): Scene<E, R
|
|
22
|
-
annotateMerge(context: Context.Context<never>): Scene<E, R
|
|
22
|
+
annotate<I, S>(key: Context.Key<I, S>, value: S): Scene<E, R>;
|
|
23
|
+
annotateMerge(context: Context.Context<never>): Scene<E, R>;
|
|
23
24
|
}
|
|
24
|
-
type
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Eff
|
|
28
|
-
] extends [never] ? never : [Eff] extends [Effect.Effect<infer _A, infer _E, infer R>] ? R : never>;
|
|
29
|
-
export declare const make: <const Eff extends Effect.Effect<any, any, any>, AEff>(f: () => Generator<Eff, void, never>) => MakeEffect<Eff, AEff> extends Effect.Effect<AEff, infer E, infer R> ? Scene<E, Exclude<R, {
|
|
30
|
-
readonly [Entity.TypeId]: typeof Entity.TypeId;
|
|
31
|
-
}> | Scope.Scope, Extract<R, {
|
|
32
|
-
readonly [Entity.TypeId]: typeof Entity.TypeId;
|
|
33
|
-
}>> : never;
|
|
34
|
-
export declare const instantiate: <Name extends string, Data extends Schema.Top, Traits extends Partial<Entity.EntityTraits<Data["Type"]>>, MakeInput>(entity: Entity.Entity<Name, Data, Traits, MakeInput>, props: Runner.InstantiateProps<MakeInput>) => Effect.Effect<Instance.Instance<Name, Data, Traits>, unknown, Entity.Entity<Name, Data, Traits, MakeInput> | Runner.Runner>;
|
|
25
|
+
export type AnyScene = Scene<never, never>;
|
|
26
|
+
export declare const make: <const Eff extends Effect.Effect<any, any, any>, const AEff>(f: () => Generator<Eff, AEff, never>) => Scene<[Eff] extends [never] ? never : [Eff] extends [Effect.Effect<infer _A, infer E, infer _R>] ? E : never, [Eff] extends [never] ? never : [Eff] extends [Effect.Effect<infer _A, infer _E, infer R>] ? R : never>;
|
|
27
|
+
export declare const instantiate: <Name extends string, Data extends Schema.Top, Traits extends Partial<Entity.EntityTraits<Data["Type"]>>>(entity: Entity.Entity<Name, Data, Traits>, props: Runner.InstantiateProps<Data["~type.make.in"]>) => Effect.Effect<Instance.Instance<Name, Data, Traits>, never, Runner.Runner>;
|
|
35
28
|
export declare const tick: Effect.Effect<void, never, Runner.Runner>;
|
|
36
29
|
/**
|
|
37
30
|
* Hold the scene for `duration` of scene time (frames at the runner's
|
|
@@ -52,7 +45,7 @@ export interface FrameEntry<Entity extends Entity.AnyEntity> {
|
|
|
52
45
|
export type EntriesFromEntities<Entities> = Entities extends Entity.AnyEntity ? {
|
|
53
46
|
[K in Entities as K["name"]]: FrameEntry<K>;
|
|
54
47
|
}[Entities["name"]] : never;
|
|
55
|
-
export interface Frame<Entities extends Entity.AnyEntity> {
|
|
48
|
+
export interface Frame<Entities extends Entity.AnyEntity = Entity.AnyEntity> {
|
|
56
49
|
instances: Record<string, EntriesFromEntities<Entities>>;
|
|
57
50
|
/** id of the root group (conventionally "root"); never rendered itself */
|
|
58
51
|
root: string;
|
|
@@ -60,25 +53,21 @@ export interface Frame<Entities extends Entity.AnyEntity> {
|
|
|
60
53
|
frameRate: number;
|
|
61
54
|
width: number;
|
|
62
55
|
height: number;
|
|
63
|
-
backgroundColor:
|
|
64
|
-
/** the active camera's view;
|
|
65
|
-
camera:
|
|
66
|
-
x: number;
|
|
67
|
-
y: number;
|
|
68
|
-
zoom: number;
|
|
69
|
-
};
|
|
56
|
+
backgroundColor: Color.Color;
|
|
57
|
+
/** the active camera's view; Camera.IDENTITY when unused */
|
|
58
|
+
camera: Camera.CameraState;
|
|
70
59
|
}
|
|
71
|
-
export declare const step: <E, R
|
|
72
|
-
interface RunningScene<E, R
|
|
60
|
+
export declare const step: <E, R>(runningScene: RunningScene<E, R>) => Effect.Effect<Frame<Entity.AnyEntity> | null, E, never>;
|
|
61
|
+
export interface RunningScene<E, R> {
|
|
73
62
|
readonly runner: Runner.Runner["Service"];
|
|
74
|
-
readonly scene: Scene<E, R
|
|
63
|
+
readonly scene: Scene<E, R>;
|
|
75
64
|
readonly fiber: Fiber.Fiber<void, E>;
|
|
76
65
|
readonly done: boolean;
|
|
77
66
|
/** frames delivered so far — mutated by `step` for the maxFrames cap */
|
|
78
67
|
framesDelivered: number;
|
|
79
68
|
}
|
|
80
|
-
export declare const run: <E, R
|
|
81
|
-
export declare const stream: <E, R
|
|
69
|
+
export declare const run: <E, R>(scene: Scene<E, R>, settings?: Partial<Runner.Settings>) => Effect.Effect<RunningScene<E, R>, never, Scope.Scope | Exclude<Exclude<Exclude<Exclude<R, Scope.Scope>, never>, Phaser.Phaser>, Runner.Runner>>;
|
|
70
|
+
export declare const stream: <E = never, R = never>(scene: Scene<E, R>, settings?: Partial<Runner.Settings>) => Stream.Stream<Frame<Entity.AnyEntity>, Exclude<E, Cause.Done<any>>, Exclude<Exclude<Exclude<Exclude<Exclude<R, Scope.Scope>, never>, Phaser.Phaser>, Runner.Runner>, Scope.Scope>>;
|
|
82
71
|
type Updater<Data> = Data | ((data: Data) => Data);
|
|
83
72
|
export declare const data: <Name extends string, Data extends Schema.Top>(instance: Instance.Instance<Name, Data>) => Effect.Effect<Data["Type"] & ({} | undefined), never, Runner.Runner>;
|
|
84
73
|
export declare const update: <Name extends string, Data extends Schema.Top>(instance: Instance.Instance<Name, Data>, props: Updater<Data["Type"]>) => Effect.Effect<void | false, never, Runner.Runner>;
|
|
@@ -95,41 +84,81 @@ export declare const settings: () => Effect.Effect<{
|
|
|
95
84
|
frameRate: number;
|
|
96
85
|
width: number;
|
|
97
86
|
height: number;
|
|
98
|
-
backgroundColor:
|
|
87
|
+
backgroundColor: Color.Color;
|
|
99
88
|
seed: Runner.Seed;
|
|
100
89
|
maxFrames: number;
|
|
101
90
|
}, never, Runner.Runner>;
|
|
102
91
|
/**
|
|
103
92
|
* The active camera instance — an ordinary instance carrying `~position`
|
|
104
|
-
* (x/y
|
|
105
|
-
* `
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
93
|
+
* (world x/y/z), Euler orientation (`rotX`/`rotY`/`rotZ`), and
|
|
94
|
+
* `focalLength` (perspective strength — see Projection.defaultFocalLength),
|
|
95
|
+
* so the existing animators drive it: `Scene.make(function* () { const cam
|
|
96
|
+
* = yield* Scene.camera; yield* cam.pipe(Motion.moveTo({ z: -400 })) })`.
|
|
97
|
+
* A default resting camera is always present (width-relative 50mm-equivalent
|
|
98
|
+
* focal length, projecting z=0 content to plain-2D placement); animate it
|
|
99
|
+
* directly, or `Scene.setCamera` to swap in another instance. The camera is
|
|
100
|
+
* never drawn.
|
|
109
101
|
*/
|
|
110
102
|
export declare const camera: Effect.Effect<Instance.Instance<"Camera", Schema.Struct<{
|
|
111
103
|
x: Schema.withConstructorDefault<Schema.Number>;
|
|
112
104
|
y: Schema.withConstructorDefault<Schema.Number>;
|
|
113
|
-
|
|
105
|
+
z: Schema.withConstructorDefault<Schema.Number>;
|
|
106
|
+
rotX: Schema.withConstructorDefault<Schema.Number>;
|
|
107
|
+
rotY: Schema.withConstructorDefault<Schema.Number>;
|
|
108
|
+
rotZ: Schema.withConstructorDefault<Schema.Number>;
|
|
109
|
+
focalLength: Schema.withConstructorDefault<Schema.Number>;
|
|
110
|
+
focusDistance: Schema.withConstructorDefault<Schema.Number>;
|
|
111
|
+
aperture: Schema.withConstructorDefault<Schema.Number>;
|
|
112
|
+
poiX: Schema.optionalKey<Schema.Number>;
|
|
113
|
+
poiY: Schema.optionalKey<Schema.Number>;
|
|
114
|
+
poiZ: Schema.optionalKey<Schema.Number>;
|
|
114
115
|
}>, {
|
|
115
116
|
readonly "~position": {
|
|
116
|
-
get: (data:
|
|
117
|
-
x:
|
|
118
|
-
y:
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
get: (data: {
|
|
118
|
+
readonly x: number;
|
|
119
|
+
readonly y: number;
|
|
120
|
+
readonly z: number;
|
|
121
|
+
readonly rotX: number;
|
|
122
|
+
readonly rotY: number;
|
|
123
|
+
readonly rotZ: number;
|
|
124
|
+
readonly focalLength: number;
|
|
125
|
+
readonly focusDistance: number;
|
|
126
|
+
readonly aperture: number;
|
|
127
|
+
readonly poiX?: number;
|
|
128
|
+
readonly poiY?: number;
|
|
129
|
+
readonly poiZ?: number;
|
|
130
|
+
}) => {
|
|
121
131
|
x: number;
|
|
122
132
|
y: number;
|
|
133
|
+
z: number;
|
|
134
|
+
};
|
|
135
|
+
set: (data: {
|
|
136
|
+
readonly x: number;
|
|
137
|
+
readonly y: number;
|
|
138
|
+
readonly z: number;
|
|
139
|
+
readonly rotX: number;
|
|
140
|
+
readonly rotY: number;
|
|
141
|
+
readonly rotZ: number;
|
|
142
|
+
readonly focalLength: number;
|
|
143
|
+
readonly focusDistance: number;
|
|
144
|
+
readonly aperture: number;
|
|
145
|
+
readonly poiX?: number;
|
|
146
|
+
readonly poiY?: number;
|
|
147
|
+
readonly poiZ?: number;
|
|
148
|
+
}, value: Entity.Position) => {
|
|
149
|
+
readonly x: number;
|
|
150
|
+
readonly y: number;
|
|
151
|
+
readonly z: number;
|
|
152
|
+
readonly rotX: number;
|
|
153
|
+
readonly rotY: number;
|
|
154
|
+
readonly rotZ: number;
|
|
155
|
+
readonly focalLength: number;
|
|
156
|
+
readonly focusDistance: number;
|
|
157
|
+
readonly aperture: number;
|
|
158
|
+
readonly poiX?: number;
|
|
159
|
+
readonly poiY?: number;
|
|
160
|
+
readonly poiZ?: number;
|
|
123
161
|
};
|
|
124
|
-
set: (data: Schema.Struct.ReadonlySide<{
|
|
125
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
126
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
127
|
-
zoom: Schema.withConstructorDefault<Schema.Number>;
|
|
128
|
-
}, "Type">, value: Entity.Position) => Schema.Struct.ReadonlySide<{
|
|
129
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
130
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
131
|
-
zoom: Schema.withConstructorDefault<Schema.Number>;
|
|
132
|
-
}, "Type">;
|
|
133
162
|
};
|
|
134
163
|
}>, never, Runner.Runner>;
|
|
135
164
|
/** Swap the active camera to `instance`; its live data becomes the view. */
|
|
@@ -142,7 +171,7 @@ export declare const setCamera: (instance: Instance.Instance) => Effect.Effect<v
|
|
|
142
171
|
* the rest of the scene stays live while you wait. `fiber` is the
|
|
143
172
|
* branch's physical execution — interrupt it to bound a tail.
|
|
144
173
|
*/
|
|
145
|
-
export interface BranchHandle<A = unknown, E =
|
|
174
|
+
export interface BranchHandle<A = unknown, E = never> {
|
|
146
175
|
readonly finished: Effect.Effect<void, never, Runner.Runner>;
|
|
147
176
|
readonly fiber: Fiber.Fiber<A, E>;
|
|
148
177
|
}
|
|
@@ -178,7 +207,7 @@ export declare const repeat: <A, E, R, Output, ScheduleE, ScheduleR>(effect: Eff
|
|
|
178
207
|
* instead. Forks are supervised by the fiber that spawned them: a fork
|
|
179
208
|
* made inside another fork is interrupted when its spawner completes.
|
|
180
209
|
*/
|
|
181
|
-
export declare const fork: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<BranchHandle<A, E>, never, Runner.Runner | Exclude<Exclude<R, never>, Phaser.Phaser>>;
|
|
210
|
+
export declare const fork: <A, E = never, R = never>(effect: Effect.Effect<A, E, R>) => Effect.Effect<BranchHandle<A, E>, never, Runner.Runner | Exclude<Exclude<R, never>, Phaser.Phaser>>;
|
|
182
211
|
/**
|
|
183
212
|
* Like {@link fork}, but the fiber is INTERRUPTED at scene end instead
|
|
184
213
|
* of awaited — for indefinite work (`Scene.repeat(…, Schedule.forever)`)
|
|
@@ -186,7 +215,7 @@ export declare const fork: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.E
|
|
|
186
215
|
* alive. "Scene end" includes the fork drain: backgrounds keep animating
|
|
187
216
|
* while awaited forks finish, and are stopped after the last one.
|
|
188
217
|
*/
|
|
189
|
-
export declare const background: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<BranchHandle<A, E>, never, Runner.Runner | Exclude<Exclude<R, never>, Phaser.Phaser>>;
|
|
218
|
+
export declare const background: <A, E = never, R = never>(effect: Effect.Effect<A, E, R>) => Effect.Effect<BranchHandle<A, E>, never, Runner.Runner | Exclude<Exclude<R, never>, Phaser.Phaser>>;
|
|
190
219
|
export interface PlayOptions {
|
|
191
220
|
/** group to mount the scene's instances under (default: the root) */
|
|
192
221
|
readonly parent?: Runner.GroupInstance;
|
|
@@ -202,14 +231,14 @@ export interface PlayOptions {
|
|
|
202
231
|
* like a fork — `yield* handle.finished` for sequential nesting, or
|
|
203
232
|
* don't await for concurrent scenes.
|
|
204
233
|
*/
|
|
205
|
-
export declare const play: <E, R
|
|
234
|
+
export declare const play: <E, R>(scene: Scene<E, R>, options?: PlayOptions) => Effect.Effect<BranchHandle<void, E>, never, Runner.Runner | Exclude<R, Scope.Scope>>;
|
|
206
235
|
/**
|
|
207
236
|
* Run effects in lockstep parallel, sharing frame phases — the public
|
|
208
237
|
* counterpart to the low-level `Phaser.all`. Takes no schedule: pacing a
|
|
209
238
|
* list sequentially belongs to {@link chain}, overlapping staggered
|
|
210
239
|
* starts to {@link stagger}.
|
|
211
240
|
*/
|
|
212
|
-
export declare const all:
|
|
241
|
+
export declare const all: <Eff extends Effect.Effect<any, any, any>>(effects: Iterable<Eff>) => Effect.Effect<void, Eff extends Effect.Effect<any, infer E, any> ? E : never, Runner.Runner | Exclude<Eff extends Effect.Effect<any, any, infer R> ? R : never, Phaser.Phaser>>;
|
|
213
242
|
/**
|
|
214
243
|
* Run items one at a time, in order — items NEVER overlap, mirroring
|
|
215
244
|
* Effect's guarantee for scheduled effects. The first item runs
|
|
@@ -237,5 +266,5 @@ export declare const chain: <Eff extends Effect.Effect<any, any, any>, ScheduleE
|
|
|
237
266
|
*/
|
|
238
267
|
export declare const stagger: <Eff extends Effect.Effect<any, any, any>, ScheduleE = never, ScheduleR = never>(effects: Iterable<Eff>, schedule: Schedule.Schedule<unknown, void, ScheduleE, ScheduleR>) => Effect.Effect<{
|
|
239
268
|
released: number;
|
|
240
|
-
}, (Eff extends Effect.Effect<any, infer E, any> ? E : never) | ScheduleE, (Eff extends Effect.Effect<any, any, infer R> ? R : never) |
|
|
269
|
+
}, (Eff extends Effect.Effect<any, infer E, any> ? E : never) | ScheduleE, (Eff extends Effect.Effect<any, any, infer R> ? R : never) | Runner.Runner | ScheduleR>;
|
|
241
270
|
export {};
|
package/dist/Scene.js
CHANGED
|
@@ -5,9 +5,9 @@ import * as Exit from "effect/Exit";
|
|
|
5
5
|
import * as Fiber from "effect/Fiber";
|
|
6
6
|
import * as Random from "effect/Random";
|
|
7
7
|
import * as Stream from "effect/Stream";
|
|
8
|
-
import * as Phaser from "./Phaser";
|
|
9
|
-
import * as Runner from "./Runner";
|
|
10
|
-
import * as Time from "./Time";
|
|
8
|
+
import * as Phaser from "./Phaser.js";
|
|
9
|
+
import * as Runner from "./Runner.js";
|
|
10
|
+
import * as Time from "./Time.js";
|
|
11
11
|
export const TypeId = "~motion/Scene";
|
|
12
12
|
export const make = (f) => {
|
|
13
13
|
return makeScene(Effect.scoped(Effect.gen(f)), Context.empty());
|
|
@@ -126,13 +126,13 @@ export const run = (scene, settings = {}) => Effect.gen(function* () {
|
|
|
126
126
|
// interrupt can cut this fiber before failCause runs,
|
|
127
127
|
// and the root branch records like any other branch
|
|
128
128
|
onFailure: (cause) => Effect.sync(() => runner.recordFailure(cause)).pipe(Effect.andThen(releaseRoot), Effect.andThen(Fiber.interruptAll([...runner.forks, ...runner.backgrounds].map((b) => b.fiber))), Effect.andThen(Effect.failCause(cause))),
|
|
129
|
-
}))).pipe(Effect.ensuring(releaseRoot), Effect.provideService(
|
|
129
|
+
}))).pipe(Effect.ensuring(releaseRoot), Effect.provideService(currentBranch(), rootBranch),
|
|
130
130
|
// success, failure, or interrupt: the scene is over either way
|
|
131
131
|
Effect.ensuring(Effect.sync(() => {
|
|
132
132
|
done = true;
|
|
133
133
|
})), Effect.provide(Layer.succeed(Phaser.Phaser, runner.phaser)), Effect.provide(Layer.succeed(Runner.Runner, runner)),
|
|
134
134
|
// seeded pseudo-randomness, scoped to the scene fiber
|
|
135
|
-
Random.withSeed(runner.settings.seed), Effect.
|
|
135
|
+
Random.withSeed(runner.settings.seed), Effect.forkScoped);
|
|
136
136
|
}));
|
|
137
137
|
const runningScene = {
|
|
138
138
|
runner,
|
|
@@ -191,11 +191,14 @@ export const settings = Effect.fnUntraced(function* () {
|
|
|
191
191
|
});
|
|
192
192
|
/**
|
|
193
193
|
* The active camera instance — an ordinary instance carrying `~position`
|
|
194
|
-
* (x/y
|
|
195
|
-
* `
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
194
|
+
* (world x/y/z), Euler orientation (`rotX`/`rotY`/`rotZ`), and
|
|
195
|
+
* `focalLength` (perspective strength — see Projection.defaultFocalLength),
|
|
196
|
+
* so the existing animators drive it: `Scene.make(function* () { const cam
|
|
197
|
+
* = yield* Scene.camera; yield* cam.pipe(Motion.moveTo({ z: -400 })) })`.
|
|
198
|
+
* A default resting camera is always present (width-relative 50mm-equivalent
|
|
199
|
+
* focal length, projecting z=0 content to plain-2D placement); animate it
|
|
200
|
+
* directly, or `Scene.setCamera` to swap in another instance. The camera is
|
|
201
|
+
* never drawn.
|
|
199
202
|
*/
|
|
200
203
|
export const camera = Effect.gen(function* () {
|
|
201
204
|
const runner = yield* Runner.Runner;
|
|
@@ -207,7 +210,9 @@ export const setCamera = (instance) => Effect.gen(function* () {
|
|
|
207
210
|
runner.setCamera(instance);
|
|
208
211
|
});
|
|
209
212
|
/** the innermost enclosing branch; null = outside any running scene */
|
|
210
|
-
const
|
|
213
|
+
const currentBranch = () => Context.Reference("motion/Scene/CurrentBranch", {
|
|
214
|
+
defaultValue: () => null,
|
|
215
|
+
});
|
|
211
216
|
const makeBranch = (runner, kind) => {
|
|
212
217
|
const latch = Latch.makeUnsafe();
|
|
213
218
|
let finished = false;
|
|
@@ -247,7 +252,7 @@ const makeBranch = (runner, kind) => {
|
|
|
247
252
|
* reported — by then nothing is listening.
|
|
248
253
|
*/
|
|
249
254
|
export const finish = Effect.gen(function* () {
|
|
250
|
-
const branch = yield*
|
|
255
|
+
const branch = yield* currentBranch();
|
|
251
256
|
if (branch === null) {
|
|
252
257
|
return yield* Effect.die(new Error("Scene.finish called outside a running scene"));
|
|
253
258
|
}
|
|
@@ -270,7 +275,7 @@ const forkBranch = (runner, effect, kind) => Effect.gen(function* () {
|
|
|
270
275
|
runner.recordFailure(exit.cause);
|
|
271
276
|
}
|
|
272
277
|
branch.finishUnsafe();
|
|
273
|
-
})), Effect.provideService(
|
|
278
|
+
})), Effect.provideService(currentBranch(), branch)));
|
|
274
279
|
branch.entry.fiber = fiber;
|
|
275
280
|
if (kind === "fork" && !branch.isFinished()) {
|
|
276
281
|
runner.forks.add(branch.entry);
|
|
@@ -373,7 +378,11 @@ export const play = (scene, options) => Effect.gen(function* () {
|
|
|
373
378
|
* list sequentially belongs to {@link chain}, overlapping staggered
|
|
374
379
|
* starts to {@link stagger}.
|
|
375
380
|
*/
|
|
376
|
-
export const all = (
|
|
381
|
+
export const all = Effect.fnUntraced(function* (effects) {
|
|
382
|
+
const runner = yield* Runner.Runner;
|
|
383
|
+
// runner.phaser
|
|
384
|
+
return yield* Phaser.all(effects).pipe(Effect.provideService(Phaser.Phaser, runner.phaser));
|
|
385
|
+
});
|
|
377
386
|
/**
|
|
378
387
|
* Run items one at a time, in order — items NEVER overlap, mirroring
|
|
379
388
|
* Effect's guarantee for scheduled effects. The first item runs
|
|
@@ -449,6 +458,6 @@ export const stagger = (effects, schedule) => Effect.gen(function* () {
|
|
|
449
458
|
// biome-ignore lint/style/noNonNullAssertion: same length as releaseFrames
|
|
450
459
|
yield* list[i];
|
|
451
460
|
}));
|
|
452
|
-
yield* Phaser.all(branches);
|
|
461
|
+
yield* Phaser.all(branches).pipe(Effect.provideService(Phaser.Phaser, runner.phaser));
|
|
453
462
|
return { released: releaseFrames.length };
|
|
454
463
|
});
|
package/dist/Shapes.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Circle } from "./shapes/Circle.js";
|
|
2
|
+
export { Ellipse } from "./shapes/Ellipse.js";
|
|
3
|
+
export * from "./shapes/Group.js";
|
|
4
|
+
export { Hud } from "./shapes/Hud.js";
|
|
5
|
+
export { Image } from "./shapes/Image.js";
|
|
6
|
+
export { Line } from "./shapes/Line.js";
|
|
7
|
+
export { Path } from "./shapes/Path.js";
|
|
8
|
+
export { Rect } from "./shapes/Rect.js";
|
|
9
|
+
export * as Shape2D from "./shapes/Shape2D.js";
|
|
10
|
+
export { Square } from "./shapes/Square.js";
|
|
11
|
+
export { Text } from "./shapes/Text.js";
|
package/dist/Shapes.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Circle } from "./shapes/Circle.js";
|
|
2
|
+
export { Ellipse } from "./shapes/Ellipse.js";
|
|
3
|
+
export * from "./shapes/Group.js";
|
|
4
|
+
export { Hud } from "./shapes/Hud.js";
|
|
5
|
+
export { Image } from "./shapes/Image.js";
|
|
6
|
+
export { Line } from "./shapes/Line.js";
|
|
7
|
+
export { Path } from "./shapes/Path.js";
|
|
8
|
+
export { Rect } from "./shapes/Rect.js";
|
|
9
|
+
export * as Shape2D from "./shapes/Shape2D.js";
|
|
10
|
+
export { Square } from "./shapes/Square.js";
|
|
11
|
+
export { Text } from "./shapes/Text.js";
|
package/dist/demo.d.ts
CHANGED
|
@@ -1,186 +1,3 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare const scene: Scene.Scene<unknown, import("./Runner").Runner | import("effect/Scope").Scope, Entity.Entity<"shapes/Group", Schema.Struct<{
|
|
5
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
6
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
7
|
-
opacity: Schema.withConstructorDefault<Schema.Number>;
|
|
8
|
-
transform: Schema.withConstructorDefault<Schema.Struct<{
|
|
9
|
-
readonly a: Schema.Number;
|
|
10
|
-
readonly b: Schema.Number;
|
|
11
|
-
readonly c: Schema.Number;
|
|
12
|
-
readonly d: Schema.Number;
|
|
13
|
-
readonly e: Schema.Number;
|
|
14
|
-
readonly f: Schema.Number;
|
|
15
|
-
}>>;
|
|
16
|
-
children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
|
|
17
|
-
}>, {
|
|
18
|
-
"~position": Entity.TraitLens<Schema.Struct.ReadonlySide<{
|
|
19
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
20
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
21
|
-
opacity: Schema.withConstructorDefault<Schema.Number>;
|
|
22
|
-
transform: Schema.withConstructorDefault<Schema.Struct<{
|
|
23
|
-
readonly a: Schema.Number;
|
|
24
|
-
readonly b: Schema.Number;
|
|
25
|
-
readonly c: Schema.Number;
|
|
26
|
-
readonly d: Schema.Number;
|
|
27
|
-
readonly e: Schema.Number;
|
|
28
|
-
readonly f: Schema.Number;
|
|
29
|
-
}>>;
|
|
30
|
-
children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
|
|
31
|
-
}, "Type">, Entity.Position>;
|
|
32
|
-
"~opacity": Entity.TraitLens<Schema.Struct.ReadonlySide<{
|
|
33
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
34
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
35
|
-
opacity: Schema.withConstructorDefault<Schema.Number>;
|
|
36
|
-
transform: Schema.withConstructorDefault<Schema.Struct<{
|
|
37
|
-
readonly a: Schema.Number;
|
|
38
|
-
readonly b: Schema.Number;
|
|
39
|
-
readonly c: Schema.Number;
|
|
40
|
-
readonly d: Schema.Number;
|
|
41
|
-
readonly e: Schema.Number;
|
|
42
|
-
readonly f: Schema.Number;
|
|
43
|
-
}>>;
|
|
44
|
-
children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
|
|
45
|
-
}, "Type">, number>;
|
|
46
|
-
}, Omit<{
|
|
47
|
-
readonly x?: number;
|
|
48
|
-
readonly y?: number;
|
|
49
|
-
readonly opacity?: number;
|
|
50
|
-
readonly transform?: Schema.Struct.ReadonlyMakeIn<{
|
|
51
|
-
readonly a: Schema.Number;
|
|
52
|
-
readonly b: Schema.Number;
|
|
53
|
-
readonly c: Schema.Number;
|
|
54
|
-
readonly d: Schema.Number;
|
|
55
|
-
readonly e: Schema.Number;
|
|
56
|
-
readonly f: Schema.Number;
|
|
57
|
-
}>;
|
|
58
|
-
readonly children?: readonly string[];
|
|
59
|
-
}, "transform"> & {
|
|
60
|
-
readonly transform?: readonly (Schema.Struct.ReadonlySide<{
|
|
61
|
-
readonly _tag: Schema.tag<"transform/matrix">;
|
|
62
|
-
readonly a: Schema.Number;
|
|
63
|
-
readonly b: Schema.Number;
|
|
64
|
-
readonly c: Schema.Number;
|
|
65
|
-
readonly d: Schema.Number;
|
|
66
|
-
readonly e: Schema.Number;
|
|
67
|
-
readonly f: Schema.Number;
|
|
68
|
-
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
69
|
-
readonly _tag: Schema.tag<"transform/scale">;
|
|
70
|
-
readonly x: Schema.Number;
|
|
71
|
-
readonly y: Schema.Number;
|
|
72
|
-
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
73
|
-
readonly _tag: Schema.tag<"transform/translate">;
|
|
74
|
-
readonly x: Schema.Number;
|
|
75
|
-
readonly y: Schema.Number;
|
|
76
|
-
}, "Type">)[];
|
|
77
|
-
}>>;
|
|
78
|
-
export declare const staggered: Scene.Scene<unknown, import("./Phaser").Phaser | import("./Runner").Runner | import("effect/Scope").Scope, Entity.Entity<"shapes/Circle", Schema.Struct<{
|
|
79
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
80
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
81
|
-
opacity: Schema.withConstructorDefault<Schema.Number>;
|
|
82
|
-
fill: Schema.withConstructorDefault<Schema.String>;
|
|
83
|
-
stroke: Schema.optionalKey<Schema.String>;
|
|
84
|
-
strokeWidth: Schema.optionalKey<Schema.Number>;
|
|
85
|
-
radius: Schema.withConstructorDefault<Schema.Number>;
|
|
86
|
-
}>, {
|
|
87
|
-
readonly "~position": Entity.TraitLens<{
|
|
88
|
-
readonly x: number;
|
|
89
|
-
readonly y: number;
|
|
90
|
-
readonly opacity: number;
|
|
91
|
-
readonly fill: string;
|
|
92
|
-
readonly stroke?: string;
|
|
93
|
-
readonly strokeWidth?: number;
|
|
94
|
-
readonly radius: number;
|
|
95
|
-
}, Entity.Position>;
|
|
96
|
-
readonly "~opacity": Entity.TraitLens<{
|
|
97
|
-
readonly x: number;
|
|
98
|
-
readonly y: number;
|
|
99
|
-
readonly opacity: number;
|
|
100
|
-
readonly fill: string;
|
|
101
|
-
readonly stroke?: string;
|
|
102
|
-
readonly strokeWidth?: number;
|
|
103
|
-
readonly radius: number;
|
|
104
|
-
}, number>;
|
|
105
|
-
}, {
|
|
106
|
-
readonly x?: number;
|
|
107
|
-
readonly y?: number;
|
|
108
|
-
readonly opacity?: number;
|
|
109
|
-
readonly fill?: string;
|
|
110
|
-
readonly stroke?: string;
|
|
111
|
-
readonly strokeWidth?: number;
|
|
112
|
-
readonly radius?: number;
|
|
113
|
-
}> | Entity.Entity<"shapes/Group", Schema.Struct<{
|
|
114
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
115
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
116
|
-
opacity: Schema.withConstructorDefault<Schema.Number>;
|
|
117
|
-
transform: Schema.withConstructorDefault<Schema.Struct<{
|
|
118
|
-
readonly a: Schema.Number;
|
|
119
|
-
readonly b: Schema.Number;
|
|
120
|
-
readonly c: Schema.Number;
|
|
121
|
-
readonly d: Schema.Number;
|
|
122
|
-
readonly e: Schema.Number;
|
|
123
|
-
readonly f: Schema.Number;
|
|
124
|
-
}>>;
|
|
125
|
-
children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
|
|
126
|
-
}>, {
|
|
127
|
-
"~position": Entity.TraitLens<Schema.Struct.ReadonlySide<{
|
|
128
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
129
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
130
|
-
opacity: Schema.withConstructorDefault<Schema.Number>;
|
|
131
|
-
transform: Schema.withConstructorDefault<Schema.Struct<{
|
|
132
|
-
readonly a: Schema.Number;
|
|
133
|
-
readonly b: Schema.Number;
|
|
134
|
-
readonly c: Schema.Number;
|
|
135
|
-
readonly d: Schema.Number;
|
|
136
|
-
readonly e: Schema.Number;
|
|
137
|
-
readonly f: Schema.Number;
|
|
138
|
-
}>>;
|
|
139
|
-
children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
|
|
140
|
-
}, "Type">, Entity.Position>;
|
|
141
|
-
"~opacity": Entity.TraitLens<Schema.Struct.ReadonlySide<{
|
|
142
|
-
x: Schema.withConstructorDefault<Schema.Number>;
|
|
143
|
-
y: Schema.withConstructorDefault<Schema.Number>;
|
|
144
|
-
opacity: Schema.withConstructorDefault<Schema.Number>;
|
|
145
|
-
transform: Schema.withConstructorDefault<Schema.Struct<{
|
|
146
|
-
readonly a: Schema.Number;
|
|
147
|
-
readonly b: Schema.Number;
|
|
148
|
-
readonly c: Schema.Number;
|
|
149
|
-
readonly d: Schema.Number;
|
|
150
|
-
readonly e: Schema.Number;
|
|
151
|
-
readonly f: Schema.Number;
|
|
152
|
-
}>>;
|
|
153
|
-
children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
|
|
154
|
-
}, "Type">, number>;
|
|
155
|
-
}, Omit<{
|
|
156
|
-
readonly x?: number;
|
|
157
|
-
readonly y?: number;
|
|
158
|
-
readonly opacity?: number;
|
|
159
|
-
readonly transform?: Schema.Struct.ReadonlyMakeIn<{
|
|
160
|
-
readonly a: Schema.Number;
|
|
161
|
-
readonly b: Schema.Number;
|
|
162
|
-
readonly c: Schema.Number;
|
|
163
|
-
readonly d: Schema.Number;
|
|
164
|
-
readonly e: Schema.Number;
|
|
165
|
-
readonly f: Schema.Number;
|
|
166
|
-
}>;
|
|
167
|
-
readonly children?: readonly string[];
|
|
168
|
-
}, "transform"> & {
|
|
169
|
-
readonly transform?: readonly (Schema.Struct.ReadonlySide<{
|
|
170
|
-
readonly _tag: Schema.tag<"transform/matrix">;
|
|
171
|
-
readonly a: Schema.Number;
|
|
172
|
-
readonly b: Schema.Number;
|
|
173
|
-
readonly c: Schema.Number;
|
|
174
|
-
readonly d: Schema.Number;
|
|
175
|
-
readonly e: Schema.Number;
|
|
176
|
-
readonly f: Schema.Number;
|
|
177
|
-
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
178
|
-
readonly _tag: Schema.tag<"transform/scale">;
|
|
179
|
-
readonly x: Schema.Number;
|
|
180
|
-
readonly y: Schema.Number;
|
|
181
|
-
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
182
|
-
readonly _tag: Schema.tag<"transform/translate">;
|
|
183
|
-
readonly x: Schema.Number;
|
|
184
|
-
readonly y: Schema.Number;
|
|
185
|
-
}, "Type">)[];
|
|
186
|
-
}>>;
|
|
1
|
+
import * as Scene from "./Scene.js";
|
|
2
|
+
export declare const scene: Scene.Scene<never, import("./Runner.js").Runner>;
|
|
3
|
+
export declare const staggered: Scene.Scene<never, import("./Runner.js").Runner>;
|
package/dist/demo.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { NodeServices } from "@effect/platform-node";
|
|
2
|
+
import { Session } from "@effect-motion/thorvg";
|
|
3
|
+
import { EngineNode } from "@effect-motion/thorvg/node";
|
|
1
4
|
import { Effect, Layer, Schedule, Stream } from "effect";
|
|
2
|
-
import
|
|
3
|
-
import * as Motion from "./Motion";
|
|
4
|
-
import * as Physics from "./Physics";
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
5
|
+
import * as Color from "./Color.js";
|
|
6
|
+
import * as Motion from "./Motion.js";
|
|
7
|
+
import * as Physics from "./Physics.js";
|
|
8
|
+
import * as PngExporter from "./PngExporter.js";
|
|
9
|
+
import * as Renderer from "./Renderer.js";
|
|
10
|
+
import * as Scene from "./Scene.js";
|
|
11
|
+
import * as Shapes from "./Shapes.js";
|
|
7
12
|
// children live in the group's local coordinates: one motion moves them all
|
|
8
13
|
export const scene = Scene.make(function* () {
|
|
9
14
|
const duo = yield* Scene.instantiate(Shapes.Group, {
|
|
@@ -14,35 +19,19 @@ export const scene = Scene.make(function* () {
|
|
|
14
19
|
x: 0,
|
|
15
20
|
y: 0,
|
|
16
21
|
radius: 14,
|
|
17
|
-
fill: "#e53170",
|
|
22
|
+
fill: Color.hex("#e53170"),
|
|
18
23
|
}),
|
|
19
24
|
Scene.instantiate(Shapes.Square, {
|
|
20
25
|
x: 20,
|
|
21
26
|
y: -16,
|
|
22
27
|
size: 28,
|
|
23
|
-
fill: "#a786df",
|
|
28
|
+
fill: Color.hex("#a786df"),
|
|
24
29
|
}),
|
|
25
30
|
],
|
|
26
31
|
});
|
|
27
|
-
const moveA = Motion.moveTo({ x: 380 }, "1.5 seconds", "easeInOutCubic");
|
|
28
|
-
const moveB = Motion.moveTo({ x: 70 }, "1.5 seconds", "easeInOutCubic");
|
|
29
32
|
yield* Motion.wait("1.5 seconds");
|
|
30
33
|
yield* duo.pipe(Motion.moveTo({ x: 380 }, "1.5 seconds", "easeInOutCubic"), Motion.moveTo({ x: 70 }, "1.5 seconds", "easeInOutCubic"), Motion.wait("1.5 seconds"), Physics.springTo({ y: 80 }, "jump"), Motion.fadeTo(0.15, "1 second"));
|
|
31
34
|
});
|
|
32
|
-
// const program = Effect.gen(function* () {
|
|
33
|
-
// const renderer = yield* Svg.SvgRenderer.Context;
|
|
34
|
-
// const sceneResult = yield* Scene.stream(scene, {
|
|
35
|
-
// }).pipe(
|
|
36
|
-
// Stream.runCollect,
|
|
37
|
-
// Effect.provide(renderer)
|
|
38
|
-
// )
|
|
39
|
-
// console.log(sceneResult);
|
|
40
|
-
// // renderer.render(scene, {
|
|
41
|
-
// // width: 500,
|
|
42
|
-
// // height: 300,
|
|
43
|
-
// // });
|
|
44
|
-
// }).pipe(Effect.provide(shapesLayer));
|
|
45
|
-
// Effect.runPromise(program);
|
|
46
35
|
// schedule-driven composition: a background pulse loops for the scene's
|
|
47
36
|
// duration while three staggered dots define its actual length
|
|
48
37
|
export const staggered = Scene.make(function* () {
|
|
@@ -53,7 +42,7 @@ export const staggered = Scene.make(function* () {
|
|
|
53
42
|
x,
|
|
54
43
|
y: 0,
|
|
55
44
|
radius: 10,
|
|
56
|
-
fill: "#e53170",
|
|
45
|
+
fill: Color.hex("#e53170"),
|
|
57
46
|
});
|
|
58
47
|
// reparent the freshly-born dot from root into the stage group
|
|
59
48
|
yield* Scene.appendChild(stage, circle);
|
|
@@ -61,16 +50,16 @@ export const staggered = Scene.make(function* () {
|
|
|
61
50
|
});
|
|
62
51
|
yield* Scene.stagger([dot(0), dot(25), dot(50)], Schedule.spaced("250 millis"));
|
|
63
52
|
});
|
|
53
|
+
// render the middle frame of the duo scene to a PNG through the single ThorVG
|
|
54
|
+
// renderer (Node adapter) — the end-to-end path: Scene.stream → renderToPng.
|
|
64
55
|
const movie = Effect.gen(function* () {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// }
|
|
72
|
-
const frames = yield* Scene.stream(staggered).pipe(Stream.runCollect);
|
|
73
|
-
console.log(`staggered scene: ${[...frames].length} frames`);
|
|
56
|
+
const frames = yield* Scene.stream(scene, { width: 500, height: 300 }).pipe(Stream.runCollect);
|
|
57
|
+
const list = [...frames];
|
|
58
|
+
const mid = list[Math.floor(list.length / 2)];
|
|
59
|
+
const framebuffer = yield* Renderer.render(mid);
|
|
60
|
+
const _png = yield* PngExporter.toBuffer(framebuffer);
|
|
61
|
+
yield* PngExporter.toFile(framebuffer, "output.png");
|
|
74
62
|
});
|
|
75
|
-
|
|
76
|
-
|
|
63
|
+
Effect.runPromise(movie.pipe(Effect.scoped, Effect.provide(Layer.provideMerge(
|
|
64
|
+
// a demo scene with declared assets would add fonts/images maps here
|
|
65
|
+
Session.layer({ width: 500, height: 300 }), EngineNode.layer("sw"))), Effect.provide(NodeServices.layer)));
|