@thinkersteps_labs/3d-viewer-angular 0.0.0-stage → 1.0.1
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/README.md +106 -2
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/swatches/jewelry-customizer.component.d.ts +29 -0
- package/dist/swatches/jewelry-customizer.component.d.ts.map +1 -0
- package/dist/swatches/jewelry-customizer.component.js +198 -0
- package/dist/swatches/jewelry-customizer.component.js.map +1 -0
- package/dist/swatches/metal-swatches.component.d.ts +28 -0
- package/dist/swatches/metal-swatches.component.d.ts.map +1 -0
- package/dist/swatches/metal-swatches.component.js +265 -0
- package/dist/swatches/metal-swatches.component.js.map +1 -0
- package/dist/swatches/stone-swatches.component.d.ts +28 -0
- package/dist/swatches/stone-swatches.component.d.ts.map +1 -0
- package/dist/swatches/stone-swatches.component.js +265 -0
- package/dist/swatches/stone-swatches.component.js.map +1 -0
- package/dist/viewer.component.d.ts +136 -0
- package/dist/viewer.component.d.ts.map +1 -0
- package/dist/viewer.component.js +339 -0
- package/dist/viewer.component.js.map +1 -0
- package/dist/viewer.module.d.ts +22 -0
- package/dist/viewer.module.d.ts.map +1 -0
- package/dist/viewer.module.js +52 -0
- package/dist/viewer.module.js.map +1 -0
- package/package.json +47 -3
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { EventEmitter, OnChanges, AfterViewInit, OnDestroy, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { type Viewer, type ViewerSourceInput, type MetalColorProp, type StoneColorProp, type ViewerOptions, type ViewerState, type PartInfo, type PartType, type MaterialSlotInfo } from '@thinkersteps_labs/3d-viewer-core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Angular wrapper for @3d-viewer/core.
|
|
6
|
+
*
|
|
7
|
+
* Usage (standalone):
|
|
8
|
+
* import { ViewerComponent } from '@thinkersteps_labs/3d-viewer-angular'
|
|
9
|
+
*
|
|
10
|
+
* Usage (NgModule):
|
|
11
|
+
* import { ViewerModule } from '@thinkersteps_labs/3d-viewer-angular'
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```html
|
|
15
|
+
* <td-viewer
|
|
16
|
+
* [src]="'/models/ring.glb'"
|
|
17
|
+
* [metalColor]="'yellow-gold-18k'"
|
|
18
|
+
* [stoneColor]="'diamond-d'"
|
|
19
|
+
* (loaded)="onLoaded($event)"
|
|
20
|
+
* (error)="onError($event)"
|
|
21
|
+
* ></td-viewer>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare class ViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
|
|
25
|
+
/** Direct 3D model URL string. Resolves and normalizes format automatically. */
|
|
26
|
+
src?: string;
|
|
27
|
+
/** The 3D model to load. Supports URL string, ModelSource payload, or null to unload. */
|
|
28
|
+
source: ViewerSourceInput;
|
|
29
|
+
/** Metal preset ID or hex color string. Reactive post-init. */
|
|
30
|
+
metalColor?: MetalColorProp;
|
|
31
|
+
/** Stone preset ID or hex color string. Reactive post-init. */
|
|
32
|
+
stoneColor?: StoneColorProp;
|
|
33
|
+
/** Bulk material name or pinpoint slot ID color overrides. Reactive. */
|
|
34
|
+
materialColors?: Record<string, string>;
|
|
35
|
+
/** Part color overrides keyed by partId or partId:slotIndex. Reactive. */
|
|
36
|
+
partColors?: Record<string, string>;
|
|
37
|
+
/** Optional explicit container height (e.g. 520 or '520px'). Prevents 0px collapse. */
|
|
38
|
+
height?: number | string;
|
|
39
|
+
/** Optional explicit container min-height. */
|
|
40
|
+
minHeight?: number | string;
|
|
41
|
+
get hostHeight(): string | undefined;
|
|
42
|
+
get hostMinHeight(): string | undefined;
|
|
43
|
+
/** Background color as hex string or number. */
|
|
44
|
+
background?: string | number;
|
|
45
|
+
/** Metal HDR environment URL or buffer. */
|
|
46
|
+
metalEnvUrl?: string | ArrayBuffer;
|
|
47
|
+
/** Gemstone HDR environment URL or buffer. */
|
|
48
|
+
gemEnvUrl?: string | ArrayBuffer;
|
|
49
|
+
/** Camera field of view. */
|
|
50
|
+
fov?: number;
|
|
51
|
+
/** Enable shadow rendering. */
|
|
52
|
+
shadows?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Init-time viewer options (background, fov, shadows, etc.).
|
|
55
|
+
* Changes after mount are ignored — use dedicated reactive inputs instead.
|
|
56
|
+
*/
|
|
57
|
+
options?: ViewerOptions;
|
|
58
|
+
/**
|
|
59
|
+
* Reactive auto-rotation toggle. Calls startRotation() / stopRotation() on change.
|
|
60
|
+
* Overrides the autoRotate flag in `options` after initialization.
|
|
61
|
+
*/
|
|
62
|
+
autoRotate?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Reactive render quality. Calls setQuality() on change.
|
|
65
|
+
* Overrides the quality flag in `options` after initialization.
|
|
66
|
+
*/
|
|
67
|
+
quality?: 'low' | 'medium' | 'high';
|
|
68
|
+
/**
|
|
69
|
+
* Full viewer state object. When changed, calls viewer.setState() — a COMPLETE
|
|
70
|
+
* replace of metalColor, stoneColor, camera, and part overrides. Not a merge.
|
|
71
|
+
* Takes precedence over individual metalColor / stoneColor inputs.
|
|
72
|
+
*/
|
|
73
|
+
state?: ViewerState;
|
|
74
|
+
/** Emits classified part list (with attached .materials) when model finishes loading. */
|
|
75
|
+
loaded: EventEmitter<PartInfo[] & {
|
|
76
|
+
parts: PartInfo[];
|
|
77
|
+
materials: MaterialSlotInfo[];
|
|
78
|
+
}>;
|
|
79
|
+
/** Emits { parts, materials } when model finishes loading. */
|
|
80
|
+
modelLoaded: EventEmitter<{
|
|
81
|
+
parts: PartInfo[];
|
|
82
|
+
materials: MaterialSlotInfo[];
|
|
83
|
+
}>;
|
|
84
|
+
/** Emits loading progress 0-1. $event = number */
|
|
85
|
+
progress: EventEmitter<number>;
|
|
86
|
+
/** Emits clicked part info and slot metadata. */
|
|
87
|
+
partSelected: EventEmitter<{
|
|
88
|
+
meshId: string;
|
|
89
|
+
partId?: string;
|
|
90
|
+
type: PartType;
|
|
91
|
+
slotIndex?: number;
|
|
92
|
+
slotId?: string;
|
|
93
|
+
materialName?: string;
|
|
94
|
+
}>;
|
|
95
|
+
/** Emits Error when model loading fails. */
|
|
96
|
+
error: EventEmitter<Error>;
|
|
97
|
+
/**
|
|
98
|
+
* Emits full ViewerState on every metal/stone/camera change.
|
|
99
|
+
* Use for persistence, undo history, or sharing a viewer URL.
|
|
100
|
+
* Note: OrbitControls dragging emits state updates continuously.
|
|
101
|
+
*/
|
|
102
|
+
change: EventEmitter<ViewerState>;
|
|
103
|
+
private containerRef;
|
|
104
|
+
private viewer;
|
|
105
|
+
private abortCtrl;
|
|
106
|
+
private initRafId;
|
|
107
|
+
/**
|
|
108
|
+
* Source received before viewer is initialized. Applied in ngAfterViewInit.
|
|
109
|
+
* Needed because ngOnChanges fires before ngAfterViewInit on first render.
|
|
110
|
+
*/
|
|
111
|
+
private pendingSource;
|
|
112
|
+
/** Direct access to underlying @3d-viewer/core instance (null before mount/after destroy). */
|
|
113
|
+
getViewer(): Viewer | null;
|
|
114
|
+
/** Apply bulk or pinpoint material slot color override. */
|
|
115
|
+
setMaterialColor(slotIdOrName: string, colorOrPresetId: string): void;
|
|
116
|
+
/** Apply part color override. */
|
|
117
|
+
setPartColor(partIdOrMeshId: string, colorOrPresetId: string, slotIndex?: number): void;
|
|
118
|
+
/** Clear override for a material slot. */
|
|
119
|
+
clearMaterialColor(slotIdOrName: string): void;
|
|
120
|
+
/** Clear override for a part. */
|
|
121
|
+
clearPartColor(partIdOrMeshId: string, slotIndex?: number): void;
|
|
122
|
+
/** Reset all material and part color overrides back to global defaults. */
|
|
123
|
+
clearOverrides(): void;
|
|
124
|
+
/** Get detected material slots from loaded model. */
|
|
125
|
+
getMaterials(): MaterialSlotInfo[];
|
|
126
|
+
/** Get detected parts from loaded model. */
|
|
127
|
+
getParts(): PartInfo[];
|
|
128
|
+
ngAfterViewInit(): void;
|
|
129
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
130
|
+
ngOnDestroy(): void;
|
|
131
|
+
private _loadSource;
|
|
132
|
+
private _isSameSource;
|
|
133
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ViewerComponent, never>;
|
|
134
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ViewerComponent, "td-viewer", never, { "src": { "alias": "src"; "required": false; }; "source": { "alias": "source"; "required": false; }; "metalColor": { "alias": "metalColor"; "required": false; }; "stoneColor": { "alias": "stoneColor"; "required": false; }; "materialColors": { "alias": "materialColors"; "required": false; }; "partColors": { "alias": "partColors"; "required": false; }; "height": { "alias": "height"; "required": false; }; "minHeight": { "alias": "minHeight"; "required": false; }; "background": { "alias": "background"; "required": false; }; "metalEnvUrl": { "alias": "metalEnvUrl"; "required": false; }; "gemEnvUrl": { "alias": "gemEnvUrl"; "required": false; }; "fov": { "alias": "fov"; "required": false; }; "shadows": { "alias": "shadows"; "required": false; }; "options": { "alias": "options"; "required": false; }; "autoRotate": { "alias": "autoRotate"; "required": false; }; "quality": { "alias": "quality"; "required": false; }; "state": { "alias": "state"; "required": false; }; }, { "loaded": "loaded"; "modelLoaded": "modelLoaded"; "progress": "progress"; "partSelected": "partSelected"; "error": "error"; "change": "change"; }, never, never, true, never>;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=viewer.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.component.d.ts","sourceRoot":"","sources":["../src/viewer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAGZ,SAAS,EACT,aAAa,EACb,SAAS,EACT,aAAa,EAGd,MAAM,eAAe,CAAA;AACtB,OAAO,EAGL,KAAK,MAAM,EAEX,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,gBAAgB,EAEtB,MAAM,mCAAmC,CAAA;;AAE1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAca,eAAgB,YAAW,aAAa,EAAE,SAAS,EAAE,SAAS;IAIzE,gFAAgF;IACvE,GAAG,CAAC,EAAE,MAAM,CAAA;IAErB,yFAAyF;IAChF,MAAM,EAAE,iBAAiB,CAAO;IAEzC,+DAA+D;IACtD,UAAU,CAAC,EAAE,cAAc,CAAA;IAEpC,+DAA+D;IACtD,UAAU,CAAC,EAAE,cAAc,CAAA;IAEpC,wEAAwE;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEhD,0EAA0E;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE5C,uFAAuF;IAC9E,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAEjC,8CAA8C;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAEpC,IACI,UAAU,IAAI,MAAM,GAAG,SAAS,CAGnC;IAED,IACI,aAAa,IAAI,MAAM,GAAG,SAAS,CAGtC;IAED,gDAAgD;IACvC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAErC,2CAA2C;IAClC,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAE3C,8CAA8C;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAEzC,4BAA4B;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IAErB,+BAA+B;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IAE1B;;;OAGG;IACM,OAAO,CAAC,EAAE,aAAa,CAAA;IAEhC;;;OAGG;IACM,UAAU,CAAC,EAAE,OAAO,CAAA;IAE7B;;;OAGG;IACM,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;IAE5C;;;;OAIG;IACM,KAAK,CAAC,EAAE,WAAW,CAAA;IAI5B,yFAAyF;IAC/E,MAAM;eAA0C,QAAQ,EAAE;mBAAa,gBAAgB,EAAE;OAAK;IAExG,8DAA8D;IACpD,WAAW;eAA6B,QAAQ,EAAE;mBAAa,gBAAgB,EAAE;OAAK;IAEhG,kDAAkD;IACxC,QAAQ,uBAA6B;IAE/C,iDAAiD;IACvC,YAAY;gBACZ,MAAM;iBACL,MAAM;cACT,QAAQ;oBACF,MAAM;iBACT,MAAM;uBACA,MAAM;OACnB;IAEJ,4CAA4C;IAClC,KAAK,sBAA4B;IAE3C;;;;OAIG;IACO,MAAM,4BAAkC;IAI1B,OAAO,CAAC,YAAY,CAA6B;IAEzE,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAAsB;IAEvC;;;OAGG;IACH,OAAO,CAAC,aAAa,CAA0B;IAI/C,8FAA8F;IAC9F,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B,2DAA2D;IAC3D,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAIrE,iCAAiC;IACjC,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAIvF,0CAA0C;IAC1C,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAI9C,iCAAiC;IACjC,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAIhE,2EAA2E;IAC3E,cAAc,IAAI,IAAI;IAItB,qDAAqD;IACrD,YAAY,IAAI,gBAAgB,EAAE;IAIlC,4CAA4C;IAC5C,QAAQ,IAAI,QAAQ,EAAE;IAMtB,eAAe,IAAI,IAAI;IAkEvB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAwEzC,WAAW,IAAI,IAAI;IAYnB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,aAAa;yCA/UV,eAAe;2CAAf,eAAe;CA0V3B"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, HostBinding, } from '@angular/core';
|
|
2
|
+
import { createViewer, normalizeModelSource, } from '@thinkersteps_labs/3d-viewer-core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Angular wrapper for @3d-viewer/core.
|
|
6
|
+
*
|
|
7
|
+
* Usage (standalone):
|
|
8
|
+
* import { ViewerComponent } from '@thinkersteps_labs/3d-viewer-angular'
|
|
9
|
+
*
|
|
10
|
+
* Usage (NgModule):
|
|
11
|
+
* import { ViewerModule } from '@thinkersteps_labs/3d-viewer-angular'
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```html
|
|
15
|
+
* <td-viewer
|
|
16
|
+
* [src]="'/models/ring.glb'"
|
|
17
|
+
* [metalColor]="'yellow-gold-18k'"
|
|
18
|
+
* [stoneColor]="'diamond-d'"
|
|
19
|
+
* (loaded)="onLoaded($event)"
|
|
20
|
+
* (error)="onError($event)"
|
|
21
|
+
* ></td-viewer>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class ViewerComponent {
|
|
25
|
+
constructor() {
|
|
26
|
+
/** The 3D model to load. Supports URL string, ModelSource payload, or null to unload. */
|
|
27
|
+
this.source = null;
|
|
28
|
+
// ── Outputs ───────────────────────────────────────────────────────────────
|
|
29
|
+
/** Emits classified part list (with attached .materials) when model finishes loading. */
|
|
30
|
+
this.loaded = new EventEmitter();
|
|
31
|
+
/** Emits { parts, materials } when model finishes loading. */
|
|
32
|
+
this.modelLoaded = new EventEmitter();
|
|
33
|
+
/** Emits loading progress 0-1. $event = number */
|
|
34
|
+
this.progress = new EventEmitter();
|
|
35
|
+
/** Emits clicked part info and slot metadata. */
|
|
36
|
+
this.partSelected = new EventEmitter();
|
|
37
|
+
/** Emits Error when model loading fails. */
|
|
38
|
+
this.error = new EventEmitter();
|
|
39
|
+
/**
|
|
40
|
+
* Emits full ViewerState on every metal/stone/camera change.
|
|
41
|
+
* Use for persistence, undo history, or sharing a viewer URL.
|
|
42
|
+
* Note: OrbitControls dragging emits state updates continuously.
|
|
43
|
+
*/
|
|
44
|
+
this.change = new EventEmitter();
|
|
45
|
+
this.viewer = null;
|
|
46
|
+
this.abortCtrl = null;
|
|
47
|
+
this.initRafId = null;
|
|
48
|
+
/**
|
|
49
|
+
* Source received before viewer is initialized. Applied in ngAfterViewInit.
|
|
50
|
+
* Needed because ngOnChanges fires before ngAfterViewInit on first render.
|
|
51
|
+
*/
|
|
52
|
+
this.pendingSource = null;
|
|
53
|
+
}
|
|
54
|
+
get hostHeight() {
|
|
55
|
+
if (this.height === undefined)
|
|
56
|
+
return undefined;
|
|
57
|
+
return typeof this.height === 'number' ? `${this.height}px` : this.height;
|
|
58
|
+
}
|
|
59
|
+
get hostMinHeight() {
|
|
60
|
+
if (this.minHeight === undefined)
|
|
61
|
+
return undefined;
|
|
62
|
+
return typeof this.minHeight === 'number' ? `${this.minHeight}px` : this.minHeight;
|
|
63
|
+
}
|
|
64
|
+
// ── Public Access ─────────────────────────────────────────────────────────
|
|
65
|
+
/** Direct access to underlying @3d-viewer/core instance (null before mount/after destroy). */
|
|
66
|
+
getViewer() {
|
|
67
|
+
return this.viewer;
|
|
68
|
+
}
|
|
69
|
+
/** Apply bulk or pinpoint material slot color override. */
|
|
70
|
+
setMaterialColor(slotIdOrName, colorOrPresetId) {
|
|
71
|
+
this.viewer?.setMaterialColor(slotIdOrName, colorOrPresetId);
|
|
72
|
+
}
|
|
73
|
+
/** Apply part color override. */
|
|
74
|
+
setPartColor(partIdOrMeshId, colorOrPresetId, slotIndex) {
|
|
75
|
+
this.viewer?.setPartColor(partIdOrMeshId, colorOrPresetId, slotIndex);
|
|
76
|
+
}
|
|
77
|
+
/** Clear override for a material slot. */
|
|
78
|
+
clearMaterialColor(slotIdOrName) {
|
|
79
|
+
this.viewer?.clearMaterialColor(slotIdOrName);
|
|
80
|
+
}
|
|
81
|
+
/** Clear override for a part. */
|
|
82
|
+
clearPartColor(partIdOrMeshId, slotIndex) {
|
|
83
|
+
this.viewer?.clearPartColor(partIdOrMeshId, slotIndex);
|
|
84
|
+
}
|
|
85
|
+
/** Reset all material and part color overrides back to global defaults. */
|
|
86
|
+
clearOverrides() {
|
|
87
|
+
this.viewer?.clearOverrides();
|
|
88
|
+
}
|
|
89
|
+
/** Get detected material slots from loaded model. */
|
|
90
|
+
getMaterials() {
|
|
91
|
+
return this.viewer?.getMaterials() ?? [];
|
|
92
|
+
}
|
|
93
|
+
/** Get detected parts from loaded model. */
|
|
94
|
+
getParts() {
|
|
95
|
+
return this.viewer?.getParts() ?? [];
|
|
96
|
+
}
|
|
97
|
+
// ── Lifecycle ─────────────────────────────────────────────────────────────
|
|
98
|
+
ngAfterViewInit() {
|
|
99
|
+
// requestAnimationFrame ensures the container has real layout dimensions
|
|
100
|
+
// before createViewer initializes the WebGLRenderer (matches AngularJMS pattern).
|
|
101
|
+
this.initRafId = requestAnimationFrame(() => {
|
|
102
|
+
this.initRafId = null;
|
|
103
|
+
const viewerOptions = {
|
|
104
|
+
...this.options,
|
|
105
|
+
...(this.background !== undefined && { background: this.background }),
|
|
106
|
+
...(this.fov !== undefined && { fov: this.fov }),
|
|
107
|
+
...(this.shadows !== undefined && { shadows: this.shadows }),
|
|
108
|
+
...(this.autoRotate !== undefined && { autoRotate: this.autoRotate }),
|
|
109
|
+
...(this.quality !== undefined && { quality: this.quality }),
|
|
110
|
+
...(this.metalEnvUrl !== undefined && { metalEnvUrl: this.metalEnvUrl }),
|
|
111
|
+
...(this.gemEnvUrl !== undefined && { gemEnvUrl: this.gemEnvUrl }),
|
|
112
|
+
};
|
|
113
|
+
this.viewer = createViewer(this.containerRef.nativeElement, viewerOptions);
|
|
114
|
+
this.viewer.on('loaded', ({ parts, materials }) => {
|
|
115
|
+
const payload = Object.assign([...parts], { parts, materials });
|
|
116
|
+
this.loaded.emit(payload);
|
|
117
|
+
this.modelLoaded.emit({ parts, materials });
|
|
118
|
+
});
|
|
119
|
+
this.viewer.on('loading', ({ progress }) => this.progress.emit(progress));
|
|
120
|
+
this.viewer.on('error', (err) => this.error.emit(err));
|
|
121
|
+
this.viewer.on('partSelected', (info) => this.partSelected.emit(info));
|
|
122
|
+
this.viewer.on('change', (state) => this.change.emit(state));
|
|
123
|
+
// Apply initial model source if one was queued.
|
|
124
|
+
const initial = this.src ?? this.source ?? this.pendingSource;
|
|
125
|
+
if (initial) {
|
|
126
|
+
this._loadSource(initial);
|
|
127
|
+
this.pendingSource = null;
|
|
128
|
+
}
|
|
129
|
+
// Precedence: full state snapshot overrides individual color inputs
|
|
130
|
+
if (this.state) {
|
|
131
|
+
this.viewer.setState(this.state);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
if (this.metalColor)
|
|
135
|
+
this.viewer.setMetalColor(this.metalColor);
|
|
136
|
+
if (this.stoneColor)
|
|
137
|
+
this.viewer.setStoneColor(this.stoneColor);
|
|
138
|
+
if (this.materialColors) {
|
|
139
|
+
for (const [key, color] of Object.entries(this.materialColors)) {
|
|
140
|
+
this.viewer.setMaterialColor(key, color);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (this.partColors) {
|
|
144
|
+
for (const [key, color] of Object.entries(this.partColors)) {
|
|
145
|
+
if (key.includes(':')) {
|
|
146
|
+
const [partId, slotIdxStr] = key.split(':');
|
|
147
|
+
const slotIndex = parseInt(slotIdxStr ?? '', 10);
|
|
148
|
+
this.viewer.setPartColor(partId ?? '', color, isNaN(slotIndex) ? undefined : slotIndex);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.viewer.setPartColor(key, color);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (this.autoRotate !== undefined) {
|
|
157
|
+
if (this.autoRotate)
|
|
158
|
+
this.viewer.startRotation();
|
|
159
|
+
else
|
|
160
|
+
this.viewer.stopRotation();
|
|
161
|
+
}
|
|
162
|
+
if (this.quality)
|
|
163
|
+
this.viewer.setQuality(this.quality);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
ngOnChanges(changes) {
|
|
167
|
+
// Guard: viewer is null until ngAfterViewInit + rAF fires.
|
|
168
|
+
if (!this.viewer) {
|
|
169
|
+
if (changes['src'] || changes['source']) {
|
|
170
|
+
this.pendingSource = this.src ?? this.source;
|
|
171
|
+
}
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (changes['src'] || changes['source']) {
|
|
175
|
+
const currentInput = this.src ?? this.source;
|
|
176
|
+
this._loadSource(currentInput);
|
|
177
|
+
}
|
|
178
|
+
// Precedence: if 'state' changed in this cycle, setState handles everything.
|
|
179
|
+
// Individual color inputs in the same cycle are ignored.
|
|
180
|
+
if (changes['state'] && this.state) {
|
|
181
|
+
this.viewer.setState(this.state);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
if (changes['metalColor'] && this.metalColor)
|
|
185
|
+
this.viewer.setMetalColor(this.metalColor);
|
|
186
|
+
if (changes['stoneColor'] && this.stoneColor)
|
|
187
|
+
this.viewer.setStoneColor(this.stoneColor);
|
|
188
|
+
if (changes['materialColors'] && this.viewer) {
|
|
189
|
+
const prev = changes['materialColors'].previousValue ?? {};
|
|
190
|
+
const current = this.materialColors ?? {};
|
|
191
|
+
for (const key of Object.keys(prev)) {
|
|
192
|
+
if (!(key in current)) {
|
|
193
|
+
this.viewer.clearMaterialColor(key);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
for (const [key, color] of Object.entries(current)) {
|
|
197
|
+
if (prev[key] !== color) {
|
|
198
|
+
this.viewer.setMaterialColor(key, color);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (changes['partColors'] && this.viewer) {
|
|
203
|
+
const prev = changes['partColors'].previousValue ?? {};
|
|
204
|
+
const current = this.partColors ?? {};
|
|
205
|
+
for (const key of Object.keys(prev)) {
|
|
206
|
+
if (!(key in current)) {
|
|
207
|
+
if (key.includes(':')) {
|
|
208
|
+
const [partId, slotIdxStr] = key.split(':');
|
|
209
|
+
const slotIndex = parseInt(slotIdxStr ?? '', 10);
|
|
210
|
+
this.viewer.clearPartColor(partId ?? '', isNaN(slotIndex) ? undefined : slotIndex);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
this.viewer.clearPartColor(key);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
for (const [key, color] of Object.entries(current)) {
|
|
218
|
+
if (prev[key] !== color) {
|
|
219
|
+
if (key.includes(':')) {
|
|
220
|
+
const [partId, slotIdxStr] = key.split(':');
|
|
221
|
+
const slotIndex = parseInt(slotIdxStr ?? '', 10);
|
|
222
|
+
this.viewer.setPartColor(partId ?? '', color, isNaN(slotIndex) ? undefined : slotIndex);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
this.viewer.setPartColor(key, color);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (changes['autoRotate'] && this.autoRotate !== undefined) {
|
|
232
|
+
if (this.autoRotate)
|
|
233
|
+
this.viewer.startRotation();
|
|
234
|
+
else
|
|
235
|
+
this.viewer.stopRotation();
|
|
236
|
+
}
|
|
237
|
+
if (changes['quality'] && this.quality)
|
|
238
|
+
this.viewer.setQuality(this.quality);
|
|
239
|
+
}
|
|
240
|
+
ngOnDestroy() {
|
|
241
|
+
if (this.initRafId !== null) {
|
|
242
|
+
cancelAnimationFrame(this.initRafId);
|
|
243
|
+
this.initRafId = null;
|
|
244
|
+
}
|
|
245
|
+
this.abortCtrl?.abort();
|
|
246
|
+
this.viewer?.dispose();
|
|
247
|
+
this.viewer = null;
|
|
248
|
+
}
|
|
249
|
+
// ── Helpers ───────────────────────────────────────────────────────────────
|
|
250
|
+
_loadSource(source) {
|
|
251
|
+
this.abortCtrl?.abort();
|
|
252
|
+
if (!this.viewer)
|
|
253
|
+
return;
|
|
254
|
+
const normalized = normalizeModelSource(source);
|
|
255
|
+
if (!normalized) {
|
|
256
|
+
this.viewer.unload();
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
this.abortCtrl = new AbortController();
|
|
260
|
+
this.viewer.load(normalized, { signal: this.abortCtrl.signal }).catch(() => {
|
|
261
|
+
// Error is emitted via the viewer's 'error' event — no duplicate handling needed.
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
_isSameSource(a, b) {
|
|
265
|
+
if (a === b)
|
|
266
|
+
return true;
|
|
267
|
+
if (!a || !b)
|
|
268
|
+
return false;
|
|
269
|
+
if ('url' in a && 'url' in b) {
|
|
270
|
+
return a.url === b.url && a.format === b.format && a.mtlUrl === b.mtlUrl;
|
|
271
|
+
}
|
|
272
|
+
if ('data' in a && 'data' in b) {
|
|
273
|
+
return a.data === b.data && a.format === b.format;
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
278
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ViewerComponent, isStandalone: true, selector: "td-viewer", inputs: { src: "src", source: "source", metalColor: "metalColor", stoneColor: "stoneColor", materialColors: "materialColors", partColors: "partColors", height: "height", minHeight: "minHeight", background: "background", metalEnvUrl: "metalEnvUrl", gemEnvUrl: "gemEnvUrl", fov: "fov", shadows: "shadows", options: "options", autoRotate: "autoRotate", quality: "quality", state: "state" }, outputs: { loaded: "loaded", modelLoaded: "modelLoaded", progress: "progress", partSelected: "partSelected", error: "error", change: "change" }, host: { properties: { "style.height": "this.hostHeight", "style.minHeight": "this.hostMinHeight" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `<div #container style="width:100%;height:100%;display:block;"></div>`, isInline: true, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n }\n "], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
279
|
+
}
|
|
280
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ViewerComponent, decorators: [{
|
|
281
|
+
type: Component,
|
|
282
|
+
args: [{ selector: 'td-viewer', standalone: true, template: `<div #container style="width:100%;height:100%;display:block;"></div>`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host {\n display: block;\n width: 100%;\n height: 100%;\n position: relative;\n }\n "] }]
|
|
283
|
+
}], propDecorators: { src: [{
|
|
284
|
+
type: Input
|
|
285
|
+
}], source: [{
|
|
286
|
+
type: Input
|
|
287
|
+
}], metalColor: [{
|
|
288
|
+
type: Input
|
|
289
|
+
}], stoneColor: [{
|
|
290
|
+
type: Input
|
|
291
|
+
}], materialColors: [{
|
|
292
|
+
type: Input
|
|
293
|
+
}], partColors: [{
|
|
294
|
+
type: Input
|
|
295
|
+
}], height: [{
|
|
296
|
+
type: Input
|
|
297
|
+
}], minHeight: [{
|
|
298
|
+
type: Input
|
|
299
|
+
}], hostHeight: [{
|
|
300
|
+
type: HostBinding,
|
|
301
|
+
args: ['style.height']
|
|
302
|
+
}], hostMinHeight: [{
|
|
303
|
+
type: HostBinding,
|
|
304
|
+
args: ['style.minHeight']
|
|
305
|
+
}], background: [{
|
|
306
|
+
type: Input
|
|
307
|
+
}], metalEnvUrl: [{
|
|
308
|
+
type: Input
|
|
309
|
+
}], gemEnvUrl: [{
|
|
310
|
+
type: Input
|
|
311
|
+
}], fov: [{
|
|
312
|
+
type: Input
|
|
313
|
+
}], shadows: [{
|
|
314
|
+
type: Input
|
|
315
|
+
}], options: [{
|
|
316
|
+
type: Input
|
|
317
|
+
}], autoRotate: [{
|
|
318
|
+
type: Input
|
|
319
|
+
}], quality: [{
|
|
320
|
+
type: Input
|
|
321
|
+
}], state: [{
|
|
322
|
+
type: Input
|
|
323
|
+
}], loaded: [{
|
|
324
|
+
type: Output
|
|
325
|
+
}], modelLoaded: [{
|
|
326
|
+
type: Output
|
|
327
|
+
}], progress: [{
|
|
328
|
+
type: Output
|
|
329
|
+
}], partSelected: [{
|
|
330
|
+
type: Output
|
|
331
|
+
}], error: [{
|
|
332
|
+
type: Output
|
|
333
|
+
}], change: [{
|
|
334
|
+
type: Output
|
|
335
|
+
}], containerRef: [{
|
|
336
|
+
type: ViewChild,
|
|
337
|
+
args: ['container']
|
|
338
|
+
}] } });
|
|
339
|
+
//# sourceMappingURL=viewer.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.component.js","sourceRoot":"","sources":["../src/viewer.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import * as i1 from "./viewer.component";
|
|
3
|
+
import * as i2 from "./swatches/metal-swatches.component";
|
|
4
|
+
import * as i3 from "./swatches/stone-swatches.component";
|
|
5
|
+
import * as i4 from "./swatches/jewelry-customizer.component";
|
|
6
|
+
/**
|
|
7
|
+
* Import this module in NgModule-based Angular apps (Angular 18 style, like AngularJMS).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { ViewerModule } from '@thinkersteps_labs/3d-viewer-angular'
|
|
12
|
+
*
|
|
13
|
+
* @NgModule({ imports: [ViewerModule] })
|
|
14
|
+
* export class YourFeatureModule {}
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare class ViewerModule {
|
|
18
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ViewerModule, never>;
|
|
19
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<ViewerModule, never, [typeof i1.ViewerComponent, typeof i2.MetalSwatchesComponent, typeof i2.MetalSelectComponent, typeof i3.StoneSwatchesComponent, typeof i3.StoneSelectComponent, typeof i4.JewelryCustomizerComponent], [typeof i1.ViewerComponent, typeof i2.MetalSwatchesComponent, typeof i2.MetalSelectComponent, typeof i3.StoneSwatchesComponent, typeof i3.StoneSelectComponent, typeof i4.JewelryCustomizerComponent]>;
|
|
20
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<ViewerModule>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=viewer.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.module.d.ts","sourceRoot":"","sources":["../src/viewer.module.ts"],"names":[],"mappings":";;;;;AAeA;;;;;;;;;;GAUG;AACH,qBAIa,YAAY;yCAAZ,YAAY;0CAAZ,YAAY;0CAAZ,YAAY;CAAI"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { ViewerComponent } from './viewer.component';
|
|
3
|
+
import { MetalSwatchesComponent, MetalSelectComponent } from './swatches/metal-swatches.component';
|
|
4
|
+
import { StoneSwatchesComponent, StoneSelectComponent } from './swatches/stone-swatches.component';
|
|
5
|
+
import { JewelryCustomizerComponent } from './swatches/jewelry-customizer.component';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
const COMPONENTS = [
|
|
8
|
+
ViewerComponent,
|
|
9
|
+
MetalSwatchesComponent,
|
|
10
|
+
MetalSelectComponent,
|
|
11
|
+
StoneSwatchesComponent,
|
|
12
|
+
StoneSelectComponent,
|
|
13
|
+
JewelryCustomizerComponent,
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Import this module in NgModule-based Angular apps (Angular 18 style, like AngularJMS).
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { ViewerModule } from '@thinkersteps_labs/3d-viewer-angular'
|
|
21
|
+
*
|
|
22
|
+
* @NgModule({ imports: [ViewerModule] })
|
|
23
|
+
* export class YourFeatureModule {}
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class ViewerModule {
|
|
27
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ViewerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
28
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ViewerModule, imports: [ViewerComponent,
|
|
29
|
+
MetalSwatchesComponent,
|
|
30
|
+
MetalSelectComponent,
|
|
31
|
+
StoneSwatchesComponent,
|
|
32
|
+
StoneSelectComponent,
|
|
33
|
+
JewelryCustomizerComponent], exports: [ViewerComponent,
|
|
34
|
+
MetalSwatchesComponent,
|
|
35
|
+
MetalSelectComponent,
|
|
36
|
+
StoneSwatchesComponent,
|
|
37
|
+
StoneSelectComponent,
|
|
38
|
+
JewelryCustomizerComponent] }); }
|
|
39
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ViewerModule, imports: [MetalSwatchesComponent,
|
|
40
|
+
MetalSelectComponent,
|
|
41
|
+
StoneSwatchesComponent,
|
|
42
|
+
StoneSelectComponent,
|
|
43
|
+
JewelryCustomizerComponent] }); }
|
|
44
|
+
}
|
|
45
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ViewerModule, decorators: [{
|
|
46
|
+
type: NgModule,
|
|
47
|
+
args: [{
|
|
48
|
+
imports: [...COMPONENTS],
|
|
49
|
+
exports: [...COMPONENTS],
|
|
50
|
+
}]
|
|
51
|
+
}] });
|
|
52
|
+
//# sourceMappingURL=viewer.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer.module.js","sourceRoot":"","sources":["../src/viewer.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAA;AAClG,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAA;AAClG,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAA;;AAEpF,MAAM,UAAU,GAAG;IACjB,eAAe;IACf,sBAAsB;IACtB,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,0BAA0B;CAC3B,CAAA;AAED;;;;;;;;;;GAUG;AAKH,MAAM,OAAO,YAAY;+GAAZ,YAAY;gHAAZ,YAAY,YAvBvB,eAAe;YACf,sBAAsB;YACtB,oBAAoB;YACpB,sBAAsB;YACtB,oBAAoB;YACpB,0BAA0B,aAL1B,eAAe;YACf,sBAAsB;YACtB,oBAAoB;YACpB,sBAAsB;YACtB,oBAAoB;YACpB,0BAA0B;gHAkBf,YAAY,YAtBvB,sBAAsB;YACtB,oBAAoB;YACpB,sBAAsB;YACtB,oBAAoB;YACpB,0BAA0B;;4FAkBf,YAAY;kBAJxB,QAAQ;mBAAC;oBACR,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC;oBACxB,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC;iBACzB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thinkersteps_labs/3d-viewer-angular",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/lalitthinker/3d-jewelry-viewer.git",
|
|
8
|
+
"directory": "packages/angular"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@angular/common": ">=18.0.0",
|
|
29
|
+
"@angular/core": ">=18.0.0",
|
|
30
|
+
"three": ">=0.150.0",
|
|
31
|
+
"@thinkersteps_labs/3d-viewer-core": "1.0.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@angular/common": "^18.2.0",
|
|
35
|
+
"@angular/compiler": "^18.2.0",
|
|
36
|
+
"@angular/compiler-cli": "^18.2.0",
|
|
37
|
+
"@angular/core": "^18.2.0",
|
|
38
|
+
"@angular/platform-browser": "^18.2.0",
|
|
39
|
+
"@types/node": "^20.11.0",
|
|
40
|
+
"rxjs": "^7.8.0",
|
|
41
|
+
"three": "^0.160.0",
|
|
42
|
+
"typescript": "~5.5.4",
|
|
43
|
+
"zone.js": "^0.14.0",
|
|
44
|
+
"@thinkersteps_labs/3d-viewer-core": "1.0.1"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "ngc -p tsconfig.json",
|
|
48
|
+
"typecheck": "tsc --noEmit"
|
|
49
|
+
}
|
|
6
50
|
}
|