@zkmake/three-studio 0.3.1 → 0.3.3

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 (2) hide show
  1. package/README.md +75 -19
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -33,15 +33,19 @@ const config: StudioConfig = {
33
33
  };
34
34
  ```
35
35
 
36
- `orbitViews(centre, near, { play })` gives `play`, `close` (along the play bearing), `front`, `side`,
37
- `back` and `top`. `front` looks from +x; for an object facing another way, pass where its front
38
- camera stands, `{ front: [0, 0.25, -1] }` for a vehicle driving down -z, and `side` and `back` turn
39
- with it. Write your own as `{ position, target, fov?, near?, far?, zoom? }`.
36
+ `orbitViews(centre, near, { play })` gives `play` (when `play` is passed), `close` (along the play
37
+ bearing), `front`, `side`, `back` and `top`, all but `play` with a 40° lens (`fov` changes it).
38
+ `front` looks from +x; for an object facing another way, pass where its front camera stands,
39
+ `{ front: [0, 0.25, -1] }` for a vehicle driving down -z, and `side` and `back` turn with it. Write
40
+ your own as `{ position, target, fov?, near?, far?, zoom? }`. A link without `view=` opens `play`
41
+ (else the first view); `defaultView` on the config names another.
40
42
 
41
43
  ## With React Three Fiber
42
44
 
43
- `<Studio>` is the whole page. Each variant renders its part; `stage` is what every variant stands in.
44
- Pass the game's `<Canvas>` settings so variants look as they will in the game.
45
+ `<Studio>` is the whole page: a canvas filling its parent. Each variant renders its part; `stage` is
46
+ what every variant stands in. Pass the game's `<Canvas>` settings so variants look as they will in
47
+ the game. Its variants are `StudioReactVariant`s, so a shared config is a
48
+ `StudioConfig<StudioReactVariant>`.
45
49
 
46
50
  ```tsx
47
51
  import { Studio, type StudioReactVariant } from "@zkmake/three-studio/react";
@@ -73,10 +77,30 @@ useFrame(({ clock }) => {
73
77
  });
74
78
  ```
75
79
 
76
- Building the `<Canvas>` yourself? Put `<StudioRig state={resolveStudio(config, location.search)} />`
77
- inside it for the same wiring. Or hand `<Studio>` the `Canvas` component to mount: on React Three
78
- Fiber 10, whose default `Canvas` is WebGPU, a game drawn with WebGL (GLSL material patches) passes
79
- `Canvas={Canvas}` from `@react-three/fiber/legacy`.
80
+ | Prop | Does |
81
+ | ------------------------------ | ----------------------------------------------------------------- |
82
+ | `config` | Areas, variants, views |
83
+ | `canvas` | `<Canvas>` props, or a function of the state (per-area fog) |
84
+ | `stage` | `(state) => ReactNode`: lights, ground, background |
85
+ | `Canvas` | The `<Canvas>` component to mount. Default `@react-three/fiber`'s |
86
+ | `search` | The query to read. Default `location.search` |
87
+ | `onReady` | `(studio) => void`, with `mountStudio`'s handle |
88
+ | `className`, `style` | On the wrapper |
89
+ | `controls`, `audit`, `overlay` | As `mountStudio`'s, below |
90
+ | `globals`, `shotEndpoint` | As `mountStudio`'s, below |
91
+
92
+ `canvas.gl` is merged over `{ preserveDrawingBuffer: true }` and `canvas.camera` over the view's
93
+ lens, when they're plain objects.
94
+
95
+ A variant's `hud: (state) => ReactNode` draws DOM over the canvas (a HUD mockup); `saveShot` leaves
96
+ it out, as it does the overlay.
97
+
98
+ On React Three Fiber 10, whose default `Canvas` is WebGPU, a game drawn with WebGL (GLSL material
99
+ patches) passes `Canvas={Canvas}` from `@react-three/fiber/legacy`.
100
+
101
+ Building the `<Canvas>` yourself? Put `<StudioRig state={state} />` inside it for the same wiring,
102
+ with `state` from `resolveStudio(config, location.search)` made once (module scope or `useMemo`):
103
+ a new state remounts the rig. It takes the same rig props and `onReady`.
80
104
 
81
105
  ## Vanilla three
82
106
 
@@ -99,8 +123,14 @@ renderer.setAnimationLoop(() => {
99
123
  ```
100
124
 
101
125
  `mountStudio` puts the camera at the view, adds OrbitControls, the overlay and the console helpers.
102
- Turn any of them off with `controls: false`, `overlay: false`, `audit: false`, `globals: false`. With
103
- post-processing, pass `render: () => composer.render()` so shots include it.
126
+ Turn any of them off with `controls: false`, `overlay: false`, `audit: false`, `globals: false`, or
127
+ pass options through: `audit` takes three-audit's `installAuditHelpers` options (it passes the
128
+ `renderer` itself), `overlay` a `container`. With post-processing, pass
129
+ `render: () => composer.render()` so shots include it. `shotEndpoint` sets where shots post, over
130
+ `?shots=`.
131
+
132
+ The handle has `state`, `camera`, `controls`, `overlay`, `setView(name)`, `saveShot(path)`,
133
+ `stats()`, `update()` and `dispose()`.
104
134
 
105
135
  ## The URL
106
136
 
@@ -108,14 +138,15 @@ post-processing, pass `render: () => composer.render()` so shots include it.
108
138
  | -------------- | ------------------------------------------------------------------- |
109
139
  | `area=<name>` | The area. A bare `?<name>` works too, as single-object studios link |
110
140
  | `v=<name>` | The variant; the area's first by default |
111
- | `view=<name>` | The camera view; `play` by default |
141
+ | `view=<name>` | The camera view; `play` (or `defaultView`) by default |
112
142
  | `t=<seconds>` | Freezes animation at that time, for steady shots (`useStudioTime`) |
113
143
  | `wire=1` | Draws every material as wireframe, to read the topology |
114
144
  | `clean=1` | Hides the overlay, for screenshots of the whole window |
115
145
  | `shots=<port>` | Where `saveShot` posts, when `three-studio serve` isn't on 8787 |
116
146
 
117
147
  Unknown names fall back to the defaults and are listed in `state.unknown`. `studioHref(state, change)`
118
- builds links: a new area starts at its first variant, the view and `wire` / `t` carry over.
148
+ builds links: a new area starts at its first variant; the view, `wire`, `t` and `shots` carry over,
149
+ `clean` only when asked for.
119
150
 
120
151
  The overlay puts areas and variants top left with the readout (`12 calls · 34,567 tris`) under them,
121
152
  and views top right. View chips move the camera in place and update the URL; area and variant chips
@@ -134,6 +165,10 @@ await saveShot("round-1/trees-lush-play.png");
134
165
  // "/…/shots/round-1/trees-lush-play.png 38 calls · 112,400 tris"
135
166
  ```
136
167
 
168
+ That `saveShot` is the page's, on `window` (`mountStudio` and `<Studio>` put it there): it draws
169
+ through the page's `render`, adds the readout and posts to the `?shots=` port. Paths are relative to
170
+ the receiver's folder, or absolute inside it.
171
+
137
172
  Port 8787 taken (another receiver, another agent's pass)? `serve` says so: run it with
138
173
  `--port 8797` and open the page with `&shots=8797`, which links on the page carry along.
139
174
 
@@ -143,8 +178,14 @@ works in a hidden browser pane where `requestAnimationFrame` never fires. The re
143
178
  size instead of its pixels.
144
179
 
145
180
  `window.studio` has the rest: `studio.setView("close")`, `studio.views`, `studio.stats()`,
146
- `studio.state`, and `studio.installFrameShim()`, which keeps animations running in a hidden pane
147
- (frame rates from it mean nothing; draws and triangles still hold).
181
+ `studio.state`, `studio.scene`, `studio.camera`, `studio.renderer`, `studio.saveShot`, and
182
+ `studio.installFrameShim()`, which keeps animations running in a hidden pane (frame rates from it
183
+ mean nothing; draws and triangles still hold).
184
+
185
+ Without a mounted studio, `saveShot(path, options)` from `@zkmake/three-studio` takes the pieces
186
+ itself: `canvas` (default the first on the page), `render`, `size`, `endpoint` (default
187
+ `http://127.0.0.1:8787`, `SHOT_PORT`) and `stats`. `canvasPng(canvas, { render, size })` is the
188
+ PNG alone.
148
189
 
149
190
  ## Comparing shots
150
191
 
@@ -156,9 +197,24 @@ npx @zkmake/three-studio montage compare.png before-play.png after-play.png befo
156
197
 
157
198
  `diff` counts the pixels whose largest channel moved more than `--fuzz` (3% by default) and exits 1
158
199
  when more than `--max` percent differ, so a stored baseline can gate CI. `--out` writes those pixels
159
- in white over a dimmed copy of the first image. `montage` lays out before/after pairs side by side,
160
- rows stacked, at half size (`--scale`, `--gap`).
200
+ in white over a dimmed copy of the first image; `--json` prints `{ pixels, total, share, over }`.
201
+ Both images must be the same size. `montage` lays out before/after pairs side by side, rows
202
+ stacked, at half size (`--scale`, default 0.5; `--gap`, default 8 px before scaling). Bad arguments
203
+ or an unreadable file exit 2.
161
204
 
162
205
  From a script, `@zkmake/three-studio/node` has the same pieces: `startShotServer`, `decodePng`,
163
206
  `encodePng`, `diffImages`, `montage`, `scaleImage`. PNGs only, 8-bit, not interlaced: what canvases
164
- and browsers save.
207
+ and browsers save. `startShotServer(folder, { port, host, log })` takes port 0 for a free one, and
208
+ its `url` is what `saveShot`'s `endpoint` takes.
209
+
210
+ ## The rest
211
+
212
+ The core (`@zkmake/three-studio`, no DOM at import) also exports what the page is built from:
213
+ `applyView(camera, view, controls?)`, `setWireframe(root, on)`, `studioTime(state, elapsed)`,
214
+ `titleOf`, `installFrameShim()`, and the readout's `frameStats(renderer)` and `formatStats`. `/ui`
215
+ exports `mountStudioOverlay({ state, container?, onView? })`, the switchers and readout alone, and
216
+ `injectStyles` / `STUDIO_STYLES`.
217
+
218
+ ## License
219
+
220
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkmake/three-studio",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "A dev page for three.js scenes: areas, variants and camera views from the URL, an orbit rig, a draw-call readout, audit helpers and screenshots an agent can take, plus a CLI to save and diff them. Vanilla three and React Three Fiber.",
5
5
  "keywords": [
6
6
  "devtools",
@@ -51,7 +51,7 @@
51
51
  "typecheck": "tsc"
52
52
  },
53
53
  "dependencies": {
54
- "@zkmake/three-audit": "^0.6.0"
54
+ "@zkmake/three-audit": "^0.7.0"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@arethetypeswrong/core": "catalog:",