Skip to content

Viewports

A viewport embeds an interactive view of the engine’s scene in your application. Use it in a native UI framework, a web-based UI, or any other application that can host a webview. The viewport displays the scene and sends pointer input back to the engine.

The same HTML element supports an in-page WebAssembly engine and a native engine that streams its rendered view.

The native engine renders with native graphics APIs. It streams or copies the rendered frames into your UI. The streaming viewport works in any UI toolkit that can display a WebView. Custom integrations for specific frameworks, including Electron, are available on a case-by-case basis for native performance. Contact Foresight to discuss your integration.

WebAssembly engine

Import @fslabs/spatialengine, initialize it, and mount the element without an engine attribute:

<spatialengine-viewport label="main" aria-label="Scene viewport"></spatialengine-viewport>

The TypeScript guide shows initialization. Give the element a visible width and height.

Native engine

Open the web portal

Start SpatialEngine and open the portal address reported in its startup output. The default address is http://localhost:8080. Open /streaming to see connected viewports, or /streaming/viewport to view and interact with the scene directly in your browser. The portal also provides engine settings.

Embed a viewport

Load the element from the native engine’s portal and set engine to that portal’s address:

<spatialengine-viewport
  engine="http://localhost:8080"
  label="main"
  aria-label="Scene viewport"
  style="display:block; width:100%; height:480px"
></spatialengine-viewport>
<script type="module" src="http://localhost:8080/spatialengine-viewport.js"></script>

Use the actual bound portal address. Your application controls the engine through its separate gRPC port. The Python SDK supplies generated calls; clients in other languages can use gRPC reflection or the exported protobuf schema.

A page served over HTTPS cannot embed arbitrary insecure HTTP endpoints. Use the engine’s supported network configuration or your deployment’s TLS setup for remote access.

Labels and camera control

Camera statements accept a label such as main as viewport. Labels select viewports; they are not unique IDs. Several viewports can share a label. A statement that requires one viewport rejects an ambiguous selection.

Python:

client.std.viewport.camera.zoom_extents(viewport="main")

TypeScript:

await client.std.viewport.camera.zoomExtents({
  viewport: "main",
  durationSeconds: 0.25,
});

Rendering settings

The element accepts theme, cube, cube-size, and render-scale attributes.

<spatialengine-viewport
  label="main"
  theme="light"
  cube="hidden"
  render-scale="1"
  style="display:block; width:100%; height:480px"
></spatialengine-viewport>

render-scale="1" renders one pixel per CSS pixel. Lower values reduce rendering work. Pointer input remains in CSS pixels.

theme="light" and theme="dark" select the scene background, view cube colors, and viewport control styling together. Without this attribute, the viewport follows the device’s color scheme. Attributes can change at runtime with setAttribute().

Call background() to override the scene color. Set cube-theme="light" or cube-theme="dark" to override the view cube colors. These overrides remain in effect when theme changes. Call background(null) or remove cube-theme to follow theme again.

The fullscreen, stats, and gamepad attributes show buttons for fullscreen, rendering statistics, and virtual joysticks. Set an attribute to hidden to hide its button.

Element methods

Call these methods on the <spatialengine-viewport> element:

MethodBehavior
background(color, transitionMs)Overrides the scene background with a hex color. A duration of 0 changes it immediately. Pass null to follow the theme again.
tier(name)Caps native streaming quality. Accepts auto, ultra, highres, standard, or low. It has no effect on an in-page engine.
fill()Toggles fullscreen. Call it from a user interaction, such as a button click.
filling()Returns whether the viewport is fullscreen.
const viewport = document.querySelector("spatialengine-viewport");
viewport.setAttribute("theme", "light");
viewport.background("#ffffff", 0);

The element also exposes a ready promise. It settles when the mounting attempt finishes, including failed attempts. Background and tier requests wait for mounting internally.

Studio apps

Studio supplies the engine address. Its Python page helper replaces __ENGINE__ in pages loaded with app.page(). Built frontends can ask their Python backend for spatialstudio.engine_url().

Custom Studio UI shows both approaches.