UNPKG

@3dsource/metabox-modular-configurator-api

Version:

API for Metabox MODULAR configurator

705 lines (543 loc) 26.9 kB
# Metabox Modular Configurator API A powerful TypeScript API for integrating and controlling the Metabox Modular Configurator in web applications. This package provides seamless communication with 3D configurators, allowing you to control environments, components, component types, materials, and capture screenshots or PDFs. ## Table of Contents - [Features](#features) - [Prerequisites](#prerequisites) - [Installation](#installation) - [NPM Installation (Recommended)](#npm-installation-recommended) - [CDN Installation](#cdn-installation) - [Quick Start](#quick-start) - [1. HTML Setup](#1-html-setup) - [2. Basic Integration](#2-basic-integration) - [JavaScript (ES6 Modules)](#javascript-es6-modules) - [TypeScript/Angular/React](#typescriptangularreact) - [API Reference](#api-reference) - [System Terminology](#system-terminology) - [Steps to build a custom menu](#steps-to-build-a-custom-menu) - [Core Integration](#core-integration) - [`integrateMetabox`](#integratemetabox) - [Type Definitions](#type-definitions) - [Core Types](#core-types) - [`Communicator`](#communicator) - [`ModularConfiguratorEnvelope`](#modularconfiguratorenvelope) - [`ModularConfiguratorComponent`](#modularconfiguratorcomponent) - [`Material`](#material) - [`Environment`](#environment) - [Utility Types](#utility-types) - [`MimeType`](#mimetype) - [`ApplicationDeviceTypes`](#applicationdevicetypes) - [Command Classes](#command-classes) - [Core Configuration Commands](#core-configuration-commands) - [UI / Interface](#ui--interface) - [Camera / View](#camera--view) - [Showcase Control](#showcase-control) - [Export / Media](#export--media) - [Unreal / Advanced](#unreal--advanced) - [Event Handling](#event-handling) - [Available Events](#available-events) - [Event Examples](#event-examples) - [Troubleshooting](#troubleshooting) - [Common Issues](#common-issues) - [Configurator Not Loading](#configurator-not-loading) - [Commands Not Working](#commands-not-working) - [TypeScript Errors](#typescript-errors) - [Standalone Mode](#standalone-mode) ## Features - 🚀 Easy integration with any web framework (Angular, React, Vue, etc.) - 📱 Responsive design support - 🎨 Full control over materials, environments, and components - 📸 Screenshot and PDF generation - 🛒 Call-to-Action (CTA) data generation - 🎬 Showcase management - 📦 TypeScript support with full type definitions - 🌐 CDN support for quick prototyping ## Prerequisites - Modern web browser with ES6 module support - HTTPS connection (required for Unreal Engine) - Valid Metabox configurator ID (not a full URL) Important: integrateMetabox validates inputs at runtime. It requires a non-empty configuratorId and a non-empty containerId. The iframe URL is constructed internally as `https://{domain}/metabox-configurator/modular/{configuratorId}` with optional query parameters (introImage, introVideo, loadingImage). HTTPS is enforced and non-HTTPS URLs are rejected. It will throw if the container element is not found. ## Installation ### NPM Installation (Recommended) For use with modern frameworks like Angular, React, Vue, etc.: ```bash npm install @3dsource/metabox-modular-configurator-api@latest --save ``` ### CDN Installation For direct browser usage without a build system: ```javascript import { integrateMetabox, Communicator, SetEnvironment, SetComponent } from 'https://cdn.jsdelivr.net/npm/@3dsource/metabox-modular-configurator-api@latest/+esm'; ``` Alternative CDN options: - **jsDelivr**: `https://cdn.jsdelivr.net/npm/@3dsource/metabox-modular-configurator-api@latest/+esm` ## Quick Start ### 1. HTML Setup Ensure your HTML page has the following structure, where the Metabox Configurator will be integrated. You must provide CSS for the `#embed3DSource` element to make the configurator responsive and fit your layout needs. Create a container element where the configurator will be embedded: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Metabox Configurator</title> <style> #embed3DSource { width: 100%; height: 600px; border: 1px solid #ccc; border-radius: 8px; } </style> </head> <body> <div id="embed3DSource"> <!-- Configurator iframe will be embedded here --> </div> </body> </html> ``` ### 2. Basic Integration #### JavaScript (ES6 Modules) ```html <script type="module"> import { GetPdf, GetScreenshot, GetCallToActionInformation, integrateMetabox, saveImage, SetComponent, SetComponentMaterial, SetEnvironment, SetEnvironmentMaterial, ShowEmbeddedMenu, ShowOverlayInterface, ResetCamera, ApplyZoom } from 'https://cdn.jsdelivr.net/npm/@3dsource/metabox-modular-configurator-api@latest/+esm'; // Replace it with your actual configurator ID (not a full URL) const configuratorId = 'configurator-id'; integrateMetabox(configuratorId, 'embed3DSource', (api) => { console.log('Configurator API ready!'); // Listen for configurator data updates api.addEventListener('configuratorDataUpdated', (data) => { console.log('Configurator data:', data); }); // Listen for screenshot events api.addEventListener('screenshotReady', (data) => { saveImage(data, 'configurator-screenshot.png'); }); // Set initial configuration api.sendCommandToMetabox(new SetComponent('componentId', 'typeId', true)); api.sendCommandToMetabox(new SetEnvironment('environmentId')); api.sendCommandToMetabox(new SetComponentMaterial('componentId', 'slotId', 'materialId')); api.sendCommandToMetabox(new SetEnvironmentMaterial('slotId', 'materialId')); api.sendCommandToMetabox(new ShowEmbeddedMenu(false)); api.sendCommandToMetabox(new ShowOverlayInterface(false)); api.sendCommandToMetabox(new GetPdf()); api.sendCommandToMetabox(new GetScreenshot('image/png', { x: 1024, y: 1024 })); api.sendCommandToMetabox(new GetCallToActionInformation()); }); </script> ``` #### TypeScript/Angular/React ```typescript import { integrateMetabox, Communicator, ModularConfiguratorEnvelope, SetEnvironment, ShowOverlayInterface, GetScreenshot, saveImage, SetComponent, SetComponentMaterial, type MimeType, ShowEmbeddedMenu } from '@3dsource/metabox-modular-configurator-api'; class ConfiguratorIntegration { private api: Communicator | null = null; private readonly configuratorId: string; constructor(configuratorId: string) { this.configuratorId = configuratorId; this.initialize(); } private initialize(): void { integrateMetabox(this.configuratorId, 'embed3DSource', (api: Communicator) => { this.api = api; this.setupEventListeners(); this.setupInitialState(); }); } private setupEventListeners(): void { if (!this.api) { return; } // Listen for configuration data changes this.api.addEventListener('configuratorDataUpdated', (data: ModularConfiguratorEnvelope) => { console.log('Configurator data updated:', data); this.handleConfiguratorData(data); }); // Handle screenshot events this.api.addEventListener('screenshotReady', (imageData: string | null) => { saveImage(imageData ?? '', 'configurator-render.png'); }); // Handle viewport ready events this.api.addEventListener('viewportReady', (isReady: boolean) => { console.log('Viewport ready:', isReady); }); // Handle status messages this.api.addEventListener('statusMessageChanged', (message: string | null) => { console.log('Status message:', message); }); } private setupInitialState(): void { if (!this.api) return; // Configure initial environment and components this.api.sendCommandToMetabox(new SetEnvironment('default-environment')); this.api.sendCommandToMetabox(new SetComponent('main-product', 'chair', true)); this.api.sendCommandToMetabox(new ShowOverlayInterface(true)); this.api.sendCommandToMetabox(new ShowEmbeddedMenu(true)); } private handleConfiguratorData(data: ModularConfiguratorEnvelope): void { // Access typed data properties according to actual interface console.log('Configurator:', data.configurator); console.log('Configuration tree:', data.configurationTree); console.log('Components by type:', data.componentsByComponentType); console.log('Component materials:', data.componentMaterialsIds); console.log('Environment ID:', data.environmentId); console.log('Environment materials:', data.environmentMaterialsIds); // Process configurator data according to your needs this.updateUI(data); } private updateUI(data: ModularConfiguratorEnvelope): void { // Update your application UI based on configurator state // This method would contain your specific UI update logic } // Public API methods public takeScreenshot(format: MimeType = 'image/png', size?: { x: number; y: number }): void { if (this.api) { this.api.sendCommandToMetabox(new GetScreenshot(format, size)); } } public changeMaterial(componentId: string, slotId: string, materialId: string): void { if (this.api) { this.api.sendCommandToMetabox(new SetComponentMaterial(componentId, slotId, materialId)); } } public changeEnvironment(environmentId: string): void { if (this.api) { this.api.sendCommandToMetabox(new SetEnvironment(environmentId)); } } public destroy(): void { // Clean up resources when component is destroyed this.api = null; } } // Usage example const configurator = new ConfiguratorIntegration('configurator-id'); // Take a high-resolution screenshot configurator.takeScreenshot('image/png', { x: 1920, y: 1080 }); // Change material configurator.changeMaterial('componentId', 'seat-fabric', 'leather-brown'); ``` ## API Reference ### System Terminology - **product** - 3D digital twin of the actual physical product within a Metabox system; concept is used in Basic configurator. - **productId** - Unique Product ID within the Metabox system; mandatory. Assigned by the Metabox system automatically after the product's 3D digital twin is uploaded into Metabox. - **environment** - 3D digital twin of the actual environment (room scene or other) within a Metabox system. - **environmentId** - Unique environment ID within the Metabox system; mandatory. Assigned by the Metabox system automatically after the environment's 3D digital twin is uploaded into Metabox. - **externalId** - Product or Material ID assigned to product or material in Metabox; optional; can be a combination of letters or numbers or both. Should be identical to the product SKU number in any other non-Metabox e-commerce system that is used for managing products, so Metabox can be integrated with such a system. - **showcase** - Exists as an attribute of product only; optional. If present, it means the product's digital twin contains a camera sequence that causes the video mode added automatically to the configurator by Metabox system to play this camera sequence. - **component** - Product in the Modular configurator context. - **componentId** - Unique Component ID within the Metabox system; mandatory. Assigned by the Metabox system automatically after the Modular configurator is created in Metabox. - **componentType** - Exists in Modular Configurator only; the name of the type of the product component, which can include one or several separate products of the same category (examples of product component types: truck wheel, truck bumper). It is set by an unreal artist while creating the digital twin model and is automatically added to the Metabox system after this twin is uploaded to Metabox. - **E‑Com Configurator** — can be created from any Basic or Modular Configurator by adding a CTA (call‑to‑action) button to the standard configurator right‑nav menu in the Metabox Configurator Manager (where users create and edit configurators). To enable the CTA button, add two mandatory parameters in the Configurator Manager: - Text label for the CTA button (examples: "Get Quote", "Contact Dealer"). - Callback URL for an HTTP POST request. Response requirements: ```json { "redirectUrl": "https://your.site/thank-you-or-checkout" } ``` When the user clicks the CTA button in the configurator: - Metabox generates a JSON payload with the current configuration and sends it to the specified Callback URL. - Your backend decides how to use the configuration JSON (e.g., generate a PDF or build a product list). - After your endpoint responds with a JSON containing "redirectUrl", the user is redirected in a new browser tab to that URL (a non‑Metabox page on your side) to complete the flow (e.g., leave contact information, proceed to checkout, etc.). ### Steps to build a custom menu Updated recommendations: - Use `configuratorDataUpdated` to hydrate custom UI and subscribe for deltas. - Hide built‑in menu: `ShowEmbeddedMenu(false)`; restore with `ShowEmbeddedMenu(true)`. - Hide overlay elements if replacing viewport controls: `ShowOverlayInterface(false)`. ### Core Integration #### `integrateMetabox` Integrates the Metabox Modular Configurator into the specified container element. **TypeScript Signature:** ```typescript declare function integrateMetabox( configuratorId: string, containerId: string, // defaults to 'embed3DSource' apiReadyCallback: (api: Communicator) => void, // required config?: IntegrateMetaboxConfig, ): void; ``` **Parameters:** - `configuratorId` (required): Modular configurator ID (not full URL). Iframe src internally: `https://{domain}/metabox-configurator/modular/{configuratorId}`. - `containerId` (optional): Host element id (default `embed3DSource`). - `apiReadyCallback` (required): Called once the embedded app signals readiness (`appLoaded`). - `config` (optional): - `standalone?`: Disable built‑in template / UI logic inside iframe. - `introImage?`, `introVideo?`, `loadingImage?`: Optional URLs appended as query params when present. - `state?`: Optional initial configurator state. - `domain?`: Override default domain (HTTPS enforced). **Throws:** Error if IDs empty, container missing, or computed iframe URL not HTTPS. **Notes:** A previous iframe with id `embeddedContent` is removed before adding a new one. **Example:** ```typescript import { IntegrateMetaboxConfig } from '@3dsource/metabox-modular-configurator-api'; const config: IntegrateMetaboxConfig = { introImage: 'https://example.com/intro.png', loadingImage: 'https://example.com/loading.png', standalone: false, }; integrateMetabox( 'configurator-id', 'embed3DSource', (api) => { console.log('API ready!', api); }, config, ); ``` ### Type Definitions The API provides comprehensive TypeScript support with the following key interfaces and types: #### Core Types ##### `Communicator` The main API interface for sending commands and listening to events. ```typescript interface Communicator { sendCommandToMetabox<T extends keyof ToMetaboxMessagePayloads>(command: CommandBase<T>): void; addEventListener<K extends keyof FromMetaboxMessagePayloads>(eventType: K, listener: (data: FromMetaboxMessagePayloads[K]) => void): void; removeEventListener<K extends keyof FromMetaboxMessagePayloads>(eventType: K, listener: (data: FromMetaboxMessagePayloads[K]) => void): void; } ``` ##### `ModularConfiguratorEnvelope` The main data structure contains the complete configurator state. ```typescript interface ModularConfiguratorEnvelope { /** Represents the modular configurator api with its components, component types, and environments */ configurator: InitialModularConfigurator; /** The unique tree of components and parent and component type id */ configurationTree: ComponentWithParent[]; /** A record mapping all components by current component type */ componentsByComponentType: Record<string, string>; /** A record mapping component material selection */ componentMaterialsIds: SelectedIds; /** The unique environment identifier */ environmentId: string; /** A record mapping environment material selections */ environmentMaterialsIds: SelectedIds; } ``` ##### `ModularConfiguratorComponent` Represents a component in the configurator. ```typescript interface ModularConfiguratorComponent { /** The id unique identifier. */ id: string; /** The modular configurator component type identifier. */ componentType: ModularConfiguratorComponentType; /** Display the name for the product. */ name: string; /** Position index of the product. */ position: number; /** The detailed product information. */ product: Product; /** Connectors between connectors and virtual sockets. */ virtualSocketToConnectorsMap?: ModularConfiguratorVirtualSocketToConnector[]; /** GraphQL typename for the component. */ __typename: 'ModularConfiguratorComponent'; } ``` ##### `Material` Represents a material that can be applied to components or environments. ```typescript interface Material { /** Unique identifier for the material. */ id: string; /** Title or name of the material. */ title: string; /** Unique external id for the material. */ externalId: string; /** List of thumbnails for the material. */ thumbnailList: Thumbnail[]; /** GraphQL typename for the material. */ __typename: 'Material'; } ``` ##### `Environment` Represents an environment/scene configuration. ```typescript interface Environment { /** Unique identifier for the environment. */ id: string; /** Title or name of the environment. */ title: string; /** Flag indicating if UDS is enabled. */ udsEnabled: boolean; /** The north yaw of the sun in the environment. */ sunNorthYaw: number; /** The UDS hour setting for the environment. */ udsHour: number; /** List of thumbnails for the environment (optional). */ thumbnailList: Thumbnail[]; /** List of slots for the environment (optional). */ slots: Slot[]; /** GraphQL typename for the environment. */ __typename: 'Environment'; } ``` #### Utility Types ##### `MimeType` Supported image formats for screenshots. ```typescript type MimeType = 'image/png' | 'image/jpeg' | 'image/webp'; ``` ##### `ApplicationDeviceTypes` Device type options for responsive behavior. ```typescript type ApplicationDeviceTypes = 'desktop' | 'tablet' | 'mobile'; ``` ### Command Classes All commands are dispatched via: ```typescript api.sendCommandToMetabox(new SomeCommand(...)); ``` #### Core Configuration Commands - `SetComponent(id, typeId, isRoot)` – Add/select a component (root or child). - `SetComponentMaterial(componentId, slotId, materialId)` – Apply material to a component slot. - `SetEnvironment(id)` – Activate environment. - `SetEnvironmentMaterial(slotId, materialId)` – Apply material to environment slot. #### UI / Interface - `ShowEmbeddedMenu(visible)` – Toggle built‑in right sidebar menu. - `ShowOverlayInterface(visible)` – Toggle overlay UI elements (hotspots / viewport controls). #### Camera / View - `ResetCamera()` – Reset to initial camera transform. - `ApplyZoom(zoom)` – Apply zoom delta (positive/negative). Respect configured min/max. #### Showcase Control - `InitShowcase()` – Initialize a showcase sequence for current component/product context. - `PlayShowcase()` / `PauseShowcase()` / `StopShowcase()` – Playback controls. #### Export / Media - `GetScreenshot(format, size?)` – Request ordered render; listen to `screenshotReady`. - `GetPdf()` – Request PDF generation (no dedicated completion event; follow status messages). - `GetCallToActionInformation()` – Trigger CTA flow; backend must respond with `{ redirectUrl }`. #### Unreal / Advanced - `UnrealCommand(command: object | string)` – Send custom Unreal engine command (low‑level; not guaranteed stable). - `MetaboxConfig(appId, partialConfig)` – Initialization command auto‑sent internally. **Examples:** ```typescript // Adjust zoom smoothly api.sendCommandToMetabox(new ApplyZoom(0.25)); // zoom in api.sendCommandToMetabox(new ApplyZoom(-0.25)); // zoom out // Low-level Unreal command (example payload) api.sendCommandToMetabox(new UnrealCommand({ action: 'SetLightIntensity', lightId: 'keyLight', value: 2.5 })); // Simpler string-based Unreal command variant (if supported) api.sendCommandToMetabox(new UnrealCommand('SetSunTime 14:30')); ``` ### Event Handling The below events originate from the embedded configurator (`FromMetaboxMessagePayloads`). Register via `api.addEventListener(name, handler)`. ### Available Events | Event | Payload | Description | | ----------------------------- | ----------------------------- | --------------------------------------------------------------------- | -------------------- | ------- | | `configuratorDataUpdated` | `ModularConfiguratorEnvelope` | Any configuration change (components, types, materials, environment). | | `ecomConfiguratorDataUpdated` | `EcomConfigurator` | CTA label/callback updates (E‑Com enabled). | | `showcaseStatusChanged` | `ShowCaseStatus` | Showcase playback status: init, play, pause, stop. | | `dataChannelConnected` | `boolean` | Unreal data channel connectivity (true = connected). | | `viewportReady` | `boolean` | Unreal viewport visibility / readiness. | | `statusMessageChanged` | string or null | Loading / progress status messages. | | `screenshotReady` | string or null | Base64 image from latest screenshot (null if failed). | | `videoResolutionChanged` | object | Stream resolution changed. `{ width: number | null; height: number | null }` | ### Event Examples ```typescript api.addEventListener('configuratorDataUpdated', (env) => { console.log('Active environment:', env.environmentId); console.log('Components per type:', env.componentsByComponentType); }); api.addEventListener('screenshotReady', (img) => { if (img) saveImage(img, 'modular-configurator.png'); }); api.addEventListener('dataChannelConnected', (connected) => { console.log('Unreal channel connected?', connected); }); api.addEventListener('videoResolutionChanged', (res) => { console.log('Viewport resolution:', res.width, 'x', res.height); }); ``` ## Troubleshooting ### Common Issues #### Configurator Not Loading **Problem**: The configurator iframe doesn't appear or loads indefinitely. **Solutions**: 1. Verify the configurator ID is correct and accessible 2. Check that the container element exists in the DOM 3. Ensure the container has proper dimensions (width/height) 4. Check the browser console for CORS or network errors ```typescript // Ensure the element exists and ID is correct before calling integrateMetabox(configuratorId, 'embed3DSource', (api) => { console.log('API ready!'); }); ``` #### Commands Not Working **Problem**: API commands are sent but don't affect the configurator. **Solutions**: 1. Ensure the API is ready before sending commands 2. Verify component/environment IDs are correct 3. Check that the configurator supports the specific command ```typescript // Wait for API to be ready integrateMetabox(configuratorId, containerId, (api) => { // Only send commands after this callback api.sendCommandToMetabox(new SetEnvironment('env-001')); }); ``` #### TypeScript Errors **Problem**: TypeScript compilation errors with API types. **Solutions**: 1. Ensure you're importing types correctly: ```typescript import type { Communicator, ModularConfiguratorEnvelope } from '@3dsource/metabox-modular-configurator-api'; ``` 2. Update your `tsconfig.json` to include proper module resolution: ```json { "compilerOptions": { "moduleResolution": "node", "esModuleInterop": true } } ``` --- For more examples and advanced usage, visit our [documentation site](https://preview.3dsource.com/front-libraries/master/modular-configurator-api-doc/). ## Standalone Mode Standalone mode lets you embed the Metabox renderer without the built‑in Metabox UI and template logic. This is ideal when you want to build a fully custom UI (menus, buttons, flows) and drive the configurator entirely through this API. When standalone is enabled, the embedded page does not render Metabox’s internal menus, overlays, or template logic. You are responsible for sending commands (e.g., setComponent, setEnvironment, setComponentMaterialById) and listening to events to keep your UI in sync. Key points: - Purpose: use when you need a 100% custom interface and logic on the host page. - Behavior: Metabox default UI, embedded menu and template logic are disabled on the iframe side. - Control: you drive everything with API commands and events. How to enable Pass as param to config with a standalone set to true when calling integrateMetabox. TypeScript example: ```typescript import { integrateMetabox, Communicator, SetComponent, SetEnvironment } from '@3dsource/metabox-modular-configurator-api'; integrateMetabox( 'configurator-id', 'embed3DSource', (api: Communicator) => { // Send your initial commands to establish state api.sendCommandToMetabox(new SetComponent('your-component-id', 'your-type-id', true)); api.sendCommandToMetabox(new SetEnvironment('your-environment-id')); }, { standalone: true }, ); ``` JavaScript (CDN) example: ```html <script type="module"> import { integrateMetabox, SetComponent, SetEnvironment } from 'https://cdn.jsdelivr.net/npm/@3dsource/metabox-modular-configurator-api@latest/+esm'; integrateMetabox( 'configurator-id', 'embed3DSource', (api) => { api.sendCommandToMetabox(new SetComponent('your-component-id', 'your-type-id', true)); api.sendCommandToMetabox(new SetEnvironment('your-environment-id')); }, { standalone: true }, ); </script> ``` Notes and tips - In standalone mode, nothing will change until you send initial commands (e.g., set component/environment). If you see a blank/default view, ensure you dispatch the necessary SetComponent/SetEnvironment commands once api is ready. - All events (like configuratorDataUpdated, screenshotReady) still work; use them to keep your UI synchronized. - The library sets the config.hostUrl and config.apiVersion automatically; you typically don’t need to pass them.