@virtualdisplay.io/client 4.0.0-alpha.34 → 4.0.0-alpha.36

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,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.0-alpha.36
4
+
5
+ ### Minor Changes
6
+
7
+ Add `client.personalisation` to show a Shopper's own picture on a print zone of the model, clear it again, and move and scale it with `place()`; the picture stays in the browser, and `zones` reports each zone's real size. A failed `setImage` or `clear` call rejects with a `VirtualdisplayError` coded `PERSONALISATION_FAILED`.
8
+
9
+ ## 4.0.0-alpha.35
10
+
11
+ ### Minor Changes
12
+
13
+ Show an attribute whose values are a product's sizes as a slider in the standard interface, each stop a size with its unit.
14
+
15
+ ### Patch Changes
16
+
17
+ Announce the loading progress and a failed load to screen readers.
18
+
3
19
  ## 4.0.0-alpha.34
4
20
 
5
21
  ### Patch Changes
package/README.md CHANGED
@@ -264,6 +264,50 @@ In an app that shows several models, this toggles the first model's markers.
264
264
  `viewerSettings.annotations` (see below) and the marker button in the standard
265
265
  interface govern every model's.
266
266
 
267
+ ## Personalisation
268
+
269
+ A print zone is a material the 3D artist named in the model, such as `logo`.
270
+ `setImage` shows a picture the Shopper chose on it, fitted without stretching;
271
+ `clear` brings back the zone's own texture. The picture stays in the browser
272
+ and is never uploaded.
273
+
274
+ ```typescript
275
+ input.addEventListener('change', async () => {
276
+ const file = input.files?.[0];
277
+ if (file === undefined) return;
278
+ try {
279
+ await client.personalisation.setImage('logo', file);
280
+ } catch (error) {
281
+ console.error(error.message); // PERSONALISATION_FAILED
282
+ }
283
+ });
284
+
285
+ await client.personalisation.clear('logo');
286
+ ```
287
+
288
+ Each call resolves once the model shows the result. A call rejects when the
289
+ zone is not on the model, when the file is not a picture, and when a later call
290
+ on the same zone replaces it before it shows.
291
+
292
+ `zones` lists every material of the model with its own texture, each a zone a
293
+ picture can go on, with its real size in millimetres; pick yours by name.
294
+ `onZones` calls back each time the viewer reports them. `place` moves and scales
295
+ the picture on a zone: `x` and `y` are the picture's centre and `scale` its width,
296
+ as fractions of the zone measured from its top left. Calls for one zone within
297
+ one animation frame collapse into the last, so call it on every pointer move.
298
+ A zone that shows no picture yet drops the placement, so call `place` once
299
+ `setImage` has resolved.
300
+ `editing: true` draws the zone's outline while the Shopper edits. The `Placement`
301
+ and `ZoneSize` types are exported.
302
+
303
+ ```typescript
304
+ client.personalisation.onZones((zones) => {
305
+ // [{ name: 'logo', aspect: 2.95, widthMm: 73.2, heightMm: 24.8 }]
306
+ });
307
+
308
+ client.personalisation.place('logo', { x: 0.5, y: 0.4, scale: 0.6, editing: true });
309
+ ```
310
+
267
311
  ## Standard interface
268
312
 
269
313
  The client renders a complete viewer UI automatically: loading indicator,
@@ -363,14 +407,15 @@ type ClientAddress =
363
407
 
364
408
  The client throws `VirtualdisplayError` for known error conditions:
365
409
 
366
- | Code | Meaning |
367
- | --------------------- | ------------------------------------------------ |
368
- | `NO_MAPPING` | Attribute data not yet available from the server |
369
- | `ATTRIBUTE_NOT_FOUND` | Requested attribute doesn't exist in the mapping |
370
- | `VALUE_NOT_FOUND` | Requested value doesn't exist for attribute |
371
- | `PARENT_NOT_FOUND` | Parent element for iframe not found |
372
- | `INVALID_PARAMETER` | Invalid parameter (e.g. snapshot filename) |
373
- | `SNAPSHOT_FAILED` | Server could not capture the snapshot |
410
+ | Code | Meaning |
411
+ | ------------------------ | ------------------------------------------------ |
412
+ | `NO_MAPPING` | Attribute data not yet available from the server |
413
+ | `ATTRIBUTE_NOT_FOUND` | Requested attribute doesn't exist in the mapping |
414
+ | `VALUE_NOT_FOUND` | Requested value doesn't exist for attribute |
415
+ | `PARENT_NOT_FOUND` | Parent element for iframe not found |
416
+ | `INVALID_PARAMETER` | Invalid parameter (e.g. snapshot filename) |
417
+ | `SNAPSHOT_FAILED` | Server could not capture the snapshot |
418
+ | `PERSONALISATION_FAILED` | The picture could not be shown on the print zone |
374
419
 
375
420
  ## Troubleshooting
376
421
 
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./rolldown-runtime-CYdcPHCu.js";
2
- // ../../../../../../../../../pnpm-stores/e3aff882cdc12f5743094dba4c0352ef7fba83c50787c88540bf1ca2d7880a2f/v11/links/@/qrcode/1.5.4/38431ab3ce46851b9c5211f56296031bcdd3ab8a89e17d0d2a55d25922dcc7fe/node_modules/qrcode/lib/can-promise.js
2
+ // ../../../../../../../../../pnpm-stores/ab1eeece5fc302f45711b88f6df917354b6e66d4ade8287a9ef8aa65a21e9642/v11/links/@/qrcode/1.5.4/38431ab3ce46851b9c5211f56296031bcdd3ab8a89e17d0d2a55d25922dcc7fe/node_modules/qrcode/lib/can-promise.js
3
3
  var t = /* @__PURE__ */ e(((e, t) => {
4
4
  t.exports = function() {
5
5
  return typeof Promise == "function" && Promise.prototype && Promise.prototype.then;
package/dist/index.d.ts CHANGED
@@ -61,6 +61,15 @@ interface SelectableAttribute {
61
61
  */
62
62
  readonly hidden?: boolean;
63
63
  }
64
+ /** One print zone the viewer can show a picture on, measured on its surface. */
65
+ interface ZoneSize {
66
+ /** The zone's material name, as the 3D artist named it in the GLB. */
67
+ readonly name: string;
68
+ /** Width over height. */
69
+ readonly aspect: number;
70
+ readonly widthMm: number;
71
+ readonly heightMm: number;
72
+ }
64
73
  /**
65
74
  * What the configurator does with a matched configuration.
66
75
  */
@@ -324,6 +333,56 @@ declare class Focus {
324
333
  onChange(callback: (state: FocusState | null) => void): void;
325
334
  }
326
335
 
336
+ /** Where the picture sits on a print zone. `x` and `y` are its centre, measured from the zone's top left. */
337
+ interface Placement {
338
+ /** The centre, as a fraction of the zone width, 0 to 1. */
339
+ readonly x: number;
340
+ /** The centre, as a fraction of the zone height, 0 to 1. */
341
+ readonly y: number;
342
+ /** The picture width as a fraction of the zone width, where 1 is the full width. */
343
+ readonly scale: number;
344
+ /** True while the Shopper edits, which draws the zone outline. */
345
+ readonly editing: boolean;
346
+ }
347
+ /**
348
+ * Shows the Shopper's own picture on a print zone of the model, or clears it.
349
+ * The picture stays in the browser: it is sent to the viewer and never uploaded.
350
+ */
351
+ declare class Personalisation {
352
+ private readonly send;
353
+ private readonly instance;
354
+ private readonly pending;
355
+ private readonly zoneListeners;
356
+ private zoneReport;
357
+ private sequence;
358
+ private readonly pendingPlacements;
359
+ private frame;
360
+ /**
361
+ * Show a picture on a print zone. Resolves once the picture shows on the model.
362
+ * Rejects with the viewer's message when the picture cannot be shown, and when
363
+ * a later call on the same zone replaces it before it shows.
364
+ */
365
+ setImage(zone: string, image: Blob): Promise<void>;
366
+ /**
367
+ * Restore the zone's own picture. Resolves once the model shows it again.
368
+ * Rejects with the viewer's message when the zone is not on the model.
369
+ */
370
+ clear(zone: string): Promise<void>;
371
+ /** The print zones of the model, from the last report. Empty until the model loads. */
372
+ get zones(): readonly ZoneSize[];
373
+ /** Call back with the print zones each time the viewer reports them. */
374
+ onZones(callback: (zones: readonly ZoneSize[]) => void): void;
375
+ /**
376
+ * Move the picture on a zone. Calls for one zone within one animation frame collapse into
377
+ * the last, so a drag sends at most one message per zone per frame. A zone that shows no
378
+ * picture yet drops the placement, so call it once `setImage` has resolved.
379
+ */
380
+ place(zone: string, placement: Placement): void;
381
+ private sendPlacements;
382
+ private request;
383
+ private expire;
384
+ }
385
+
327
386
  /**
328
387
  * Error codes for Virtualdisplay client errors
329
388
  */
@@ -334,6 +393,7 @@ declare const ERROR_CODES: {
334
393
  readonly PARENT_NOT_FOUND: "PARENT_NOT_FOUND";
335
394
  readonly INVALID_PARAMETER: "INVALID_PARAMETER";
336
395
  readonly SNAPSHOT_FAILED: "SNAPSHOT_FAILED";
396
+ readonly PERSONALISATION_FAILED: "PERSONALISATION_FAILED";
337
397
  };
338
398
  type ErrorCode = typeof ERROR_CODES[keyof typeof ERROR_CODES];
339
399
  /**
@@ -520,6 +580,7 @@ declare class BaseClient {
520
580
  private readonly cameraApi;
521
581
  private readonly cameraPositionApi;
522
582
  private readonly focusApi;
583
+ private readonly personalisationApi;
523
584
  private readonly configurationApi;
524
585
  private readonly snapshotApi;
525
586
  private readonly annotationsApi;
@@ -584,6 +645,7 @@ declare class BaseClient {
584
645
  get annotations(): Annotations;
585
646
  get camera(): Camera;
586
647
  get focus(): Focus;
648
+ get personalisation(): Personalisation;
587
649
  get configuration(): Configuration;
588
650
  get cameraPosition(): CameraPosition;
589
651
  get snapshot(): Snapshot;
@@ -668,5 +730,5 @@ declare class VirtualdisplayClient extends BaseClient {
668
730
  onSyncChange(callback: (connected: boolean) => void): void;
669
731
  }
670
732
 
671
- export { AVAILABILITY, Annotations, Attribute, AttributeValue, Camera, CameraPosition, Configuration, ERROR_CODES, Focus, Photo, Snapshot, VD_EVENTS, VirtualdisplayClient, VirtualdisplayError, enableDebugMode, isDebugMode, logger };
672
- export type { AnnotationVisibility, AppSubmitSettings, AppType, Availability, CameraLimits, CameraPositionState, ClientAddress, ClientLogger, ClientOptions, ClientOptionsBase, ErrorCode, FocusState, MutationFailedEvent, PhotoData, PricingDocument, PricingRule, ResolvedAppInfo, ResolvedConfiguration, SelectableAttribute, SelectableSnapshot, SubmitOptions, SubmittedConfiguration, VdEvent, ViewerSettings, ViewerSettingsOverride, VirtualdisplaySelectEvent, VirtualdisplaySelectedEvent, VirtualdisplayUiEventMap, VirtualdisplayUiEventType };
733
+ export { AVAILABILITY, Annotations, Attribute, AttributeValue, Camera, CameraPosition, Configuration, ERROR_CODES, Focus, Personalisation, Photo, Snapshot, VD_EVENTS, VirtualdisplayClient, VirtualdisplayError, enableDebugMode, isDebugMode, logger };
734
+ export type { AnnotationVisibility, AppSubmitSettings, AppType, Availability, CameraLimits, CameraPositionState, ClientAddress, ClientLogger, ClientOptions, ClientOptionsBase, ErrorCode, FocusState, MutationFailedEvent, PhotoData, Placement, PricingDocument, PricingRule, ResolvedAppInfo, ResolvedConfiguration, SelectableAttribute, SelectableSnapshot, SubmitOptions, SubmittedConfiguration, VdEvent, ViewerSettings, ViewerSettingsOverride, VirtualdisplaySelectEvent, VirtualdisplaySelectedEvent, VirtualdisplayUiEventMap, VirtualdisplayUiEventType, ZoneSize };