softbox 4.23.0 → 4.25.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/README.md CHANGED
@@ -36,6 +36,8 @@ Balanced studio lighting, a baked soft contact shadow that grounds the model, au
36
36
  - **[Turntable](#turntable)** — one-word showcase auto-rotate that pauses while the user drags
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
+ - **[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
39
41
  - **[Photoreal mode](#photoreal-mode--stills)** — progressive path tracing + `captureStill()` PNG export
40
42
  - **[Video capture](#video-capture)** — `captureVideo()` records the canvas to WebM/MP4, zero dependencies
41
43
  - **[Hotspots & click selection](#hotspot-annotations--click-selection)** — DOM pins on world-space points, BVH-accelerated picking
@@ -139,6 +141,51 @@ pick survives unrelated option changes. Variant materials materialize in
139
141
  the background right after load (first paint never waits for colorways
140
142
  nobody opened); an early pick is applied the moment they're ready.
141
143
 
144
+ ## AR
145
+
146
+ One option puts an **AR** button over the canvas that opens the model in the
147
+ platform's native AR viewer — no WebXR session, no extra bundle:
148
+
149
+ ```tsx
150
+ <SimpleViewer object={url} options={{ ar: true }} />
151
+
152
+ // iOS AR Quick Look cannot read GLB — give it the USDZ counterpart:
153
+ <SimpleViewer object={url} options={{ ar: { iosSrc: '/shoe.usdz', title: 'Runner' } }} />
154
+ ```
155
+
156
+ - **Android** → Scene Viewer, straight from the model's own URL (`ar: true`
157
+ is enough). The model must be loaded from an **https** URL — a dropped
158
+ `blob:` file has no address a native app could fetch, and Scene Viewer
159
+ refuses plain http. Imperative `loadModel()` swaps are tracked — the
160
+ button always hands off the model that is on stage.
161
+ - **iOS** → AR Quick Look, from `iosSrc` (USDZ).
162
+ - **Desktop / unsupported** → the button simply never renders, so setting
163
+ `ar` unconditionally is safe. On an Android-UA device that turns out to
164
+ have no AR component (Quest, TV boxes), the failed handoff bounces back
165
+ reload-free and the button retires itself.
166
+
167
+ `placement` picks the corner (`bottom-left` by default; it lifts above the
168
+ built-in preset picker on its own). UI-only: toggling `ar` never rebuilds
169
+ the viewer or reloads the model.
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
+
142
189
  ## Turntable
143
190
 
144
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
@@ -31,6 +31,33 @@ export declare interface AnimationOptions {
31
31
  speed?: number;
32
32
  }
33
33
 
34
+ /**
35
+ * AR handoff configuration: a small button over the canvas that opens the
36
+ * model in the platform's native AR viewer — AR Quick Look on iOS, Scene
37
+ * Viewer on Android. UI-only: the button never touches the WebGL viewer, and
38
+ * toggling it never rebuilds anything. The button only renders on devices
39
+ * that can actually hand off (never on desktop).
40
+ */
41
+ export declare interface AROptions {
42
+ /**
43
+ * USDZ counterpart of the model, for iOS AR Quick Look — Quick Look cannot
44
+ * read GLB, so without this the button stays hidden on iOS. Android Scene
45
+ * Viewer instead reuses the loaded model's own URL and needs nothing here
46
+ * (but requires the model to be loaded from a network URL — a dropped
47
+ * `blob:` file has no address a native app could fetch).
48
+ */
49
+ iosSrc?: string;
50
+ /** Title shown on Android Scene Viewer's info card. */
51
+ title?: string;
52
+ /**
53
+ * Corner the button floats in (default `bottom-left`). When the built-in
54
+ * preset picker is enabled, a bottom-placed button lifts above the chip
55
+ * row on its own — pick a top corner if it must clear other chrome (e.g.
56
+ * a `bottom-left` gizmo).
57
+ */
58
+ placement?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
59
+ }
60
+
34
61
  export declare interface AxesHelperOptions {
35
62
  size?: number;
36
63
  }
@@ -730,6 +757,23 @@ export declare interface SimpleViewerOptions {
730
757
  * live preset picker). All opt-in; UI-only — never rebuilds the viewer.
731
758
  */
732
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;
769
+ /**
770
+ * AR handoff button: opens the model in the platform's native AR viewer —
771
+ * AR Quick Look on iOS (needs `iosSrc`, a USDZ counterpart), Scene Viewer
772
+ * on Android (reuses the model's own URL). `true` enables with defaults.
773
+ * The button renders only on devices that can actually hand off, so it is
774
+ * safe to set unconditionally. UI-only — never rebuilds the viewer.
775
+ */
776
+ ar?: boolean | AROptions;
733
777
  /**
734
778
  * Click-picking / hotspot-occlusion raycast tuning (e.g. `selection: { bvh:
735
779
  * false }` to skip the load-time BVH build on memory-constrained targets).
package/dist/index.d.ts CHANGED
@@ -31,6 +31,33 @@ export declare interface AnimationOptions {
31
31
  speed?: number;
32
32
  }
33
33
 
34
+ /**
35
+ * AR handoff configuration: a small button over the canvas that opens the
36
+ * model in the platform's native AR viewer — AR Quick Look on iOS, Scene
37
+ * Viewer on Android. UI-only: the button never touches the WebGL viewer, and
38
+ * toggling it never rebuilds anything. The button only renders on devices
39
+ * that can actually hand off (never on desktop).
40
+ */
41
+ export declare interface AROptions {
42
+ /**
43
+ * USDZ counterpart of the model, for iOS AR Quick Look — Quick Look cannot
44
+ * read GLB, so without this the button stays hidden on iOS. Android Scene
45
+ * Viewer instead reuses the loaded model's own URL and needs nothing here
46
+ * (but requires the model to be loaded from a network URL — a dropped
47
+ * `blob:` file has no address a native app could fetch).
48
+ */
49
+ iosSrc?: string;
50
+ /** Title shown on Android Scene Viewer's info card. */
51
+ title?: string;
52
+ /**
53
+ * Corner the button floats in (default `bottom-left`). When the built-in
54
+ * preset picker is enabled, a bottom-placed button lifts above the chip
55
+ * row on its own — pick a top corner if it must clear other chrome (e.g.
56
+ * a `bottom-left` gizmo).
57
+ */
58
+ placement?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
59
+ }
60
+
34
61
  export declare interface AxesHelperOptions {
35
62
  size?: number;
36
63
  }
@@ -730,6 +757,23 @@ export declare interface SimpleViewerOptions {
730
757
  * live preset picker). All opt-in; UI-only — never rebuilds the viewer.
731
758
  */
732
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;
769
+ /**
770
+ * AR handoff button: opens the model in the platform's native AR viewer —
771
+ * AR Quick Look on iOS (needs `iosSrc`, a USDZ counterpart), Scene Viewer
772
+ * on Android (reuses the model's own URL). `true` enables with defaults.
773
+ * The button renders only on devices that can actually hand off, so it is
774
+ * safe to set unconditionally. UI-only — never rebuilds the viewer.
775
+ */
776
+ ar?: boolean | AROptions;
733
777
  /**
734
778
  * Click-picking / hotspot-occlusion raycast tuning (e.g. `selection: { bvh:
735
779
  * false }` to skip the load-time BVH build on memory-constrained targets).