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>