3D Viewer - API documentation
3D Viewer API
The sayduck viewer exposes an api object with various methods that you can use to interact with the sayduck viewer. There are two methods to access the viewer api.
Listen for the sayduck.api-ready event (Recommended)¨
let api;
window.addEventListener('sayduck.api-ready', (event) => {
api = (event as CustomEvent).detail.instance;
});
Invoke the sayduck.request-api event
async function getViewerApi() {
const request = new CustomEvent('sayduck.request-api', {
bubbles: true,
composed: true,
detail: {
instance: {},
},
});
window.dispatchEvent(request);
const api = await request.detail.instance;
return api;
}
glTF Loaded
sayduck.editor.gltfLoaded
Sent when the 3D Viewer has finished loading.
Variants API
Functionality related to variants is available on the configurator (api.variants) property of the api and is only available when viewer mode attribute is set to variants.
<sayduck-viewer product="product-uuid"
mode="variants"
>
</sayduck-viewer>
Change variant
api.variants.setActiveVariant("variant-uuid");
Set active variant to input.
List variant UUIDs
api.variants.getVariants();
List all variant uuids, names and metadata.
Configurator API
Functionality related to configurator is available on the configurator (api.configurator) property of the api and is only available when viewer mode attribute is set to configurator.
<sayduck-viewer product="product-uuid"
mode="configurator"
>
</sayduck-viewer>
Get configuration values
api.configurator.getConfigurations(): ConfigurationObject[]
Lists all the configuration and it's variants/configurations and their children, useful when creating a custom picker.
export interface ConfigurationObject {
uuid: string;
name: string;
label: string | null;
children?: ConfigurationObject[];
isOptional?: boolean;
isConfiguration?: boolean;
parent: {
uuid: string;
name: string;
} | null;
selectedVariant?: {
uuid: string | null;
name: string | null;
};
}
Change variant / configuration
api.configurator.setActiveByUuid("variant-uuid" | "configuration-uuid");
Note: Setting a configuration uuid instead of the variant will select the first variant of that configuration
List selected variants
api.configurator.getSelectedVariants();
List selected variant uuids, names and metadata.
List selected variant uuids
api.configurator.getSelectedVariantUuids();
List selected variants uuids.
Disable optional configuration
api.configurator.disableConfiguration("configuration-uuid");
Disable configuration that is marked optional.
Create a simple picker
api.configurator.createPicker(): HTMLElement
This will create a simple picker with buttons that change the variants. The elements themselves won't have any styling, you need to style them for yourself. If you want more control over how the picker works/looks it's recommended to create your own picker.
Here's a list of classes of the elements created:
sayduck-picker - Container element
sayduck-configuration - Configuration
sayduck-configuration-label - Configuration label
sayduck-variant-button - Variant button
sayduck-variant-button-active - Variant active
Scene API
Functionality related to scene is available on the configurator (api.scene) property of the api and is only available for both viewer mode attribute configurator & variants .
Load new product without reloading page
api.scene.update3dViewer(productUuid: string, mode: APP_MODE);
Load new product without reloading page.
Augmented reality (AR)
Launch AR (menu)
api.scene.launchWebAr();
Launch AR on the active scene when trigged on mobile.
Request QR code URL
api.scene.getQrCodeUrl();
Requests QR code URL that can then be used to integrate custom QR code elements.
Dimensions
Toggle dimensions (menu)
api.scene.toggleDimensions();
Triggers Dimensions in the action menu.
Load dimensions on selected configurations
The new function expects an array of configurations UUIDS and it returns the dimensions of the selection.
Optionally showDimensionsInViewer can be passed, making the output dimensions visible in the scene.
const configurationUuids = ['abc', 'def']
const showDimensionsInViewer = true
api.configurator.getConfigurationDimensions = (
configurationsUuids,
showDimensionsInViewer,
)
It can be also used to get the dimensions of a single configuration by passing only one element to the uuids array.
Camera
Change camera angle
api.scene.setCameraAngles(horizontalAngle, verticalAngle)
Sets camera angle to set value (-180-180).
Toggle camera position (menu)
api.scene.toggleCameraPositions();
Triggers Camera Positions in the action menu
Load camera position
api.scene.setActiveCamera("camera-uuid")
Sets the camera to a set camera position.
Screenshot
Screenshot as data url
api.scene.requestScreenshot(
format?: 'png' | 'jpeg';
keepPosition?: boolean; // Keep position of camera
horizontalAngle?: number;
verticalAngle?: number;
width?: number;
height?: number;
): string
api.scene.requestScreenshot().then(data => console.log(data));
Lists event details to console.
Example data received:
{
dataUrl: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD...",
verticalAngle: 15,
horizontalAngle: -35,
}
Take screenshot (menu)
api.scene.takePhoto({ download: boolean });
Triggers Screenshot in the action menu.
Lights
Toggle lights (menu)
api.scene.toggleLights();
Triggers Toggle Lights in the action menu.
Annotations
Toggle annotations (menu)
api.scene.toggleAnnotations();
Triggers Annotations in the action menu.
Select annotation by uuid
api.scene.selectAnnotation(variant-uuid);
Loads selected annotation.
Unselect annotation
api.scene.unselectAnnotation();
Unselect the selected annotation.
3D Text (troika-three-text)
Create and customize your 3D text using the troika-three-text package attributes.
More information on the feature can be found: https://www.npmjs.com/package/troika-three-text
Update text node
api.scene.updateTextNode(text: string)
Set 3D text to set value.
Update text styling
All of these fields are optional.
api.scene.updateTextNodeAttributes(attributes: {
anchorX: number;
anchorY: number;
clipRect: string;
color: ColorRepresentation;
curveRadius: number;
depthOffset: number;
direction: 'auto' | 'rtl' | 'ltr';
fillOpacity: number;
font: string;
fontSize: number;
glyphGeometryDetail: number;
letterSpacing: number;
lineHeight: 'normal' | number;
maxWidth: number;
outlineBlur: number;
outlineColor: ColorRepresentation;
outlineOffsetX: number;
outlineOffsetY: number;
outlineOpacity: number;
outlineWidth: number;
overflowWrap: 'normal' | 'word-wrap';
sdfGlyphSize: number;
strokeColor: ColorRepresentation;
strokeOpacity: number;
strokeWidth: number;
textAlign: string;
textIndent: number;
whiteSpace: 'normal' | 'nowrap';
}): void
Dynamic Material API
How to use?
console.log(api.scene.getAllMaterialUuids()); // Get all materials
// Update albedoColour
api.scene.updateMaterial("material-uuid", {
albedoColour: { red: 255, green: 0, blue: 0 },
});
// Change texture
api.scene.updateMaterial("material-uuid", {
albedoTexture:
"https://example.com/link-to-texture.jpg",
});
// Update multiple fields
api.scene.updateMaterial("material-uuid", {
albedoColour: { red: 255, green: 0, blue: 0 },
metalness: 1,
roughness: 0,
emissiveColour: { red: 0, green: 0, blue: 200 },
});
Example integration: https://jsfiddle.net/5d3aeub4/
Update material
api.scene.updateMaterial(materialUuid, {})
Updates Material properties.
Material fields
albedoColour: { red: number; green: number; blue: number; alpha: number; }
hasAlbedoTransparency: boolean;
albedoTexture: 'https://example.com/link-to-texture.jpg'
metalness: number;
metalnessTexture: 'https://example.com/link-to-texture.jpg'
roughness: number;
roughnessTexture: 'https://example.com/link-to-texture.jpg'
normalTextureIntensity: number;
normalTexture: 'https://example.com/link-to-texture.jpg'
occlusionTextureIntensity: number;
occlusionTexture: 'https://example.com/link-to-texture.jpg'
emissiveColour: { red: number; green: number; blue: number; }
emissiveTextureIntensity: number;
emissiveTexture: 'https://example.com/link-to-texture.jpg'
Material updated
sayduck.viewer.material.updated
Sent when material update is visible in the 3D Viewer
Extension fields
Volume
volumeExtension needs to be set to true
volumeExtension: boolean;
thicknessTexture: 'https://example.com/link-to-texture.jpg'
attenuationColour: { red: number; green: number; blue: number; }
thicknessFactor: number;
attenuationDistance: number;
Clear coat
clearcoatExtension needs to be set to true
clearcoatExtension: boolean;
clearcoatFactor: number;
clearcoatRoughnessFactor: number;
clearcoatTexture: 'https://example.com/link-to-texture.jpg'
clearcoatNormalTexture: 'https://example.com/link-to-texture.jpg'
clearcoatRoughnessTexture: 'https://example.com/link-to-texture.jpg'
Ior
iorExtension needs to be set to true
iorExtension: boolean;
ior: number;
Sheen
sheenExtension needs to be set to true
sheenExtension: boolean;
sheenTexture: 'https://example.com/link-to-texture.jpg'
sheenRoughnessTexture: 'https://example.com/link-to-texture.jpg'
sheenColour: { red: number; green: number; blue: number; }
sheenRoughnessFactor: number;
Transmission
transmissionExtension needs to be set to true
transmissionExtension: boolean;
transmissionFactor: number;
transmissionTexture: 'https://example.com/link-to-texture.jpg'
Transform (tiling)
transformExtension needs to be set to true
transformExtension: boolean;
tiling: { x: number; y: number; }
tilingOffset: { x: number; y: number; }
tilingRotation: { x: number; y: number; }
Dynamic TRS API
How to use?
console.log(api.scene.getAllNodeUuids()) // get all node uuids
api.scene.updateNode("node-uuid", {
translation: { 1, 1, 1 },
rotation: { 0, 0, 180 },
scale: { 2, 2, 2 }
})
Example integration: https://jsfiddle.net/07wx1uq3/
Get all node uuids
console.log(api.scene.getAllNodeUuids())
Update node
api.scene.updateNode("node-uuid", {
translation: { 1, 1, 1 },
rotation: { 0, 0, 180 },
scale: { 2, 2, 2 }
})
Fields
translation: { x: number; y: number; z: number; }
rotation: { x: number; y: number; z: number; }
scale: { x: number; y: number; z: number; }
Updated on: 02/08/2023
Thank you!