From aa4c5e13f8c1a3b58559b34ffbe7f91f0ab068d1 Mon Sep 17 00:00:00 2001 From: Ada Rose Cannon Date: Tue, 5 May 2026 13:29:13 -0700 Subject: [PATCH] Update backdrop explainer for JS (#2) Restructure the explainer around the JavaScript API on the element (requestImmersive / exitImmersive), moving the previous declarative design to "Alternative Considered". The imperative approach gives the page ownership of the activation UI, awareness of the current immersive state via immersivechange and a handle for controlling the backdrop after it is presented (entityTransform, environment map swaps, model animations). --------- Co-authored-by: Marcos Caceres --- spatial-backdrop/README.md | 86 +++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/spatial-backdrop/README.md b/spatial-backdrop/README.md index 300d6db..bd23568 100644 --- a/spatial-backdrop/README.md +++ b/spatial-backdrop/README.md @@ -32,7 +32,79 @@ This doesn’t cover using 2D images or videos as backdrop sources although they ## Usage -The backdrop should be specified using a link in the head which indicates that the browser should download the model asset which can be supported by the operating system, it may also include an environment map which describes the lighting for lit materials. +The spatial backdrop is exposed through a JavaScript API on the `` element, +following a pattern similar to the [Fullscreen API](https://fullscreen.spec.whatwg.org/). +A model element has `requestImmersive()` which can be called to enter the immersive presentation, +and `document.exitImmersive()` ends it. +The `requestImmersive()` method returns a promise that rejects if, +for example, the user declines to give consent to the backdrop opening. + +`document.immersiveElement` returns the model element currently being presented immersively, +or `null` if no immersive presentation is active. + +The user agent fires a simple `onimmersivechange` event when the immersive presentation starts or ends, +allowing the website to update its layout to suit the immersive presentation. +The user may choose to end the immersive presentation at any point. + +The user agent fires an `onimmersiveerror` if the immersive presentation ends without +the website or the user requesting it (i.e., because of some error). + +The selected model acts as the API surface for controlling the environment. +It can be used to control animations, +to dynamically change the environment map, +and to use its `entityTransform` to move the environment in relation to the user. + +```html + + +``` + +```js +const model = document.getElementById("backdrop"); +const toggle = document.getElementById("toggle"); + +toggle.addEventListener("change", async () => { + try { + if (toggle.checked) { + await model.requestImmersive(); + } else { + await document.exitImmersive(); + } + } catch (e) { + console.error("Failed to toggle immersive mode", e); + toggle.checked = !!document.immersiveElement; + } +}); + +model.onimmersivechange = () => { + const immersive = !!document.immersiveElement; + document.body.classList.toggle("immersive", immersive); + toggle.checked = immersive; +}; + +model.onimmersiveerror = (e) => { + console.error("Immersive error", e); +}; +``` + +## Alternative Considered: Declarative Approach + +An earlier developer preview used a declarative approach +where the backdrop was specified using a `` element in the document head +or a CSS `@backdrop` at-rule. + +This required less work on the website side, +less code to write, +and was a straight forward progressive enhancement. + +However, the feature's discoverability was limited +because the browser needed to provide its own UI affordance for activating the backdrop. +The website did not own the experience +and was limited in what it could offer, +since it had no awareness of whether or when the backdrop was being presented. ```html ``` -Just like with stylesheets you can use media to pick different models and environment maps for light mode/dark mode or prefers-reduced-data. +A similar CSS based approach has also been considered: -The backdrop must be requested in the top level frame, backdrops in frames are ignored. - -## Alternative Considered Usage - -Using a CSS @rule approach is being considered as an alternative. - -``` -*@backdrop* { +```css +@backdrop { model: url("./bg.usdz"); environment: url("./bg-env.hdr"); content: "A science fiction cantina with 3 aliens playing instruments";