@virtualdisplay.io/client 3.7.0 → 4.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,142 +1,110 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
3
+ ## 4.0.0-alpha.2
4
+
5
+ ### Patch Changes
6
+
7
+ Build optimisations.
8
+
9
+ ## 4.0.0-alpha.1
10
+
11
+ ### Major Changes
12
+
13
+ Metadata-driven configuration replaces direct scene node manipulation. The client now receives available attributes and values from the server via a mapping message, instead of managing 3D nodes directly.
14
+
15
+ ### Breaking changes
16
+
17
+ - **Attribute-only API**: replaces the previous node-based approach with `select()`, `onChange()`, `getValues()`
18
+ - **Removed `isReady` getter** — use `onReady(callback)` instead
19
+ - **Removed `getQueueStatus`** — no longer part of the public API
20
+ - **Package scope changed** from `@virtualdisplay-io/client` to `@virtualdisplay.io/client`
21
+
22
+ ### New features
23
+
24
+ - Metadata-driven mapping: server sends available attributes and values automatically
25
+ - Camera control API: `camera.rotate()`, `camera.tilt()`, `camera.zoom()`
26
+ - Snapshot API: `snapshot.take()` with `photo.onDeveloped()` callback
27
+ - Viewer configuration: AR, fullscreen, loading indicator controls
28
+ - `onMutationFailed` callback for error handling
29
+
30
+ All notable changes to this project will be documented in this file.
4
31
 
5
32
  ## [3.7.0](https://github.com/virtualdisplay-io/client/compare/v3.6.0...v3.7.0) (2025-08-05)
6
33
 
7
34
  ### ✨ Features
8
35
 
9
- * dynamic mapping - proxy release ([#9](https://github.com/virtualdisplay-io/client/issues/9)) ([a95f0e7](https://github.com/virtualdisplay-io/client/commit/a95f0e7a7672b844571b11307637083c6b487f3f)), closes [#8](https://github.com/virtualdisplay-io/client/issues/8)
36
+ - dynamic mapping - proxy release ([#9](https://github.com/virtualdisplay-io/client/issues/9)) ([a95f0e7](https://github.com/virtualdisplay-io/client/commit/a95f0e7a7672b844571b11307637083c6b487f3f)), closes [#8](https://github.com/virtualdisplay-io/client/issues/8)
10
37
 
11
38
  ### 🔧 Maintenance
12
39
 
13
- * various fixes and documentation updates ([#7](https://github.com/virtualdisplay-io/client/issues/7)) ([325150b](https://github.com/virtualdisplay-io/client/commit/325150b41bd557e7426e6dae6780cd4fd7660deb))
40
+ - various fixes and documentation updates ([#7](https://github.com/virtualdisplay-io/client/issues/7)) ([325150b](https://github.com/virtualdisplay-io/client/commit/325150b41bd557e7426e6dae6780cd4fd7660deb))
14
41
 
15
42
  ## [3.6.0](https://github.com/virtualdisplay-io/client/compare/v3.5.1...v3.6.0) (2025-07-23)
16
43
 
17
44
  ### ✨ Features
18
45
 
19
- * add camera configuration support ([#6](https://github.com/virtualdisplay-io/client/issues/6)) ([a6bce4b](https://github.com/virtualdisplay-io/client/commit/a6bce4bfd0d55362e76c893ddf5ed28409dc8bec))
46
+ - add camera configuration support ([#6](https://github.com/virtualdisplay-io/client/issues/6)) ([a6bce4b](https://github.com/virtualdisplay-io/client/commit/a6bce4bfd0d55362e76c893ddf5ed28409dc8bec))
20
47
 
21
48
  ## [3.5.1](https://github.com/virtualdisplay-io/client/compare/v3.5.0...v3.5.1) (2025-07-18)
22
49
 
23
50
  ### ♻️ Code Refactoring
24
51
 
25
- * remove validation of outgoing message types ([#5](https://github.com/virtualdisplay-io/client/issues/5)) ([5f4f985](https://github.com/virtualdisplay-io/client/commit/5f4f9853d65af676aec3a865864f43461fdb6ca5))
52
+ - remove validation of outgoing message types ([#5](https://github.com/virtualdisplay-io/client/issues/5)) ([5f4f985](https://github.com/virtualdisplay-io/client/commit/5f4f9853d65af676aec3a865864f43461fdb6ca5))
26
53
 
27
54
  ## [3.5.0](https://github.com/virtualdisplay-io/client/compare/v3.4.1...v3.5.0) (2025-07-16)
28
55
 
29
56
  ### ✨ Features
30
57
 
31
- * camera control API ([#4](https://github.com/virtualdisplay-io/client/issues/4)) ([1e4c147](https://github.com/virtualdisplay-io/client/commit/1e4c14747cad2a4617c4cc763522b50941adaa7f))
58
+ - camera control API ([#4](https://github.com/virtualdisplay-io/client/issues/4)) ([1e4c147](https://github.com/virtualdisplay-io/client/commit/1e4c14747cad2a4617c4cc763522b50941adaa7f))
32
59
 
33
60
  ## [3.4.1](https://github.com/virtualdisplay-io/client/compare/v3.4.0...v3.4.1) (2025-07-10)
34
61
 
35
62
  ### 🐛 Bug Fixes
36
63
 
37
- * EventBus once handlers and logging improvements ([#3](https://github.com/virtualdisplay-io/client/issues/3)) ([5a99d8d](https://github.com/virtualdisplay-io/client/commit/5a99d8d6ef82d058799734b54c98ca171d17dd36))
64
+ - EventBus once handlers and logging improvements ([#3](https://github.com/virtualdisplay-io/client/issues/3)) ([5a99d8d](https://github.com/virtualdisplay-io/client/commit/5a99d8d6ef82d058799734b54c98ca171d17dd36))
38
65
 
39
66
  ## [3.4.0](https://github.com/virtualdisplay-io/client/compare/v3.3.0...v3.4.0) (2025-07-09)
40
67
 
41
68
  ### ✨ Features
42
69
 
43
- * implement UI configuration via PostMessage CONFIG messages ([#2](https://github.com/virtualdisplay-io/client/issues/2)) ([abc2294](https://github.com/virtualdisplay-io/client/commit/abc229414f9f70c54f37db903c46c0612c5eb6cf))
70
+ - implement UI configuration via PostMessage CONFIG messages ([#2](https://github.com/virtualdisplay-io/client/issues/2)) ([abc2294](https://github.com/virtualdisplay-io/client/commit/abc229414f9f70c54f37db903c46c0612c5eb6cf))
44
71
 
45
72
  ## [3.3.0](https://github.com/virtualdisplay-io/client/compare/v3.2.2...v3.3.0) (2025-07-07)
46
73
 
47
74
  ### ✨ Features
48
75
 
49
- * add isInitial flag to StateMessage ([#50](https://github.com/virtualdisplay-io/client/issues/50)) ([8590354](https://github.com/virtualdisplay-io/client/commit/859035423e161f43791433baac203b2adb95c9fd))
76
+ - add isInitial flag to StateMessage ([#50](https://github.com/virtualdisplay-io/client/issues/50)) ([8590354](https://github.com/virtualdisplay-io/client/commit/859035423e161f43791433baac203b2adb95c9fd))
50
77
 
51
78
  ## [3.2.2](https://github.com/virtualdisplay-io/client/compare/v3.2.1...v3.2.2) (2025-07-01)
52
79
 
53
80
  ### 🐛 Bug Fixes
54
81
 
55
- * change default logger level to warn ([#49](https://github.com/virtualdisplay-io/client/issues/49)) ([a567db2](https://github.com/virtualdisplay-io/client/commit/a567db23a50173e3b167238af2197e545bda6320))
82
+ - change default logger level to warn ([#49](https://github.com/virtualdisplay-io/client/issues/49)) ([a567db2](https://github.com/virtualdisplay-io/client/commit/a567db23a50173e3b167238af2197e545bda6320))
56
83
 
57
84
  ## [3.2.1](https://github.com/virtualdisplay-io/client/compare/v3.2.0...v3.2.1) (2025-06-30)
58
85
 
59
86
  ### 🐛 Bug Fixes
60
87
 
61
- * prevent .env from being used in production builds ([#48](https://github.com/virtualdisplay-io/client/issues/48)) ([7ab54d0](https://github.com/virtualdisplay-io/client/commit/7ab54d02a9aad94daf5a53899fefa9299f9bf73f))
88
+ - prevent .env from being used in production builds ([#48](https://github.com/virtualdisplay-io/client/issues/48)) ([7ab54d0](https://github.com/virtualdisplay-io/client/commit/7ab54d02a9aad94daf5a53899fefa9299f9bf73f))
62
89
 
63
90
  ## [3.2.0](https://github.com/virtualdisplay-io/client/compare/v3.1.0...v3.2.0) (2025-06-27)
64
91
 
65
92
  ### ✨ Features
66
93
 
67
- * publish client package to npm registry ([#45](https://github.com/virtualdisplay-io/client/issues/45)) ([825810b](https://github.com/virtualdisplay-io/client/commit/825810b0ca56da8e50f34f2afac9f75a87acbc40))
94
+ - publish client package to npm registry ([#45](https://github.com/virtualdisplay-io/client/issues/45)) ([825810b](https://github.com/virtualdisplay-io/client/commit/825810b0ca56da8e50f34f2afac9f75a87acbc40))
68
95
 
69
96
  ### 🐛 Bug Fixes
70
97
 
71
- * improve GitHub Actions authentication and remove .env.act ([#47](https://github.com/virtualdisplay-io/client/issues/47)) ([3acc86e](https://github.com/virtualdisplay-io/client/commit/3acc86e5c27a26af0b77cc23ddff397eee141de5))
72
- * use GITHUB_TOKEN for checkout action ([#46](https://github.com/virtualdisplay-io/client/issues/46)) ([f8d60fb](https://github.com/virtualdisplay-io/client/commit/f8d60fba2547950137de10838bcfc874e78d9f33))
98
+ - improve GitHub Actions authentication and remove .env.act ([#47](https://github.com/virtualdisplay-io/client/issues/47)) ([3acc86e](https://github.com/virtualdisplay-io/client/commit/3acc86e5c27a26af0b77cc23ddff397eee141de5))
99
+ - use GITHUB_TOKEN for checkout action ([#46](https://github.com/virtualdisplay-io/client/issues/46)) ([f8d60fb](https://github.com/virtualdisplay-io/client/commit/f8d60fba2547950137de10838bcfc874e78d9f33))
73
100
 
74
101
  ### 📝 Documentation
75
102
 
76
- * update README version reference to v3.1 ([#44](https://github.com/virtualdisplay-io/client/issues/44)) ([1652c15](https://github.com/virtualdisplay-io/client/commit/1652c157890ca43d1e366b302a37f02465d6450b))
103
+ - update README version reference to v3.1 ([#44](https://github.com/virtualdisplay-io/client/issues/44)) ([1652c15](https://github.com/virtualdisplay-io/client/commit/1652c157890ca43d1e366b302a37f02465d6450b))
77
104
 
78
105
  ## [3.1.0](https://github.com/virtualdisplay-io/client/compare/v3.0.0...v3.1.0) (2025-06-25)
79
106
 
80
- ### ⚠ BREAKING CHANGES
81
-
82
- * Complete API redesign with the following changes:
83
- - Removed isReady getter - use onReady callback instead
84
- - Removed getQueueStatus method - internal implementation detail
85
- - Removed toJSON from ModelNode - not needed for public API
86
- - Complete restructure from core/ to src/ with domain-driven design
87
- - New attribute-based API is now the only way to interact with 3D models
88
- - Fire-and-forget messaging pattern for all operations
89
- - JSON Schema validation for mapping configuration
90
-
91
- Features:
92
- - Simplified color configurator demo (300 lines → 160 lines)
93
- - Bundled @virtualdisplay-io/logger package
94
- - Domain-driven directory structure
95
- - Proper error handling with error codes
96
- - Event-driven architecture with EventBus
97
- - onChange callbacks for real-time UI synchronization
98
- - Comprehensive test coverage
99
-
100
- Documentation:
101
- - Complete README rewrite focusing on actual functionality
102
- - Added terminology standards for consistent communication
103
- - Removed unimplemented accessibility claims
104
- - Clear separation between simple and configurable products
105
-
106
- * fix: update lockfile after removing translator dependency
107
-
108
- * docs: update README for v4.0 release
109
-
110
- * fix: add GitHub registry configuration for @virtualdisplay-io scope
111
-
112
- * fix: add npm authentication to bundle-size workflow and package permissions
113
-
114
- * fix: use GITHUB_TOKEN for npm auth and add trailing slash to registry URL
115
-
116
- * chore: update lockfile with fresh install
117
-
118
- * fix: use GH_PAT instead of GITHUB_TOKEN for package authentication
119
-
120
- - Replace GITHUB_TOKEN with GH_PAT in all workflows to avoid conflicts with GitHub's reserved token
121
- - Update CI, release, and bundle-size workflows to use new token variable
122
- - Add .env.act for local testing with act
123
- - Required because GitHub's automatic GITHUB_TOKEN cannot access private organization packages
124
-
125
- * fix: remove push trigger from bundle-size workflow
126
-
127
- - Bundle size analysis should only run on pull requests
128
- - Prevents duplicate runs and confusion about which branch is being tested
129
- - Aligns with CI/CD best practices for PR-based workflows
130
-
131
- ### ✨ Features
132
-
133
- * v4.0.0 - simplified architecture and attribute-only API ([#41](https://github.com/virtualdisplay-io/client/issues/41)) ([dc649c1](https://github.com/virtualdisplay-io/client/commit/dc649c1b863b2427bf6e0350960c4d2e2a2dacb8))
134
-
135
107
  ### 🐛 Bug Fixes
136
108
 
137
- * add missing conventional-changelog-conventionalcommits dependency ([8a15743](https://github.com/virtualdisplay-io/client/commit/8a15743de3984c742ccb5de0537333f321108cd4))
138
- * use NODE_AUTH_TOKEN for npm authentication ([#43](https://github.com/virtualdisplay-io/client/issues/43)) ([c148c6c](https://github.com/virtualdisplay-io/client/commit/c148c6cba6b6b4d1fc431ca5618ad2c3c26638c2))
139
-
140
- ### 🔧 Maintenance
141
-
142
- * trigger release workflow to test GH_PAT secret ([9b07140](https://github.com/virtualdisplay-io/client/commit/9b07140e01d72ccc3774f20733afd197f52c4cde))
109
+ - add missing conventional-changelog-conventionalcommits dependency ([8a15743](https://github.com/virtualdisplay-io/client/commit/8a15743de3984c742ccb5de0537333f321108cd4))
110
+ - use NODE_AUTH_TOKEN for npm authentication ([#43](https://github.com/virtualdisplay-io/client/issues/43)) ([c148c6c](https://github.com/virtualdisplay-io/client/commit/c148c6cba6b6b4d1fc431ca5618ad2c3c26638c2))
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Virtualdisplay
3
+ Copyright (c) 2025-2026 Virtualdisplay
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,6 +1,13 @@
1
1
  # Virtualdisplay client
2
2
 
3
- TypeScript library for embedding interactive 3D product models in web applications.
3
+ TypeScript library for embedding interactive 3D product models in web
4
+ applications.
5
+
6
+ - Simple attribute-based API for product configurators
7
+ - Server-driven configuration, no client-side mapping needed
8
+ - Fire-and-forget messaging with automatic state synchronisation
9
+ - Zero external dependencies (all bundled)
10
+ - Works with any frontend framework or vanilla JavaScript
4
11
 
5
12
  ## Installation
6
13
 
@@ -19,7 +26,7 @@ yarn add @virtualdisplay.io/client
19
26
  ```typescript
20
27
  import { VirtualdisplayClient } from '@virtualdisplay.io/client';
21
28
 
22
- // That's it! Your 3D model is now displayed
29
+ // Your 3D model is now displayed
23
30
  const client = new VirtualdisplayClient({
24
31
  parent: '#product-container',
25
32
  license: 'your-license-key',
@@ -32,47 +39,383 @@ const client = new VirtualdisplayClient({
32
39
  ```typescript
33
40
  import { VirtualdisplayClient } from '@virtualdisplay.io/client';
34
41
 
35
- // Create client instance
36
42
  const client = new VirtualdisplayClient({
37
43
  parent: '#product-container',
38
44
  license: 'your-license-key',
39
45
  model: 'sneaker',
40
46
  });
41
47
 
42
- // Map product options to 3D parts
43
- client.setMapping({
44
- attributes: [
45
- {
46
- name: 'Color',
47
- values: [
48
- { value: 'Red', nodeIds: ['laces_red', 'sole_red'], isSelected: true },
49
- { value: 'Blue', nodeIds: ['laces_blue', 'sole_blue'] },
50
- ],
51
- },
52
- ],
48
+ // Select a product option. The 3D model updates automatically.
49
+ // Calls are buffered until the server provides the attribute mapping
50
+ client.select('Color', 'red');
51
+ ```
52
+
53
+ The server defines which attributes and values are available for each model.
54
+ The client receives this configuration automatically via postMessage. No
55
+ manual mapping required.
56
+
57
+ ## How it works
58
+
59
+ The 3D server hosts the viewer in an iframe, keeping WebGL complexity isolated
60
+ from your application. The client library handles all communication via
61
+ postMessage.
62
+
63
+ ```mermaid
64
+ graph LR
65
+ A[Your application] -->|API calls| B[VirtualdisplayClient]
66
+ B -->|postMessage| C[3D server iframe]
67
+ C -->|Events| B
68
+ B -->|State updates| A
69
+ ```
70
+
71
+ On startup, the server tells the client what is available (attributes, values,
72
+ defaults). After that, the client sends commands and the server responds with
73
+ results.
74
+
75
+ ```mermaid
76
+ sequenceDiagram
77
+ participant UI as Your UI
78
+ participant Client as VirtualdisplayClient
79
+ participant Server as 3D server
80
+
81
+ UI ->> Client: new VirtualdisplayClient(options)
82
+ Client ->> Client: Create iframe
83
+ Note right of Client: Outgoing messages queued
84
+ Server ->> Client: READY
85
+ Note right of Client: Queue flushed
86
+ opt UI or camera options configured
87
+ Client ->> Server: CONFIG
88
+ end
89
+ Server ->> Client: MAPPING (attributes + values + defaults)
90
+ Client ->> Client: Store attribute definitions
91
+ Server ->> Client: MUTATION result (defaults, isInitial: true)
92
+ Client ->> UI: onReady + onChange callbacks fire
93
+ ```
94
+
95
+ 1. Client creates iframe; outgoing messages are queued until the server is ready.
96
+ 2. Server sends `READY` when its message listener is active; client flushes queue.
97
+ 3. `CONFIG` is only sent if UI or camera options were provided in the constructor.
98
+ 4. Server sends `MAPPING` with attribute definitions, loads the 3D model, applies defaults.
99
+ 5. `onReady` fires after the first initial mutation result arrives.
100
+
101
+ ## Product configuration
102
+
103
+ Configure product options by selecting attribute values. The server defines
104
+ which attributes exist (e.g. "Color", "Size") and which values each has
105
+ (e.g. "red", "blue"). You select values; the 3D model updates automatically.
106
+
107
+ ```mermaid
108
+ sequenceDiagram
109
+ participant UI as Your UI
110
+ participant Client as VirtualdisplayClient
111
+ participant Server as 3D server
112
+
113
+ UI ->> Client: client.select('Color', 'blue')
114
+ Client ->> Server: MUTATION
115
+ Note right of Client: Fire-and-forget
116
+ Server ->> Server: Apply 3D changes
117
+ Server ->> Client: MUTATION result
118
+ alt All succeeded
119
+ Client ->> UI: onChange callbacks fire
120
+ else Some failed
121
+ Client ->> UI: onMutationFailed callbacks fire
122
+ end
123
+ ```
124
+
125
+ - `select()` returns immediately; the result arrives asynchronously.
126
+ - Each attribute in the result has its own `success` flag and optional `error`.
127
+ - Attributes within the same component fail as a group.
128
+
129
+ ### Selecting values
130
+
131
+ ```typescript
132
+ // Select a product option. The 3D model updates automatically.
133
+ client.select('Color', 'blue');
134
+ client.select('Size', 'large');
135
+ ```
136
+
137
+ Can be called before the server is ready. Mutations are buffered and sent when
138
+ the mapping arrives.
139
+
140
+ ### Tracking changes
141
+
142
+ Keep your UI in sync with the 3D server state:
143
+
144
+ ```typescript
145
+ client.onChange('Color', (selectedValue) => {
146
+ // selectedValue.value is the selected value (e.g. 'blue')
147
+ // selectedValue.isSelected is true
148
+ updateColorButton(selectedValue.value);
149
+ });
150
+ ```
151
+
152
+ ### Querying available values
153
+
154
+ ```typescript
155
+ // All values for an attribute
156
+ const colors = client.getValues('Color');
157
+ colors.forEach((av) => {
158
+ console.log(av.value, av.isSelected);
159
+ });
160
+
161
+ // A specific value
162
+ const blue = client.getValue('Color', 'blue');
163
+ if (blue?.isSelected) {
164
+ highlightButton('blue');
165
+ }
166
+ ```
167
+
168
+ ### Direct attribute access
169
+
170
+ For advanced use cases, get the `Attribute` instance directly:
171
+
172
+ ```typescript
173
+ const colorAttr = client.getAttribute('Color');
174
+ if (colorAttr) {
175
+ colorAttr.select('blue');
176
+ colorAttr.getValues(); // AttributeValue[]
177
+ colorAttr.getValue('blue'); // AttributeValue | undefined
178
+ colorAttr.onChange((value) => { ... });
179
+ }
180
+ ```
181
+
182
+ ### Handling failed mutations
183
+
184
+ ```typescript
185
+ client.onMutationFailed(({ attribute, value }) => {
186
+ console.error(`Mutation failed: ${attribute} = ${value}`);
187
+ });
188
+ ```
189
+
190
+ ## Snapshots
191
+
192
+ Capture the current 3D view as an image. Useful for product shots, social
193
+ sharing, or saving configurations.
194
+
195
+ ```mermaid
196
+ sequenceDiagram
197
+ participant UI as Your UI
198
+ participant Client as VirtualdisplayClient
199
+ participant Server as 3D server
200
+
201
+ UI ->> Client: client.snapshot.take('photo.png')
202
+ Client ->> Server: SNAPSHOT request
203
+ alt Success
204
+ Server ->> Client: SNAPSHOT data (base64)
205
+ Client ->> UI: onDeveloped callback fires
206
+ else Failure (e.g. no canvas)
207
+ Server ->> Client: SNAPSHOT error
208
+ Client ->> UI: onError callback fires
209
+ end
210
+ ```
211
+
212
+ - Filename is validated client-side (extension, no path traversal).
213
+ - Server always responds, either with image data or an error reason.
214
+
215
+ ### Taking a snapshot
216
+
217
+ ```typescript
218
+ const photo = client.snapshot.take('product-hero-shot.png');
219
+
220
+ // Register callback for when image is ready
221
+ photo.onDeveloped((photoData) => {
222
+ // photoData.filename - The filename you provided
223
+ // photoData.data - Base64 encoded image data
224
+ const img = document.createElement('img');
225
+ img.src = photoData.data;
226
+ document.body.appendChild(img);
53
227
  });
54
228
 
55
- // Control via product options
56
- client.getAttribute('Color')?.select('Red');
229
+ // Handle errors (e.g., canvas not available)
230
+ photo.onError((error) => {
231
+ console.error('Snapshot failed:', error.message);
232
+ });
57
233
  ```
58
234
 
59
- ## Key features
235
+ Filename must end with `.png`. The server always returns PNG data.
236
+
237
+ ## Camera
238
+
239
+ Control the 3D viewer's camera position programmatically. Useful for guided
240
+ product tours, preset views, or syncing camera state with your UI.
241
+
242
+ ```mermaid
243
+ sequenceDiagram
244
+ participant UI as Your UI
245
+ participant Client as VirtualdisplayClient
246
+ participant Server as 3D server
247
+
248
+ UI ->> Client: client.camera.rotate(45).tilt(30).set()
249
+ Client ->> Server: CAMERA commands
250
+ Server ->> Client: CAMERA position
251
+ Client ->> UI: camera.onChange callbacks fire
252
+ Note right of Server: Position updates also fire on user<br/>interaction with the 3D viewport
253
+ ```
254
+
255
+ - Commands accumulate via chaining; `.set()` sends them all at once.
256
+ - `.reset()` sends immediately without chaining.
257
+ - Position updates are continuous. They fire on both programmatic and user-driven camera movement.
258
+
259
+ ### Controlling the camera
260
+
261
+ ```typescript
262
+ // Chain commands, then send with .set()
263
+ client.camera.rotate(45).set();
264
+ client.camera.rotate(90).tilt(45).zoom(150).set();
265
+
266
+ // Reset to base position (sends immediately)
267
+ client.camera.reset();
268
+ ```
269
+
270
+ ### Tracking camera position
271
+
272
+ The current camera position is updated in real-time as the user orbits, zooms,
273
+ or tilts the model.
274
+
275
+ ```typescript
276
+ client.cameraPosition.onChange((position) => {
277
+ console.log(position.rotation, position.tilt, position.zoom);
278
+ });
279
+
280
+ // Read current values directly
281
+ console.log(client.cameraPosition.rotation);
282
+ console.log(client.cameraPosition.tilt);
283
+ console.log(client.cameraPosition.zoom);
284
+ ```
285
+
286
+ ## UI controls
287
+
288
+ Toggle built-in viewer elements like AR, fullscreen, and the loading indicator.
289
+ All are visible by default.
290
+
291
+ ### Via constructor
292
+
293
+ ```typescript
294
+ const client = new VirtualdisplayClient({
295
+ parent: '#viewer',
296
+ license: 'your-license',
297
+ model: 'product',
298
+ ui: {
299
+ arEnabled: false,
300
+ loadingIndicatorEnabled: false,
301
+ },
302
+ });
303
+ ```
304
+
305
+ ### At runtime
306
+
307
+ ```typescript
308
+ client.viewer.setArEnabled(false);
309
+ client.viewer.setFullscreenEnabled(true);
310
+ client.viewer.setLoadingIndicatorEnabled(false);
311
+
312
+ // Bulk operations
313
+ client.viewer.hideAllUI();
314
+ client.viewer.showAllUI();
315
+ client.viewer.updateUIConfig({ arEnabled: false, fullscreenEnabled: true });
316
+ ```
317
+
318
+ ## Lifecycle
319
+
320
+ ### Ready state
321
+
322
+ Use `onReady` to know when the 3D model has loaded. For example, to hide
323
+ your own loading spinner. It is **not** required before calling `select()` or
324
+ `onChange()`.
325
+
326
+ ```typescript
327
+ client.onReady(() => {
328
+ document.getElementById('loading-spinner').hidden = true;
329
+ });
330
+ ```
331
+
332
+ ### Cleanup
333
+
334
+ ```typescript
335
+ client.destroy();
336
+ ```
337
+
338
+ ## Constructor options
339
+
340
+ ```typescript
341
+ interface ClientOptions {
342
+ parent: string | HTMLElement; // Where to embed the 3D viewer
343
+ license: string; // License key from your Virtualdisplay account
344
+ model: string; // Which 3D model to load
345
+ debug?: boolean; // Shows console logs for troubleshooting
346
+ language?: string; // UI language: 'nl', 'en', or 'de' (default: 'nl')
347
+
348
+ // UI elements (all visible by default)
349
+ ui?: {
350
+ arEnabled?: boolean;
351
+ fullscreenEnabled?: boolean;
352
+ loadingIndicatorEnabled?: boolean;
353
+ };
354
+
355
+ // Camera behaviour
356
+ camera?: {
357
+ initialRotate?: number; // Starting view angle (-180 to 180, 0 = front)
358
+ initialTilt?: number; // Starting elevation (0 = top view, 90 = side view)
359
+ initialZoom?: number; // Starting distance (100 = default, may need adjustment)
360
+ minZoom?: number; // Minimum zoom level constraint
361
+ maxZoom?: number; // Maximum zoom level constraint
362
+ minTilt?: number; // Minimum tilt angle constraint
363
+ maxTilt?: number; // Maximum tilt angle constraint
364
+ };
365
+ }
366
+ ```
367
+
368
+ ## Error codes
369
+
370
+ The client throws `VirtualdisplayError` for known error conditions:
371
+
372
+ | Code | Meaning |
373
+ |-----------------------|--------------------------------------------------|
374
+ | `ATTRIBUTE_NOT_FOUND` | Requested attribute doesn't exist in the mapping |
375
+ | `VALUE_NOT_FOUND` | Requested value doesn't exist for attribute |
376
+ | `PARENT_NOT_FOUND` | Parent element for iframe not found |
377
+ | `INVALID_PARAMETER` | Invalid parameter (e.g. snapshot filename) |
378
+ | `SNAPSHOT_FAILED` | Server could not capture the snapshot |
379
+
380
+ ## Real-world example
381
+
382
+ ```typescript
383
+ const client = new VirtualdisplayClient({
384
+ parent: '#product-viewer',
385
+ license: 'your-license',
386
+ model: 'dining-table',
387
+ });
388
+
389
+ // Wire up your product option buttons. Selections are buffered until ready.
390
+ document.querySelectorAll('.color-option').forEach((button) => {
391
+ button.addEventListener('click', () => {
392
+ client.select('topMaterial', button.dataset.value);
393
+ });
394
+ });
395
+
396
+ // Keep buttons in sync with 3D state
397
+ client.onChange('topMaterial', (selectedValue) => {
398
+ document.querySelectorAll('.color-option').forEach((btn) => {
399
+ btn.classList.toggle('active', btn.dataset.value === selectedValue.value);
400
+ });
401
+ });
402
+ ```
403
+
404
+ ## Troubleshooting
405
+
406
+ **Iframe not loading:**
60
407
 
61
- - **Simple API**: Attribute-based product configuration
62
- - **Fire-and-forget**: Send commands without waiting for responses
63
- - **State sync**: Automatic synchronization between client and 3D viewer
64
- - **Framework-agnostic**: Works with React, Vue, Angular, or vanilla JS
65
- - **TypeScript first**: Full type safety and IntelliSense support
66
- - **Minimal dependencies**: Only essential validation and logging included
408
+ - Check that the parent element exists in the DOM
409
+ - Verify your license key is valid
410
+ - Ensure the model ID matches your licence
67
411
 
68
- ## Documentation
412
+ **Attributes not working:**
69
413
 
70
- For complete documentation including:
414
+ - Verify attribute names match exactly (case-sensitive)
415
+ - Check that the value exists for the attribute
416
+ - Use `onMutationFailed` to catch server-side errors
71
417
 
72
- - API reference
73
- - Advanced examples
74
- - Integration guides
75
- - Architecture diagrams
76
- - Troubleshooting
418
+ ## Changelog
77
419
 
78
- Visit our [GitHub repository](https://github.com/virtualdisplay-io/client)
420
+ See the [npm version history](https://www.npmjs.com/package/@virtualdisplay.io/client?activeTab=versions)
421
+ for release notes.