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.
Files changed (103) hide show
  1. package/dist/Camera.d.ts +50 -28
  2. package/dist/Camera.js +71 -19
  3. package/dist/CameraHelpers.d.ts +70 -0
  4. package/dist/CameraHelpers.js +239 -0
  5. package/dist/CanvasExporter.d.ts +12 -0
  6. package/dist/CanvasExporter.js +40 -0
  7. package/dist/Color.d.ts +428 -0
  8. package/dist/Color.js +535 -0
  9. package/dist/EffectMotionError.d.ts +10 -0
  10. package/dist/EffectMotionError.js +6 -0
  11. package/dist/Entity.d.ts +9 -8
  12. package/dist/Entity.js +1 -4
  13. package/dist/Fonts.d.ts +10 -0
  14. package/dist/Fonts.js +16 -0
  15. package/dist/Images.d.ts +33 -0
  16. package/dist/Images.js +24 -0
  17. package/dist/Instance.d.ts +4 -4
  18. package/dist/Motion.d.ts +24 -7
  19. package/dist/Motion.js +54 -9
  20. package/dist/Phaser.d.ts +1 -1
  21. package/dist/Phaser.js +13 -9
  22. package/dist/Physics.d.ts +3 -3
  23. package/dist/Physics.js +4 -4
  24. package/dist/PngExporter.d.ts +6 -0
  25. package/dist/PngExporter.js +85 -0
  26. package/dist/Projection.d.ts +225 -0
  27. package/dist/Projection.js +473 -0
  28. package/dist/Renderer.d.ts +102 -53
  29. package/dist/Renderer.js +369 -78
  30. package/dist/Runner.d.ts +126 -42
  31. package/dist/Runner.js +42 -17
  32. package/dist/Scene.d.ts +88 -59
  33. package/dist/Scene.js +24 -15
  34. package/dist/Shapes.d.ts +11 -0
  35. package/dist/Shapes.js +11 -0
  36. package/dist/demo.d.ts +3 -186
  37. package/dist/demo.js +24 -35
  38. package/dist/index.d.ts +14 -13
  39. package/dist/index.js +14 -13
  40. package/dist/particles/Particle.d.ts +4 -3
  41. package/dist/particles/ParticleField.d.ts +11 -48
  42. package/dist/particles/ParticleField.js +5 -4
  43. package/dist/particles/constructors.d.ts +8 -7
  44. package/dist/particles/constructors.js +2 -2
  45. package/dist/particles/index.d.ts +5 -6
  46. package/dist/particles/index.js +5 -6
  47. package/dist/particles/overLife.d.ts +1 -1
  48. package/dist/particles/overLife.js +1 -1
  49. package/dist/particles/simulate.d.ts +2 -2
  50. package/dist/particles/simulate.js +6 -6
  51. package/dist/particles/step.d.ts +2 -2
  52. package/dist/particles/step.js +5 -3
  53. package/dist/render/dof.d.ts +27 -0
  54. package/dist/render/dof.js +37 -0
  55. package/dist/render/paint.d.ts +30 -0
  56. package/dist/render/paint.js +36 -0
  57. package/dist/render/shapes.d.ts +42 -0
  58. package/dist/render/shapes.js +310 -0
  59. package/dist/shapes/Circle.d.ts +10 -15
  60. package/dist/shapes/Circle.js +2 -2
  61. package/dist/shapes/Ellipse.d.ts +10 -16
  62. package/dist/shapes/Ellipse.js +2 -2
  63. package/dist/shapes/Group.d.ts +5 -39
  64. package/dist/shapes/Group.js +4 -4
  65. package/dist/shapes/Hud.d.ts +38 -0
  66. package/dist/shapes/Hud.js +35 -0
  67. package/dist/shapes/Image.d.ts +45 -0
  68. package/dist/shapes/Image.js +28 -0
  69. package/dist/shapes/Line.d.ts +12 -12
  70. package/dist/shapes/Line.js +11 -6
  71. package/dist/shapes/Path.d.ts +87 -18
  72. package/dist/shapes/Path.js +25 -6
  73. package/dist/shapes/Rect.d.ts +33 -23
  74. package/dist/shapes/Rect.js +14 -2
  75. package/dist/shapes/Shape2D.d.ts +13 -4
  76. package/dist/shapes/Shape2D.js +16 -5
  77. package/dist/shapes/Shapes.d.ts +11 -0
  78. package/dist/shapes/Shapes.js +11 -0
  79. package/dist/shapes/Square.d.ts +10 -15
  80. package/dist/shapes/Square.js +2 -2
  81. package/dist/shapes/Text.d.ts +10 -19
  82. package/dist/shapes/Text.js +2 -2
  83. package/package.json +14 -4
  84. package/dist/particles/render.d.ts +0 -13
  85. package/dist/particles/render.js +0 -33
  86. package/dist/shapes/Layer.d.ts +0 -9
  87. package/dist/shapes/Layer.js +0 -23
  88. package/dist/shapes/index.d.ts +0 -10
  89. package/dist/shapes/index.js +0 -10
  90. package/dist/svg/SvgDomRenderer.d.ts +0 -28
  91. package/dist/svg/SvgDomRenderer.js +0 -50
  92. package/dist/svg/SvgNode.d.ts +0 -13
  93. package/dist/svg/SvgNode.js +0 -18
  94. package/dist/svg/SvgRenderer.d.ts +0 -22
  95. package/dist/svg/SvgRenderer.js +0 -20
  96. package/dist/svg/camera.d.ts +0 -21
  97. package/dist/svg/camera.js +0 -43
  98. package/dist/svg/index.d.ts +0 -6
  99. package/dist/svg/index.js +0 -6
  100. package/dist/svg/layers.d.ts +0 -18
  101. package/dist/svg/layers.js +0 -13
  102. package/dist/svg/shapes.d.ts +0 -1089
  103. package/dist/svg/shapes.js +0 -119
package/dist/Runner.d.ts CHANGED
@@ -4,10 +4,11 @@ import * as Context from "effect/Context";
4
4
  import * as Effect from "effect/Effect";
5
5
  import type * as Fiber from "effect/Fiber";
6
6
  import type * as Schema from "effect/Schema";
7
- import { type CameraState } from "./Camera";
8
- import type * as Entity from "./Entity";
9
- import * as Instance from "./Instance";
10
- import { Group } from "./shapes/Group";
7
+ import { type CameraState } from "./Camera.js";
8
+ import * as Color from "./Color.js";
9
+ import type * as Entity from "./Entity.js";
10
+ import * as Instance from "./Instance.js";
11
+ import { Group } from "./shapes/Group.js";
11
12
  export declare const TypeId: "~motion/SceneRunner";
12
13
  /** conventional id of the implicit root group every instance attaches to */
13
14
  export declare const ROOT_ID = "root";
@@ -20,7 +21,7 @@ export type Settings = {
20
21
  width: number;
21
22
  height: number;
22
23
  /** canvas background — carried on every frame so renderers can paint it (default a near-black, not pure #000) */
23
- backgroundColor: string;
24
+ backgroundColor: Color.Color;
24
25
  /**
25
26
  * seeds the scene's pseudo-random service (effect's Random via
26
27
  * withSeed); the fixed default keeps default-constructed scenes
@@ -43,7 +44,7 @@ export type GroupInstance = Instance.Of<typeof Group>;
43
44
  * not-yet-yielded `instantiate` — yielded internally so JSX children need
44
45
  * no `yield*`). Normalized to a stored child id in list order.
45
46
  */
46
- export type Child = string | Instance.Instance | Effect.Effect<Instance.Instance, unknown, unknown>;
47
+ export type Child = string | Instance.Instance | Effect.Effect<Instance.Instance, never, Runner>;
47
48
  /**
48
49
  * Builtin, engine-owned instance properties — namespaced with `$` and
49
50
  * held BESIDE entity data, never in the entity schema. Every entity gets
@@ -68,6 +69,7 @@ export type InstantiateProps<MakeInput> = Omit<MakeInput, "children"> & BuiltinP
68
69
  export declare const CurrentParent: Context.Reference<Instance.Instance<"shapes/Group", Schema.Struct<{
69
70
  x: Schema.withConstructorDefault<Schema.Number>;
70
71
  y: Schema.withConstructorDefault<Schema.Number>;
72
+ z: Schema.withConstructorDefault<Schema.Number>;
71
73
  opacity: Schema.withConstructorDefault<Schema.Number>;
72
74
  transform: Schema.withConstructorDefault<Schema.Struct<{
73
75
  readonly a: Schema.Number;
@@ -82,6 +84,7 @@ export declare const CurrentParent: Context.Reference<Instance.Instance<"shapes/
82
84
  "~position": Entity.TraitLens<Schema.Struct.ReadonlySide<{
83
85
  x: Schema.withConstructorDefault<Schema.Number>;
84
86
  y: Schema.withConstructorDefault<Schema.Number>;
87
+ z: Schema.withConstructorDefault<Schema.Number>;
85
88
  opacity: Schema.withConstructorDefault<Schema.Number>;
86
89
  transform: Schema.withConstructorDefault<Schema.Struct<{
87
90
  readonly a: Schema.Number;
@@ -96,6 +99,7 @@ export declare const CurrentParent: Context.Reference<Instance.Instance<"shapes/
96
99
  "~opacity": Entity.TraitLens<Schema.Struct.ReadonlySide<{
97
100
  x: Schema.withConstructorDefault<Schema.Number>;
98
101
  y: Schema.withConstructorDefault<Schema.Number>;
102
+ z: Schema.withConstructorDefault<Schema.Number>;
99
103
  opacity: Schema.withConstructorDefault<Schema.Number>;
100
104
  transform: Schema.withConstructorDefault<Schema.Struct<{
101
105
  readonly a: Schema.Number;
@@ -121,6 +125,7 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
121
125
  root: Instance.Instance<"shapes/Group", Schema.Struct<{
122
126
  x: Schema.withConstructorDefault<Schema.Number>;
123
127
  y: Schema.withConstructorDefault<Schema.Number>;
128
+ z: Schema.withConstructorDefault<Schema.Number>;
124
129
  opacity: Schema.withConstructorDefault<Schema.Number>;
125
130
  transform: Schema.withConstructorDefault<Schema.Struct<{
126
131
  readonly a: Schema.Number;
@@ -135,6 +140,7 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
135
140
  "~position": Entity.TraitLens<Schema.Struct.ReadonlySide<{
136
141
  x: Schema.withConstructorDefault<Schema.Number>;
137
142
  y: Schema.withConstructorDefault<Schema.Number>;
143
+ z: Schema.withConstructorDefault<Schema.Number>;
138
144
  opacity: Schema.withConstructorDefault<Schema.Number>;
139
145
  transform: Schema.withConstructorDefault<Schema.Struct<{
140
146
  readonly a: Schema.Number;
@@ -149,6 +155,7 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
149
155
  "~opacity": Entity.TraitLens<Schema.Struct.ReadonlySide<{
150
156
  x: Schema.withConstructorDefault<Schema.Number>;
151
157
  y: Schema.withConstructorDefault<Schema.Number>;
158
+ z: Schema.withConstructorDefault<Schema.Number>;
152
159
  opacity: Schema.withConstructorDefault<Schema.Number>;
153
160
  transform: Schema.withConstructorDefault<Schema.Struct<{
154
161
  readonly a: Schema.Number;
@@ -161,14 +168,14 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
161
168
  children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
162
169
  }, "Type">, number>;
163
170
  }>;
164
- instantiate: <Name extends string, Data extends Schema.Top, Traits extends Partial<Entity.EntityTraits<Data["Type"]>>, MakeInput>(entity: Entity.Entity<Name, Data, Traits, MakeInput>, props: InstantiateProps<MakeInput>) => Effect.Effect<Instance.Instance<Name, Data, Traits>, unknown, Entity.Entity<Name, Data, Traits, MakeInput> | Runner>;
171
+ instantiate: <Name extends string, Data extends Schema.Top, Traits extends Partial<Entity.EntityTraits<Data["Type"]>>>(entity: Entity.Entity<Name, Data, Traits>, props: InstantiateProps<Data["~type.make.in"]>) => Effect.Effect<Instance.Instance<Name, Data, Traits>, never, Runner>;
165
172
  appendChild: (parent: GroupInstance, child: Instance.Instance) => void;
166
173
  removeChild: (parent: GroupInstance, child: Instance.Instance) => void;
167
174
  settings: {
168
175
  frameRate: number;
169
176
  width: number;
170
177
  height: number;
171
- backgroundColor: string;
178
+ backgroundColor: Color.Color;
172
179
  seed: Seed;
173
180
  maxFrames: number;
174
181
  };
@@ -186,32 +193,69 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
186
193
  frameRate: number;
187
194
  width: number;
188
195
  height: number;
189
- backgroundColor: string;
196
+ backgroundColor: Color.Color;
190
197
  camera: CameraState;
191
198
  }, never, never>;
192
199
  camera: Instance.Instance<"Camera", Schema.Struct<{
193
200
  x: Schema.withConstructorDefault<Schema.Number>;
194
201
  y: Schema.withConstructorDefault<Schema.Number>;
195
- zoom: Schema.withConstructorDefault<Schema.Number>;
202
+ z: Schema.withConstructorDefault<Schema.Number>;
203
+ rotX: Schema.withConstructorDefault<Schema.Number>;
204
+ rotY: Schema.withConstructorDefault<Schema.Number>;
205
+ rotZ: Schema.withConstructorDefault<Schema.Number>;
206
+ focalLength: Schema.withConstructorDefault<Schema.Number>;
207
+ focusDistance: Schema.withConstructorDefault<Schema.Number>;
208
+ aperture: Schema.withConstructorDefault<Schema.Number>;
209
+ poiX: Schema.optionalKey<Schema.Number>;
210
+ poiY: Schema.optionalKey<Schema.Number>;
211
+ poiZ: Schema.optionalKey<Schema.Number>;
196
212
  }>, {
197
213
  readonly "~position": {
198
- get: (data: Schema.Struct.ReadonlySide<{
199
- x: Schema.withConstructorDefault<Schema.Number>;
200
- y: Schema.withConstructorDefault<Schema.Number>;
201
- zoom: Schema.withConstructorDefault<Schema.Number>;
202
- }, "Type">) => {
214
+ get: (data: {
215
+ readonly x: number;
216
+ readonly y: number;
217
+ readonly z: number;
218
+ readonly rotX: number;
219
+ readonly rotY: number;
220
+ readonly rotZ: number;
221
+ readonly focalLength: number;
222
+ readonly focusDistance: number;
223
+ readonly aperture: number;
224
+ readonly poiX?: number;
225
+ readonly poiY?: number;
226
+ readonly poiZ?: number;
227
+ }) => {
203
228
  x: number;
204
229
  y: number;
230
+ z: number;
231
+ };
232
+ set: (data: {
233
+ readonly x: number;
234
+ readonly y: number;
235
+ readonly z: number;
236
+ readonly rotX: number;
237
+ readonly rotY: number;
238
+ readonly rotZ: number;
239
+ readonly focalLength: number;
240
+ readonly focusDistance: number;
241
+ readonly aperture: number;
242
+ readonly poiX?: number;
243
+ readonly poiY?: number;
244
+ readonly poiZ?: number;
245
+ }, value: Entity.Position) => {
246
+ readonly x: number;
247
+ readonly y: number;
248
+ readonly z: number;
249
+ readonly rotX: number;
250
+ readonly rotY: number;
251
+ readonly rotZ: number;
252
+ readonly focalLength: number;
253
+ readonly focusDistance: number;
254
+ readonly aperture: number;
255
+ readonly poiX?: number;
256
+ readonly poiY?: number;
257
+ readonly poiZ?: number;
205
258
  };
206
- set: (data: Schema.Struct.ReadonlySide<{
207
- x: Schema.withConstructorDefault<Schema.Number>;
208
- y: Schema.withConstructorDefault<Schema.Number>;
209
- zoom: Schema.withConstructorDefault<Schema.Number>;
210
- }, "Type">, value: Entity.Position) => Schema.Struct.ReadonlySide<{
211
- x: Schema.withConstructorDefault<Schema.Number>;
212
- y: Schema.withConstructorDefault<Schema.Number>;
213
- zoom: Schema.withConstructorDefault<Schema.Number>;
214
- }, "Type">;
215
259
  };
216
260
  }>;
217
261
  setCamera: (instance: Instance.Instance) => void;
@@ -239,6 +283,7 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
239
283
  root: Instance.Instance<"shapes/Group", Schema.Struct<{
240
284
  x: Schema.withConstructorDefault<Schema.Number>;
241
285
  y: Schema.withConstructorDefault<Schema.Number>;
286
+ z: Schema.withConstructorDefault<Schema.Number>;
242
287
  opacity: Schema.withConstructorDefault<Schema.Number>;
243
288
  transform: Schema.withConstructorDefault<Schema.Struct<{
244
289
  readonly a: Schema.Number;
@@ -253,6 +298,7 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
253
298
  "~position": Entity.TraitLens<Schema.Struct.ReadonlySide<{
254
299
  x: Schema.withConstructorDefault<Schema.Number>;
255
300
  y: Schema.withConstructorDefault<Schema.Number>;
301
+ z: Schema.withConstructorDefault<Schema.Number>;
256
302
  opacity: Schema.withConstructorDefault<Schema.Number>;
257
303
  transform: Schema.withConstructorDefault<Schema.Struct<{
258
304
  readonly a: Schema.Number;
@@ -267,6 +313,7 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
267
313
  "~opacity": Entity.TraitLens<Schema.Struct.ReadonlySide<{
268
314
  x: Schema.withConstructorDefault<Schema.Number>;
269
315
  y: Schema.withConstructorDefault<Schema.Number>;
316
+ z: Schema.withConstructorDefault<Schema.Number>;
270
317
  opacity: Schema.withConstructorDefault<Schema.Number>;
271
318
  transform: Schema.withConstructorDefault<Schema.Struct<{
272
319
  readonly a: Schema.Number;
@@ -279,14 +326,14 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
279
326
  children: Schema.withConstructorDefault<Schema.$Array<Schema.String>>;
280
327
  }, "Type">, number>;
281
328
  }>;
282
- instantiate: <Name extends string, Data extends Schema.Top, Traits extends Partial<Entity.EntityTraits<Data["Type"]>>, MakeInput>(entity: Entity.Entity<Name, Data, Traits, MakeInput>, props: InstantiateProps<MakeInput>) => Effect.Effect<Instance.Instance<Name, Data, Traits>, unknown, Entity.Entity<Name, Data, Traits, MakeInput> | Runner>;
329
+ instantiate: <Name extends string, Data extends Schema.Top, Traits extends Partial<Entity.EntityTraits<Data["Type"]>>>(entity: Entity.Entity<Name, Data, Traits>, props: InstantiateProps<Data["~type.make.in"]>) => Effect.Effect<Instance.Instance<Name, Data, Traits>, never, Runner>;
283
330
  appendChild: (parent: GroupInstance, child: Instance.Instance) => void;
284
331
  removeChild: (parent: GroupInstance, child: Instance.Instance) => void;
285
332
  settings: {
286
333
  frameRate: number;
287
334
  width: number;
288
335
  height: number;
289
- backgroundColor: string;
336
+ backgroundColor: Color.Color;
290
337
  seed: Seed;
291
338
  maxFrames: number;
292
339
  };
@@ -304,32 +351,69 @@ declare const Runner_base: Context.ServiceClass<Runner, "Runner", {
304
351
  frameRate: number;
305
352
  width: number;
306
353
  height: number;
307
- backgroundColor: string;
354
+ backgroundColor: Color.Color;
308
355
  camera: CameraState;
309
356
  }, never, never>;
310
357
  camera: Instance.Instance<"Camera", Schema.Struct<{
311
358
  x: Schema.withConstructorDefault<Schema.Number>;
312
359
  y: Schema.withConstructorDefault<Schema.Number>;
313
- zoom: Schema.withConstructorDefault<Schema.Number>;
360
+ z: Schema.withConstructorDefault<Schema.Number>;
361
+ rotX: Schema.withConstructorDefault<Schema.Number>;
362
+ rotY: Schema.withConstructorDefault<Schema.Number>;
363
+ rotZ: Schema.withConstructorDefault<Schema.Number>;
364
+ focalLength: Schema.withConstructorDefault<Schema.Number>;
365
+ focusDistance: Schema.withConstructorDefault<Schema.Number>;
366
+ aperture: Schema.withConstructorDefault<Schema.Number>;
367
+ poiX: Schema.optionalKey<Schema.Number>;
368
+ poiY: Schema.optionalKey<Schema.Number>;
369
+ poiZ: Schema.optionalKey<Schema.Number>;
314
370
  }>, {
315
371
  readonly "~position": {
316
- get: (data: Schema.Struct.ReadonlySide<{
317
- x: Schema.withConstructorDefault<Schema.Number>;
318
- y: Schema.withConstructorDefault<Schema.Number>;
319
- zoom: Schema.withConstructorDefault<Schema.Number>;
320
- }, "Type">) => {
372
+ get: (data: {
373
+ readonly x: number;
374
+ readonly y: number;
375
+ readonly z: number;
376
+ readonly rotX: number;
377
+ readonly rotY: number;
378
+ readonly rotZ: number;
379
+ readonly focalLength: number;
380
+ readonly focusDistance: number;
381
+ readonly aperture: number;
382
+ readonly poiX?: number;
383
+ readonly poiY?: number;
384
+ readonly poiZ?: number;
385
+ }) => {
321
386
  x: number;
322
387
  y: number;
388
+ z: number;
389
+ };
390
+ set: (data: {
391
+ readonly x: number;
392
+ readonly y: number;
393
+ readonly z: number;
394
+ readonly rotX: number;
395
+ readonly rotY: number;
396
+ readonly rotZ: number;
397
+ readonly focalLength: number;
398
+ readonly focusDistance: number;
399
+ readonly aperture: number;
400
+ readonly poiX?: number;
401
+ readonly poiY?: number;
402
+ readonly poiZ?: number;
403
+ }, value: Entity.Position) => {
404
+ readonly x: number;
405
+ readonly y: number;
406
+ readonly z: number;
407
+ readonly rotX: number;
408
+ readonly rotY: number;
409
+ readonly rotZ: number;
410
+ readonly focalLength: number;
411
+ readonly focusDistance: number;
412
+ readonly aperture: number;
413
+ readonly poiX?: number;
414
+ readonly poiY?: number;
415
+ readonly poiZ?: number;
323
416
  };
324
- set: (data: Schema.Struct.ReadonlySide<{
325
- x: Schema.withConstructorDefault<Schema.Number>;
326
- y: Schema.withConstructorDefault<Schema.Number>;
327
- zoom: Schema.withConstructorDefault<Schema.Number>;
328
- }, "Type">, value: Entity.Position) => Schema.Struct.ReadonlySide<{
329
- x: Schema.withConstructorDefault<Schema.Number>;
330
- y: Schema.withConstructorDefault<Schema.Number>;
331
- zoom: Schema.withConstructorDefault<Schema.Number>;
332
- }, "Type">;
333
417
  };
334
418
  }>;
335
419
  setCamera: (instance: Instance.Instance) => void;
package/dist/Runner.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { Layer } from "effect";
2
2
  import * as Context from "effect/Context";
3
3
  import * as Effect from "effect/Effect";
4
- import { Camera, IDENTITY } from "./Camera";
5
- import * as Instance from "./Instance";
6
- import * as Phaser from "./Phaser";
7
- import { Group } from "./shapes/Group";
8
- import { Text } from "./shapes/Text";
4
+ import { Camera, identity } from "./Camera.js";
5
+ import * as Color from "./Color.js";
6
+ import * as Instance from "./Instance.js";
7
+ import * as Phaser from "./Phaser.js";
8
+ import * as Projection from "./Projection.js";
9
+ import { Group } from "./shapes/Group.js";
10
+ import { Text } from "./shapes/Text.js";
9
11
  export const TypeId = "~motion/SceneRunner";
10
12
  /** conventional id of the implicit root group every instance attaches to */
11
13
  export const ROOT_ID = "root";
@@ -47,7 +49,7 @@ export class Runner extends Context.Service()("Runner", {
47
49
  // ($visible is set explicitly by instantiate when overridden)
48
50
  const prev = instances[instance.id];
49
51
  instances[instance.id] = {
50
- data: instance.entity.make(data),
52
+ data: instance.entity.data.make(data),
51
53
  entity: instance.entity,
52
54
  $visible: prev?.$visible ?? true,
53
55
  };
@@ -66,7 +68,7 @@ export class Runner extends Context.Service()("Runner", {
66
68
  frameRate: settings.frameRate ?? 60,
67
69
  width: settings.width ?? 500,
68
70
  height: settings.height ?? 300,
69
- backgroundColor: settings.backgroundColor ?? "#16161d",
71
+ backgroundColor: settings.backgroundColor ?? Color.rgba(22, 22, 29),
70
72
  seed: settings.seed ?? defaultSeed,
71
73
  maxFrames: settings.maxFrames ?? 36_000,
72
74
  };
@@ -78,13 +80,13 @@ export class Runner extends Context.Service()("Runner", {
78
80
  // camera is present from the start, so `depth`/zoom work with no author
79
81
  // ceremony; `setCamera` swaps which instance is active.
80
82
  const camera = Instance.make(Camera, "camera");
81
- setDataUnsafe(camera, {});
83
+ setDataUnsafe(camera, identity(resolvedSettings.width));
82
84
  let activeCameraId = camera.id;
83
85
  const cameraState = () => {
84
86
  const data = instances[activeCameraId]?.data;
85
87
  // a destroyed active camera falls back to identity rather than dying:
86
88
  // the view is not scene-critical state
87
- return data ?? IDENTITY;
89
+ return data ?? identity(resolvedSettings.width);
88
90
  };
89
91
  // append `id` to a group's children and record it as the child's parent
90
92
  const attach = (parent, id) => {
@@ -152,17 +154,40 @@ export class Runner extends Context.Service()("Runner", {
152
154
  instantiate: Effect.fnUntraced(function* (entity, props) {
153
155
  // peel off builtin ($visible) and polymorphic children before the
154
156
  // schema constructs the data — neither is an entity-data field
155
- const { $visible, children, ...rest } = props;
157
+ // = props
156
158
  // children are born (via normalizeChildren) attached to their
157
159
  // ambient parent — reparent them into THIS instance below
158
- const childIds = children === undefined
159
- ? undefined
160
- : yield* normalizeChildren(children);
161
- const dataInput = childIds === undefined ? rest : { ...rest, children: childIds };
160
+ const childIds = "children" in props && props.children
161
+ ? yield* normalizeChildren(props.children)
162
+ : undefined;
162
163
  const id = generateId(entity.name);
163
164
  const instance = Instance.make(entity, id);
164
- setDataUnsafe(instance, dataInput);
165
- if ($visible === false) {
165
+ // cameras get width-relative z/focalLength defaults filled here
166
+ // (AE's 50mm equivalent — see Camera.ts): the schema can't default
167
+ // them because only the Runner knows the scene width. Filling for
168
+ // EVERY Camera instance (not just the built-in one) keeps a
169
+ // setCamera swap from jumping zoom.
170
+ const cameraDefaults = (() => {
171
+ if (entity.name !== Camera.name) {
172
+ return undefined;
173
+ }
174
+ const p = props;
175
+ const focalLength = p.focalLength ??
176
+ Projection.defaultFocalLength(resolvedSettings.width);
177
+ return {
178
+ focalLength,
179
+ z: p.z ?? focalLength,
180
+ // depth of field: focus at the resting distance by default,
181
+ // so the z=0 plane is sharp for an untouched camera
182
+ focusDistance: p.focusDistance ?? focalLength,
183
+ };
184
+ })();
185
+ setDataUnsafe(instance, {
186
+ ...props,
187
+ ...cameraDefaults,
188
+ children: childIds,
189
+ });
190
+ if (props.$visible === false) {
166
191
  setVisibleUnsafe(id, false);
167
192
  }
168
193
  // cameras are view state, not tree nodes: they live in `instances`
@@ -230,7 +255,7 @@ export class Runner extends Context.Service()("Runner", {
230
255
  instances[id] = {
231
256
  entity: entry.entity,
232
257
  $visible: entry.$visible,
233
- data: entry.entity.make({
258
+ data: entry.entity.data.make({
234
259
  ...entry.data,
235
260
  children: children.filter((child) => child !== instance.id),
236
261
  }),