softbox 4.24.0 → 4.25.1

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 CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  Balanced studio lighting, a baked soft contact shadow that grounds the model, auto-framing, compressed-asset decoders — all on by default, zero configuration (the real-scale concrete paver floor is [one option away](#configuration)). Lighting needs zero network requests (the studio environment is procedural); the DRACO/KTX2 decoder wasm is fetched only when a model actually uses that compression, from a CDN by default or [self-hosted](#loaders) for offline use. The core is ~102 kB gzip; the path tracer lives in a lazy chunk that loads only when enabled. Every release is gated by 790+ unit tests plus a Playwright suite that asserts **real WebGL pixels** in CI.
27
27
 
28
- [![softbox playground](https://raw.githubusercontent.com/LEMing/softbox/main/public/og-image.png)](https://leming.github.io/softbox/)
28
+ [![softbox playground](https://raw.githubusercontent.com/LEMing/softbox/main/public/og-image.jpg)](https://leming.github.io/softbox/)
29
29
 
30
30
  **▶ [Live playground](https://leming.github.io/softbox/)** — drag & drop your own `.glb`, switch presets live, click the model to pin hotspots, download a still.
31
31
 
@@ -37,6 +37,7 @@ Balanced studio lighting, a baked soft contact shadow that grounds the model, au
37
37
  - **[Animations](#animations)** — GLTF clips autoplay with one word; play/pause/clip-picker API
38
38
  - **[Material variants](#material-variants)** — KHR_materials_variants colorways, switched live with one option
39
39
  - **[AR](#ar)** — one option hands the model to AR Quick Look (iOS) / Scene Viewer (Android)
40
+ - **[Poster](#poster)** — an image is the instant first paint; the live model dissolves in when ready
40
41
  - **[Photoreal mode](#photoreal-mode--stills)** — progressive path tracing + `captureStill()` PNG export
41
42
  - **[Video capture](#video-capture)** — `captureVideo()` records the canvas to WebM/MP4, zero dependencies
42
43
  - **[Hotspots & click selection](#hotspot-annotations--click-selection)** — DOM pins on world-space points, BVH-accelerated picking
@@ -167,6 +168,24 @@ platform's native AR viewer — no WebXR session, no extra bundle:
167
168
  built-in preset picker on its own). UI-only: toggling `ar` never rebuilds
168
169
  the viewer or reloads the model.
169
170
 
171
+ ## Poster
172
+
173
+ A poster image is the viewer's **instant first paint** — shown until the
174
+ model's first painted frame, then dissolved into the live scene:
175
+
176
+ ```tsx
177
+ <SimpleViewer object={url} options={{ poster: '/hero.webp', loading: 'lazy' }} />
178
+ ```
179
+
180
+ With `loading: 'lazy'` the combination is LCP-friendly: the page paints the
181
+ poster immediately with zero WebGL work, and the real viewer boots only
182
+ when scrolled into view. Generate posters with `handle.captureStill()` —
183
+ same studio look, pixel-identical to what the live viewer will show. While
184
+ opaque, the poster catches input (nothing invisible underneath can be
185
+ tapped). If the load fails, the poster stays up as the backdrop under the
186
+ built-in error overlay — with `loadingIndicator: false` it steps aside
187
+ instead, so a dead load never masquerades as a frozen hero image.
188
+
170
189
  ## Turntable
171
190
 
172
191
  One word puts the model on a slowly rotating showcase turntable. It pauses while the user drags and resumes on release; toggling is live, like presets.
package/dist/index.d.cts CHANGED
@@ -757,6 +757,15 @@ export declare interface SimpleViewerOptions {
757
757
  * live preset picker). All opt-in; UI-only — never rebuilds the viewer.
758
758
  */
759
759
  ui?: UIOptions;
760
+ /**
761
+ * Poster image (URL) shown over the canvas until the model's first painted
762
+ * frame. Composes with `loading: 'lazy'`: the poster is the instant,
763
+ * WebGL-free first paint while the real viewer boots and the GLB
764
+ * downloads. Generate one with `handle.captureStill()`. Stays up as the
765
+ * backdrop if the load errs (the error overlay renders above it).
766
+ * UI-only — changing it never rebuilds the viewer.
767
+ */
768
+ poster?: string;
760
769
  /**
761
770
  * AR handoff button: opens the model in the platform's native AR viewer —
762
771
  * AR Quick Look on iOS (needs `iosSrc`, a USDZ counterpart), Scene Viewer
package/dist/index.d.ts CHANGED
@@ -757,6 +757,15 @@ export declare interface SimpleViewerOptions {
757
757
  * live preset picker). All opt-in; UI-only — never rebuilds the viewer.
758
758
  */
759
759
  ui?: UIOptions;
760
+ /**
761
+ * Poster image (URL) shown over the canvas until the model's first painted
762
+ * frame. Composes with `loading: 'lazy'`: the poster is the instant,
763
+ * WebGL-free first paint while the real viewer boots and the GLB
764
+ * downloads. Generate one with `handle.captureStill()`. Stays up as the
765
+ * backdrop if the load errs (the error overlay renders above it).
766
+ * UI-only — changing it never rebuilds the viewer.
767
+ */
768
+ poster?: string;
760
769
  /**
761
770
  * AR handoff button: opens the model in the platform's native AR viewer —
762
771
  * AR Quick Look on iOS (needs `iosSrc`, a USDZ counterpart), Scene Viewer