Skip to content

Viz4D Viewer JavaScript API

API latest version v0.4

html
<script type="text/javascript" src="https://r.viz4d.com/api/viewer-api-0.4.js"></script>
Changelog

v0.4:

  • Add new fn: createMtl

v0.3:

  • Add new fn: goToTourStep, nextTourStep, prevTourStep, playTour, pauseTour, isTourPlaying, setTourAutoplay, isTourAutoplay, setTourSpeed, getTourSpeed, getCurrentTourStep, getTourStepCount

  • Add new events: tourTransitionStart, tourTransitionEnd, tourPlayStateChange

  • Rename V4DViewerAPI -> ViewerAPI

v0.2:

  • Add new fn: toggleFullscreen, toggleMeasure, toggleHotspotVisible, toggleControlMode, toggleHelpDialog, toggleSectionDialog, toggleCaptureDialog, toggleXRDialog

v0.1:

  • Initial release
Sample Code
html
<script type="text/javascript" src="https://r.viz4d.com/api/viewer-api-0.4.js"></script>

<!-- Normal iframe embed code -->
<iframe id="viewer-iframe" src="https://viz4d.com/viewer/_YOUR_SCENE_ID_" width="640" height="480" frameborder="0" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true" allow="autoplay;fullscreen;xr-spatial-tracking;display-capture;gamepad" xr-spatial-tracking execution-while-out-of-viewport execution-while-not-rendered web-share></iframe>

<script>
    const viewer = new ViewerAPI( document.getElementById("viewer-iframe"), {
        btnXR: false,
        btnCrossSection: false
    } );

    viewer.ready().then( async () => {
        console.log("Begin select new mtl");
        await viewer.selectMtl( "FLOOR", "Dark Wood Mtl" );
        console.log("Finish select new mtl");
    });
</script>

ViewerAPI Constructor

js
const viewer = new ViewerAPI ( HTMLIFrameElement, options = {
    debug: false, // verbose logging
    btnXR: true,
    btnFullScreen: true,
    btnCrossSection: true,
    btnCapture: true,
    btnMeasure: true,
    btnHelp: true,
    btnShare: true,
    btnControlMode: true,
    btnHotspot: true,
    btnPlay: true,
    btnInfo: true,
    
    logo: true,
    preloaderInfo: true,
    loadingSign: true,
    progressBar: true,
    menuTour: true,
    initialInfo: true, // Open scene info sidepanel at start, auto close after some seconds
    initialHelp: true, // Show help dialog at start, auto close after some seconds

    tourAutoplay: true,
    autoVariant: false // if true, auto change mtl without needing user action, it will be stopped when user open any configHotspot for the first time
} );

API METHODS

play()

Returns: Promise<void>

pause( options )

Parameters:

  • options object (optional)
    • showPreloader boolean - Show preloader screen after pause (default: true)

Returns: Promise<void>

isPlaying()

Returns: Promise< boolean >

selectMtl( mtlSetID, mtlName, options )

Parameters:

  • mtlSetID string
  • mtlName string
  • options object (optional)
    • transition number - Transition duration in ms (default: 2000)

Returns: Promise<void>

Description: Select a material from existing materials in mtlSet

INFO

This promise resolves in two scenarios:

  1. When the transition animation fully completes
  2. When a new selectMtl() call is made for the same mtlSet before the current transition finishes. In this case, the current transition will be interrupted and the promise will resolve early.

selectMtlBySKU( mtlSetID, mtlSKU, options )

Description: Behavior similar to selectMtl(), but select by SKU instead of name.

getSelectedMtl( mtlSetID )

Parameters:

  • mtlSetID string

Returns: Promise< { name, sku, content } >

Description: Get the currently selected material in mtlSet

createMtl( mtlDef, mtlSetID )

Parameters:

  • mtlDef object
  • mtlSetID string - (optional) target mtlSet to add the new mtl

Returns: Promise<void>
Promise resolve when all textures of this new mtl are loaded.

Description: Create a new material from mtlDef and add to mtlSet

mtlDef Structure

Note:
All properties are optional (except "name"). If any properties are not provided, default value like below will be used, so you don't need to provide all properties.

js
{
    name: string, // REQUIRED, must be unique in scene, otherwise Promise will reject
    sku: string, // default null
    content: string, // Markdown description of the material, default null

    diffuse: {
        color: [1, 1, 1], // [r, g, b], range from 0 to 1
        map: { // default null
            url: "/url/to/map.jpg", // .jpg / .png / .webp
            repeat: [1, 1], // [x, y]
            offset: [0, 0], // [x, y]
            rotation: 0 // in degree
        },
        mapAmount: 1, // range 0-1
        mapBrightness: 1
    },

    reflect: {
        color: [0, 0, 0],
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1
    },

    glossiness: {
        factor: 0, // range 0-1
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1,
        mapInvert: false // default false. If true, invert glossiness map, essentially treat it as roughness map. Only affect map, does not affect glossiness.factor
    },

    ior: {
        factor: 1.5, // range 1 - 2.33
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1
    },

    metalness: {
        factor: 0, // range 0-1
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1
    },

    opacity: {
        factor: 1, // range 0-1
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1
    },

    transparency: {
        factor: 0, // range 0-1
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1
    },

    emissive: {
        factor: 1, // range 0-1
        color: [0, 0, 0],
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1
    },

    normal: {
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1 // normal scale, can be negative (similar to inverted Y channel)
    },

    bump: {
        map: {
            url: "/url/to/map.jpg",
            repeat: [1, 1],
            offset: [0, 0],
            rotation: 0
        },
        mapAmount: 1 // bump scale, can be negative
    },

    clearcoat: {
        factor: 0, // range 0-1
        glossiness: 0, // range 0-1
    },

    environment: {
        factor: 1, // range 0-1
        localMode: true // if false, treat the reflection probe as infinite far away
    },

    sheen: {
        enable: false,
        color: [0, 0, 0],
        glossiness: 0, // range 0-1
    },

    side: 1, // 1: front-side, -1: back-side, 2: double-side
    alphaCutoff: 0, // range 0-1
    depthWrite: true,
    flatShading: false,
    excludeFromLightIntensity: false,
    excludeFromLightReflection: false,
    
    polygonOffset: {
        enable: false,
        factor: 0,
    }
}
createMtl Examples:
js
// Create mtl with red diffuse color
await viewer.createMtl({
    name: "Red Mtl",
    sku: "SKU_123",
    content: "This is a **Markdown** description of the material",

    diffuse: {
        color: [1, 0, 0],
    }
}, "MTL_SET_ID");

// Select new mtl right afterward
await viewer.selectMtl( "MTL_SET_ID", "Red Mtl" );

js
// Create mtl with diffuse map
await viewer.createMtl({
    name: "Mtl with diffuse map",

    diffuse: {
        map: {
            url: "https://example.com/diffuse.jpg",
            repeat: [2, 2], // custom repeat
        },
        mapAmount: 0.9
    },

    reflect: {
        color: [ 1, 1, 1 ]
    },

    glossiness: {
        factor: 0.9
    }
}, "MTL_SET_ID");

openHotspot( hotspotName, options )

Parameters:

  • hotspotName string
  • options object (optional)
    • goToView boolean - Go to the hotspot view after open (default: true)
    • transition number - Transition duration in ms (default: 3000)

Returns: Promise<void>

Description: Open a hotspot. Note: This promise resolve when transitionEnd

openInfo()

Returns: Promise<void>

Description: Open the scene info popup (title, description)

isPopupOpen()

Returns: Promise< boolean >

Description: Check if any popup is currently opened.

INFO

Only 1 popup can be opened at one time. Open a new popup will auto close the current popup.

closePopup()

Returns: Promise<void>

Description: Close the currently opened popup (hotspot / info)

toggleControlMode()

Returns: Promise<void>

Description: Switch between Orbit and Walk control modes

toggleMeasure()

Returns: Promise<void>

Description: Toggle measure tool

toggleHotspotVisible()

Returns: Promise<void>

Description: Toggle visibility of all hotspots

toggleHelpDialog()

Returns: Promise<void>

toggleSectionDialog()

Returns: Promise<void>

toggleCaptureDialog()

Returns: Promise<void>

toggleXRDialog()

Returns: Promise<void>


playTour()

Returns: Promise<void>

Description: Start or resume tour autoplay
Note: Tour will be paused when user interact with scene (move, rotate, open hotspot...)

pauseTour()

Returns: Promise<void>

isTourPlaying()

Returns: Promise<boolean>

nextTourStep( options )

Parameters:

  • options object (optional)
    • transition number - Override transition duration (in ms)
    • force boolean - if true, tour transition will be uninterruptible by user interaction (default: false)

Returns: Promise<void>

Description: Go to next step in the tour.
Promise resolve when transition end. Promise reject if transition is interrupted by user interaction.
When tour is at last step, nextTourStep will loop back to first step.

prevTourStep( options )

Parameters:

  • options object (optional)
    • transition number - Override transition duration (in ms)
    • force boolean - Tour transition will be uninterruptible by user interaction if true (default: false)

Returns: Promise<void>

Description: Go to previous step in the tour.
Promise resolve when transition end. Promise reject if transition is interrupted by user interaction.
When tour is at first step, prevTourStep will loop back to last step.

goToTourStep( index, options )

Parameters:

  • index number
  • options object (optional)
    • transition number - Override transition duration (in ms)
    • force boolean - Tour transition will be uninterruptible by user interaction if true (default: false)

Returns: Promise<void>

Description: Go to a specific step in the tour.
Promise resolve when transition end. Promise reject if transition is interrupted by user interaction.

getCurrentTourStep()

Returns: Promise<number>

Description: Get the index of the current step in the tour

getTourStepCount()

Returns: Promise<number>

getTourSpeed()

Returns: Promise<number>

setTourSpeed( multiplier )

Parameters:

  • multiplier number - Speed multiplier (default: 1)

Returns: Promise<void>

Description: Set the speed multiplier, all transition and wait time of tour will be multiplied by this value.


on( eventName, callback )

Returns: void

Description: Add a callback to an event

off( eventName, callback )

Returns: void

Description: Remove a callback from an event

once( eventName, callback )

Returns: void

Description: Add a callback to an event, but it will be removed after the first time it is triggered.


LOADING STATES

Viewer has 3 loading states, sorted in chronological order:

initialized >> ready >> loaded

initialized()

Returns: Promise<void>

Description: This promise resolve when the Viewer finish initialization and begin to loading assets.

List of fn available before initialized: on, off, once, initialized, ready, loaded, isPlaying, pause, play

Note

If Viewer has autoplay off (?autoplay=0) then initialized only trigger after the Viewer play.

ready() Promise<void>

This promise resolve when scene has loaded minimum necessary data of all objects and materials, but not fully loaded, which means low LOD of meshes/textures are added to scene, but higher LOD are still loading progressively.

INFO

All api fn are available after this ready state.

loaded() Promise<void>

This promise resolve when all data of scene is fully loaded.


API EVENTS

Events Usage Example:
javascript
viewer.on("playStateChange", (isPlaying) => {
    console.log("Viewer is now:", isPlaying ? "playing" : "paused");
});

viewer.on("hotspotOpen", ({ name, sku, content }) => {
    console.log(`Hotspot "${name}" opened`);
});

playStateChange

Callback Parameters:

  • isPlaying boolean - Current play state of the viewer

hotspotOpen

Callback Parameters: object

typescript
{
    name: string,    // Name of the opened hotspot
    sku: string,     // SKU of the opened hotspot
    content: string  // Markdown content of the hotspot
}

hotspotClose

Callback Parameters: void

selectMtlStart

Callback Parameters: object

typescript
{
    mtlSetID: string,  // ID of the material set being changed
    name: string       // Name of the new material
}

selectMtlEnd

Callback Parameters: object

typescript
{
    mtlSetID: string,  // ID of the material set that was changed
    name: string       // Name of the applied material
}

tourTransitionStart

Callback Parameters: object

typescript
{
    fromStep: number,     // Index of the previous step
    toStep: number,       // Index of the target step
    transition: number    // Transition duration in ms
}

tourTransitionEnd

Callback Parameters: object

typescript
{
    fromStep: number,     // Index of the starting step
    currentStep: number,  // Index of the current step
    completed: boolean   // Whether transition completed successfully or interrupted
}

tourPlayStateChange

Callback Parameters: object

typescript
{
    isTourPlaying: boolean, // Whether tour is currently playing
    currentStep: number    // Current step index
}