Skip to content

Viewer messaging API

The Maverick Excelsior Viewer is a lightweight, embeddable 3D renderer. It loads .webex scenes and renders them in real time with physically-based materials. This page is the reference for driving an embedded viewer from JavaScript.

For how to embed the viewer in your page (CDN, canvas setup, iframe alternative), see Hosting a viewer.

Communication model

JavaScript and the viewer talk over two one-way string channels:

Direction Function Description
Page to viewer wasm_i(op, d0, d1, d2) Send a command
Viewer to page wasm_o(op, d0, d1, d2) Receive an event

All four parameters are strings. Trailing empty strings may be omitted.

Warning

If you have older integration code that calls window.webex_in(...), migrate it to the wasm_i interface documented here.

Wiring the channels

// Call once after Module.onRuntimeInitialized fires.
window.wasm_i = (op, d0, d1, d2) => {
  Module.ccall('wasm_i', null,
    ['string', 'string', 'string', 'string'],
    [op, d0 || '', d1 || '', d2 || '']);
};

// The viewer calls window.wasm_o directly; dispatch it as a DOM event.
window.wasm_o = (op, d0, d1, d2) => {
  window.dispatchEvent(new CustomEvent('wasm_o', {
    detail: { op, d0, d1, d2 }
  }));
};

window.addEventListener('wasm_o', (e) => {
  const { op, d0, d1, d2 } = e.detail;
  // Handle events...
});

Authentication

api_key

Must be set before loading any scene; it encodes the domain allowlist that open_scene URLs are checked against. Provide it at startup via Module.json.api_key or send it explicitly:

wasm_i('api_key', 'ak_live_xxxxxxxxxxxxxxxx');

webex_shortcode

Load a published scene by its share shortcode instead of a raw URL (the w= parameter of viewer links):

wasm_i('webex_shortcode', 'AB12CD');

Scene lifecycle

open_scene

wasm_i('open_scene', 'https://assets.example.com/ring.webex');

The URL is validated against the API key's domain allowlist before fetching. Repeated calls with the same URL are ignored.

Event d0 Meaning
open_scene_starting filename Loading has begun.
open_scene_progress percentage Download progress, 0 to 100.
open_scene_ready Scene decoded; warmup begins.
open_scene_complete Scene fully loaded and interactive.

close_scene

wasm_i('close_scene');

Unloads the current scene and returns the viewer to its empty state.

Scene controls

Command d0 Description
set_quality medium / high / ultra Quality preset. medium: base geometry, no effects. high: better geometry plus reflections. ultra: best geometry, ambient occlusion, reflections, and glare.
set_clear_color black, white, #RRGGBB, or RRGGBB Background clear color behind the scene.
set_autospin 0 / 1 Continuous automatic rotation.
set_infotag 0 / 1 Information label overlay.
zoom integer delta Camera zoom. Positive zooms in, negative zooms out.
capture Asynchronously capture the current frame. The reply arrives as a capture_data event whose d0 is a base64 JPEG data URI (max 512 px, quality 85). Intended for thumbnails.

Materials

apply_mtl

wasm_i('apply_mtl', 'metal', 'White Gold 18k');
Parameter Description
d0 Material family: gemstone, metal, opal, pearl, or plastic.
d1 Material name within the family. See Material and ambience names; names are matched case-insensitively.

The material is applied to every part of the model that belongs to the family. No response event is emitted.

Properties

set_string and get_string

wasm_i('set_string', '::globals', 'globals_ibl_angle', '45.0');
wasm_i('get_string', '::camera', 'camera_hfov');
Parameter Description
d0 Node: ::globals, ::camera, ::render_pipeline, ::animation, or a layer name.
d1 Property USTR name, e.g. globals_resolution_w. See Scene properties (USTR).
d2 (set only) New value as a string.

get_string replies with a get_string event carrying d0 = node, d1 = ustr, d2 = current value. After a set, the render restarts to reflect the change.

The live camera can be driven through the virtual properties on ::camera (tracker_cam_theta, tracker_cam_phi, tracker_cam_dolly, tracker_cam_pan_x, tracker_cam_pan_y, tracker_cam_hfov), which read and write the on-screen camera directly.

Message reference

Commands (page to viewer)

Command d0 d1 d2 Description
api_key key Authenticate; sets the scene domain allowlist.
webex_shortcode shortcode Load a published scene by shortcode.
open_scene URL Load a .webex scene.
close_scene Unload the current scene.
set_quality preset medium / high / ultra.
set_clear_color color Background color.
set_autospin 0/1 Auto rotation.
set_infotag 0/1 Info label.
zoom delta Camera zoom.
capture Frame snapshot.
apply_mtl family name Apply a library material.
set_string node ustr value Set a property.
get_string node ustr Query a property.

Events (viewer to page)

Event d0 d1 d2 Description
open_scene_starting filename Loading began.
open_scene_progress percentage Download progress.
open_scene_ready Scene decoded, warming up.
open_scene_complete Scene interactive.
get_string node ustr value Property query reply.
capture_data data URI Base64 JPEG of the current frame.

Integration example

<!DOCTYPE html>
<html>
<head><title>WebEx Viewer</title></head>
<body>
  <canvas id="webex-canvas" style="width:100%;height:100vh;"></canvas>
  <script>
    var Module = {
      canvas: document.getElementById('webex-canvas'),
      json: { api_key: 'ak_live_xxxxxxxxxxxxxxxx' }
    };

    Module.onRuntimeInitialized = () => {
      window.wasm_i = (op, d0, d1, d2) => {
        Module.ccall('wasm_i', null,
          ['string', 'string', 'string', 'string'],
          [op, d0 || '', d1 || '', d2 || '']);
      };

      window.wasm_o = (op, d0, d1, d2) => {
        window.dispatchEvent(new CustomEvent('wasm_o', {
          detail: { op, d0, d1, d2 }
        }));
      };

      window.addEventListener('wasm_o', (e) => {
        if (e.detail.op === 'open_scene_complete') {
          wasm_i('apply_mtl', 'metal', 'White Gold 18k');
          wasm_i('set_quality', 'ultra');
          wasm_i('set_clear_color', '#F0F0F0');
          wasm_i('set_autospin', '1');
          wasm_i('set_string', '::globals', 'globals_ibl_angle', '45.0');
        }
      });

      wasm_i('open_scene', 'https://assets.example.com/ring.webex');
    };
  </script>
  <script src="webex-viewer.js"></script>
</body>
</html>