Skip to main content
Documentation

Quickstart

Install Five SDK, parse sample work data, render a 3D tour, and switch viewing modes.

Render a real 3D tour in five minutes. By the end of this page you will have a <canvas> running inside a Vite app, displaying a Realsee work, with a button that toggles between Panorama and Floorplan modes.

This guide uses vanilla JavaScript — the smallest path with no framework noise. In a framework project, run the same lifecycle from client-side code after its container has mounted.

Open Playground to see the bundled Demo scene before you start, or follow the steps below to render the public sample work locally.

Public demo boundary

The bundled Playground Demo and this guide's public work need no sign-in, Developer app, or OpenAPI scope. Loading a Team-owned VR in Playground additionally requires sign-in and membership in that Team.

Install

Five SDK ships as @realsee/five. Its renderer peer is three@^0.117.1. This guide also installs @realsee/open-works@0.1.1 as a separate sample-data package; it is not a Five SDK peer dependency.

npm install @realsee/five@6.8.9 three@^0.117.1 @realsee/open-works@0.1.1

Keep the declared Three.js peer range

@realsee/five@6.8.9 declares three@^0.117.1 as a peer dependency. Validate compatibility before moving outside that range.

Set the viewport meta tag

Five SDK computes scene scale from the viewport's CSS pixel ratio, so the viewport meta tag matters. Without it, mobile browsers will zoom the canvas and dimensions inside the 3D space will look wrong. Paste this into your index.html before anything else:

<meta
  name="viewport"
  content="width=device-width, initial-scale=1, viewport-fit=cover"
/>

Keep browser zoom available for accessibility. initial-scale=1 gives Five SDK the correct starting CSS-pixel scale, while users can still zoom the page when they need larger content.

Initialize Five SDK

Create the renderer with a smaller initial panorama tile size for a quicker first paint.

import { Five, parseWork } from '@realsee/five'

const five = new Five({
  imageOptions: {
    // Start at 512×512 tiles. Five will swap in higher-res tiles as the
    // camera dwells on a region — this trades a tiny first-frame for much
    // faster initial paint.
    size: 512,
  },
})

Five is a class — you instantiate one per canvas. The full initialization surface lives on the API reference.

Mount to the DOM

appendTo inserts the renderer's <canvas> as a child of the container you pass. Make sure the container has a defined size — Five SDK reads container.clientWidth / clientHeight to size the canvas:

const container = document.querySelector<HTMLElement>('#app')!
five.appendTo(container)

Style the container to fill the viewport (or whatever box you want the tour to occupy):

#app {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

Load a Work

Pull in a sample work from @realsee/open-works. The Work JSON ships in the npm package and loads through your bundler, so there is no backend Work-data request to configure. Five SDK still fetches the image and model assets referenced by that Work while rendering.

import workJSON from '@realsee/open-works/virtual/816lPVZQkQDF5XOpPo/work.json'

await five.load(parseWork(workJSON), 'initial')

load accepts a parsed work object. The examples use parseWork(workJSON) because that is the stable shape exported by @realsee/five@6.8.9. In production you would fetch work data from your backend (or call the OpenAPI — see OpenAPI overview) and pass the parsed result to load.

Handle resize

Follow the package quick start and call refresh() from a resize listener so the canvas and projection matrix stay in sync:

window.addEventListener('resize', () => five.refresh())

If your container changes size for non-window reasons (a sidebar opens, an orientation lock fires), call five.refresh() from that event too.

Switch between modes

Mode switching is two calls: getCurrentState() to read the active mode, changeMode() to transition. The SDK animates the camera between modes for you.

const $button = document.createElement('button')
$button.textContent = 'Switch to floorplan'

$button.addEventListener('click', () => {
  const { mode } = five.getCurrentState()
  if (mode === Five.Mode.Panorama) {
    void five.changeMode(Five.Mode.Floorplan)
  } else if (mode === Five.Mode.Floorplan) {
    void five.changeMode(Five.Mode.Panorama)
  }
})

// Update the label whenever the mode actually changes — including
// programmatic changes triggered elsewhere in your app.
five.on('modeChange', (mode) => {
  $button.textContent =
    mode === Five.Mode.Panorama ? 'Switch to floorplan' : 'Switch to panorama'
})

container.appendChild($button)

Three things to notice:

  1. Always read the current mode through getCurrentState(). A button label that tracks a local boolean will drift as soon as anything else in the app calls changeMode().
  2. Subscribe to modeChange for UI updates. It fires after the transition completes, so it's the right hook for "switch the icon now."
  3. Mode transitions are cancellable. Calling changeMode() mid-animation interrupts the previous one — the SDK is robust to fast taps.

Try it

The full vanilla-JS demo runs end-to-end in StackBlitz. Fork it, change the work ID, or swap in your own.

Open the Five SDK StackBlitz demo.

Next steps

You now have a tour rendering in the browser. From here: