@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
package/README.md
CHANGED
|
@@ -1,3 +1,107 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @thinkersteps_labs/3d-viewer-angular
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official Angular component wrapper for `@thinkersteps_labs/3d-viewer-core`. Renders photorealistic 3D jewelry and customizer canvases in Angular 18+ applications (including standalone components and legacy `NgModule` architectures).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @thinkersteps_labs/3d-viewer-angular @thinkersteps_labs/3d-viewer-core three
|
|
11
|
+
# or with npm
|
|
12
|
+
npm install @thinkersteps_labs/3d-viewer-angular @thinkersteps_labs/3d-viewer-core three
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
> **Peer Dependencies**: Requires `@angular/core >= 18.0.0` and `three >= 0.150.0`.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. Turnkey Customizer (`<td-jewelry-customizer>`)
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { Component } from '@angular/core'
|
|
23
|
+
import { JewelryCustomizerComponent } from '@thinkersteps_labs/3d-viewer-angular'
|
|
24
|
+
|
|
25
|
+
@Component({
|
|
26
|
+
selector: 'app-product-page',
|
|
27
|
+
standalone: true,
|
|
28
|
+
imports: [JewelryCustomizerComponent],
|
|
29
|
+
template: `
|
|
30
|
+
<td-jewelry-customizer
|
|
31
|
+
[src]="'https://cdn.example.com/models/solitaire-ring.glb'"
|
|
32
|
+
[(metal)]="activeMetal"
|
|
33
|
+
[(stone)]="activeStone"
|
|
34
|
+
[height]="520"
|
|
35
|
+
[autoRotate]="true"
|
|
36
|
+
></td-jewelry-customizer>
|
|
37
|
+
`
|
|
38
|
+
})
|
|
39
|
+
export class ProductPageComponent {
|
|
40
|
+
activeMetal = 'yellow-gold-18k'
|
|
41
|
+
activeStone = 'diamond-d'
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 2. Composable Primitives (`<td-viewer>` + Swatches)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { Component } from '@angular/core'
|
|
51
|
+
import {
|
|
52
|
+
ViewerComponent,
|
|
53
|
+
MetalSwatchesComponent,
|
|
54
|
+
StoneSwatchesComponent,
|
|
55
|
+
type MetalColorProp,
|
|
56
|
+
type StoneColorProp,
|
|
57
|
+
} from '@thinkersteps_labs/3d-viewer-angular'
|
|
58
|
+
|
|
59
|
+
@Component({
|
|
60
|
+
selector: 'app-product-detail',
|
|
61
|
+
standalone: true,
|
|
62
|
+
imports: [ViewerComponent, MetalSwatchesComponent, StoneSwatchesComponent],
|
|
63
|
+
template: `
|
|
64
|
+
<div style="max-width: 840px; margin: 0 auto;">
|
|
65
|
+
<td-viewer
|
|
66
|
+
[src]="modelUrl"
|
|
67
|
+
[metalColor]="activeMetal"
|
|
68
|
+
[stoneColor]="activeStone"
|
|
69
|
+
[height]="500"
|
|
70
|
+
[autoRotate]="true"
|
|
71
|
+
></td-viewer>
|
|
72
|
+
|
|
73
|
+
<div style="margin-top: 16px; display: flex; flex-direction: column; gap: 14px;">
|
|
74
|
+
<td-metal-swatches [(value)]="activeMetal" [variant]="'pills'"></td-metal-swatches>
|
|
75
|
+
<td-stone-swatches [(value)]="activeStone" [variant]="'pills'"></td-stone-swatches>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
`
|
|
79
|
+
})
|
|
80
|
+
export class ProductDetailComponent {
|
|
81
|
+
modelUrl = 'https://cdn.example.com/models/solitaire-ring.glb'
|
|
82
|
+
activeMetal: MetalColorProp = 'yellow-gold-18k'
|
|
83
|
+
activeStone: StoneColorProp = 'diamond-d'
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 3. NgModule Apps (e.g. Angular ERP)
|
|
90
|
+
|
|
91
|
+
Import `ViewerModule` in your feature module to get access to `<td-viewer>`, `<td-metal-swatches>`, `<td-stone-swatches>`, and `<td-jewelry-customizer>`:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { NgModule } from '@angular/core'
|
|
95
|
+
import { ViewerModule } from '@thinkersteps_labs/3d-viewer-angular'
|
|
96
|
+
|
|
97
|
+
@NgModule({
|
|
98
|
+
imports: [ViewerModule],
|
|
99
|
+
})
|
|
100
|
+
export class ProductModule {}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { ViewerComponent } from './viewer.component';
|
|
2
|
+
export { ViewerModule } from './viewer.module';
|
|
3
|
+
export { MetalSwatchesComponent, MetalSelectComponent, } from './swatches/metal-swatches.component';
|
|
4
|
+
export { StoneSwatchesComponent, StoneSelectComponent, } from './swatches/stone-swatches.component';
|
|
5
|
+
export { JewelryCustomizerComponent, } from './swatches/jewelry-customizer.component';
|
|
6
|
+
export { CANONICAL_METAL_PRESETS, CANONICAL_STONE_PRESETS, METAL_PRESETS, STONE_PRESETS, PHYSICALLY_BASED_METAL_PRESETS, DIAMOND_PRESETS, GEMSTONE_PRESETS, ALL_METAL_PRESETS, ALL_STONE_PRESETS, getMetalPreset, getStonePreset, normalizeModelSource, inferFormatFromUrl, } from '@thinkersteps_labs/3d-viewer-core';
|
|
7
|
+
export type { MetalPreset, StonePreset, StandardMetalId, StandardStoneId, MetalColorProp, StoneColorProp, ModelSource, ViewerSourceInput, ViewerOptions, ViewerState, PartInfo, PartType, MaterialSlotInfo, MeshMaterialSlot, StateRestoreResult, Viewer, } from '@thinkersteps_labs/3d-viewer-core';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,0BAA0B,GAC3B,MAAM,yCAAyC,CAAA;AAGhD,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,aAAa,EACb,8BAA8B,EAC9B,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,mCAAmC,CAAA;AAE1C,YAAY,EACV,WAAW,EACX,WAAW,EACX,eAAe,EACf,eAAe,EACf,cAAc,EACd,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,GACP,MAAM,mCAAmC,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { ViewerComponent } from './viewer.component';
|
|
2
|
+
export { ViewerModule } from './viewer.module';
|
|
3
|
+
export { MetalSwatchesComponent, MetalSelectComponent, } from './swatches/metal-swatches.component';
|
|
4
|
+
export { StoneSwatchesComponent, StoneSelectComponent, } from './swatches/stone-swatches.component';
|
|
5
|
+
export { JewelryCustomizerComponent, } from './swatches/jewelry-customizer.component';
|
|
6
|
+
// Convenience re-exports — Angular consumers can import everything from one place.
|
|
7
|
+
export { CANONICAL_METAL_PRESETS, CANONICAL_STONE_PRESETS, METAL_PRESETS, STONE_PRESETS, PHYSICALLY_BASED_METAL_PRESETS, DIAMOND_PRESETS, GEMSTONE_PRESETS, ALL_METAL_PRESETS, ALL_STONE_PRESETS, getMetalPreset, getStonePreset, normalizeModelSource, inferFormatFromUrl, } from '@thinkersteps_labs/3d-viewer-core';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,EACL,0BAA0B,GAC3B,MAAM,yCAAyC,CAAA;AAEhD,mFAAmF;AACnF,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,aAAa,EACb,aAAa,EACb,8BAA8B,EAC9B,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,mCAAmC,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import { type MetalPreset, type StonePreset, type MetalColorProp, type StoneColorProp, type ViewerSourceInput, type PartInfo, type PartType } from '@thinkersteps_labs/3d-viewer-core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class JewelryCustomizerComponent {
|
|
5
|
+
src?: string;
|
|
6
|
+
source?: ViewerSourceInput;
|
|
7
|
+
metal: MetalColorProp;
|
|
8
|
+
metalChange: EventEmitter<string>;
|
|
9
|
+
stone: StoneColorProp;
|
|
10
|
+
stoneChange: EventEmitter<string>;
|
|
11
|
+
height: number | string;
|
|
12
|
+
autoRotate: boolean;
|
|
13
|
+
quality: 'low' | 'medium' | 'high';
|
|
14
|
+
controlsVariant: 'pills' | 'dots' | 'select' | 'none';
|
|
15
|
+
metalOptions: MetalPreset[];
|
|
16
|
+
stoneOptions: StonePreset[];
|
|
17
|
+
loaded: EventEmitter<PartInfo[]>;
|
|
18
|
+
partSelected: EventEmitter<{
|
|
19
|
+
meshId: string;
|
|
20
|
+
type: PartType;
|
|
21
|
+
}>;
|
|
22
|
+
get buttonVariant(): 'pills' | 'dots';
|
|
23
|
+
get formattedHeight(): string;
|
|
24
|
+
onMetalChange(val: string): void;
|
|
25
|
+
onStoneChange(val: string): void;
|
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<JewelryCustomizerComponent, never>;
|
|
27
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<JewelryCustomizerComponent, "td-jewelry-customizer", never, { "src": { "alias": "src"; "required": false; }; "source": { "alias": "source"; "required": false; }; "metal": { "alias": "metal"; "required": false; }; "stone": { "alias": "stone"; "required": false; }; "height": { "alias": "height"; "required": false; }; "autoRotate": { "alias": "autoRotate"; "required": false; }; "quality": { "alias": "quality"; "required": false; }; "controlsVariant": { "alias": "controlsVariant"; "required": false; }; "metalOptions": { "alias": "metalOptions"; "required": false; }; "stoneOptions": { "alias": "stoneOptions"; "required": false; }; }, { "metalChange": "metalChange"; "stoneChange": "stoneChange"; "loaded": "loaded"; "partSelected": "partSelected"; }, never, never, true, never>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=jewelry-customizer.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jewelry-customizer.component.d.ts","sourceRoot":"","sources":["../../src/swatches/jewelry-customizer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAEb,MAAM,eAAe,CAAA;AAEtB,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACd,MAAM,mCAAmC,CAAA;;AAkC1C,qBA4Da,0BAA0B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,KAAK,EAAE,cAAc,CAAoB;IACxC,WAAW,uBAA6B;IAEzC,KAAK,EAAE,cAAc,CAAc;IAClC,WAAW,uBAA6B;IAEzC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM;IAC7B,UAAU,UAAO;IACjB,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAS;IAC3C,eAAe,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAU;IAE/D,YAAY,EAAE,WAAW,EAAE,CAA0B;IACrD,YAAY,EAAE,WAAW,EAAE,CAA0B;IAEpD,MAAM,2BAAiC;IACvC,YAAY;gBAA8B,MAAM;cAAQ,QAAQ;OAAK;IAE/E,IAAI,aAAa,IAAI,OAAO,GAAG,MAAM,CAEpC;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKhC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;yCAjCrB,0BAA0B;2CAA1B,0BAA0B;CAqCtC"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { CANONICAL_METAL_PRESETS, CANONICAL_STONE_PRESETS, } from '@thinkersteps_labs/3d-viewer-core';
|
|
4
|
+
import { ViewerComponent } from '../viewer.component';
|
|
5
|
+
import { MetalSwatchesComponent, MetalSelectComponent } from './metal-swatches.component';
|
|
6
|
+
import { StoneSwatchesComponent, StoneSelectComponent } from './stone-swatches.component';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/common";
|
|
9
|
+
const CUSTOMIZER_STYLES = `
|
|
10
|
+
:host {
|
|
11
|
+
display: block;
|
|
12
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
|
|
13
|
+
}
|
|
14
|
+
.td-customizer-card {
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
gap: 16px;
|
|
18
|
+
background: #ffffff;
|
|
19
|
+
border-radius: 16px;
|
|
20
|
+
border: 1px solid #e2e8f0;
|
|
21
|
+
padding: 16px;
|
|
22
|
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
|
|
23
|
+
}
|
|
24
|
+
.td-customizer-viewport {
|
|
25
|
+
position: relative;
|
|
26
|
+
width: 100%;
|
|
27
|
+
border-radius: 12px;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
background: #f8fafc;
|
|
30
|
+
}
|
|
31
|
+
.td-customizer-controls {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
gap: 14px;
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
export class JewelryCustomizerComponent {
|
|
38
|
+
constructor() {
|
|
39
|
+
this.metal = 'yellow-gold-18k';
|
|
40
|
+
this.metalChange = new EventEmitter();
|
|
41
|
+
this.stone = 'diamond-d';
|
|
42
|
+
this.stoneChange = new EventEmitter();
|
|
43
|
+
this.height = 520;
|
|
44
|
+
this.autoRotate = true;
|
|
45
|
+
this.quality = 'high';
|
|
46
|
+
this.controlsVariant = 'pills';
|
|
47
|
+
this.metalOptions = CANONICAL_METAL_PRESETS;
|
|
48
|
+
this.stoneOptions = CANONICAL_STONE_PRESETS;
|
|
49
|
+
this.loaded = new EventEmitter();
|
|
50
|
+
this.partSelected = new EventEmitter();
|
|
51
|
+
}
|
|
52
|
+
get buttonVariant() {
|
|
53
|
+
return this.controlsVariant === 'dots' ? 'dots' : 'pills';
|
|
54
|
+
}
|
|
55
|
+
get formattedHeight() {
|
|
56
|
+
return typeof this.height === 'number' ? `${this.height}px` : this.height;
|
|
57
|
+
}
|
|
58
|
+
onMetalChange(val) {
|
|
59
|
+
this.metal = val;
|
|
60
|
+
this.metalChange.emit(val);
|
|
61
|
+
}
|
|
62
|
+
onStoneChange(val) {
|
|
63
|
+
this.stone = val;
|
|
64
|
+
this.stoneChange.emit(val);
|
|
65
|
+
}
|
|
66
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: JewelryCustomizerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
67
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: JewelryCustomizerComponent, isStandalone: true, selector: "td-jewelry-customizer", inputs: { src: "src", source: "source", metal: "metal", stone: "stone", height: "height", autoRotate: "autoRotate", quality: "quality", controlsVariant: "controlsVariant", metalOptions: "metalOptions", stoneOptions: "stoneOptions" }, outputs: { metalChange: "metalChange", stoneChange: "stoneChange", loaded: "loaded", partSelected: "partSelected" }, ngImport: i0, template: `
|
|
68
|
+
<div class="td-customizer-card">
|
|
69
|
+
<div class="td-customizer-viewport" [style.height]="formattedHeight">
|
|
70
|
+
<td-viewer
|
|
71
|
+
[src]="src"
|
|
72
|
+
[source]="source"
|
|
73
|
+
[metalColor]="metal"
|
|
74
|
+
[stoneColor]="stone"
|
|
75
|
+
[autoRotate]="autoRotate"
|
|
76
|
+
[quality]="quality"
|
|
77
|
+
(loaded)="loaded.emit($event)"
|
|
78
|
+
(partSelected)="partSelected.emit($event)"
|
|
79
|
+
></td-viewer>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class="td-customizer-controls" *ngIf="controlsVariant !== 'none'">
|
|
83
|
+
<ng-container *ngIf="controlsVariant === 'select'; else buttonSwatches">
|
|
84
|
+
<td-metal-select
|
|
85
|
+
[value]="metal"
|
|
86
|
+
(valueChange)="onMetalChange($event)"
|
|
87
|
+
[options]="metalOptions"
|
|
88
|
+
></td-metal-select>
|
|
89
|
+
<td-stone-select
|
|
90
|
+
[value]="stone"
|
|
91
|
+
(valueChange)="onStoneChange($event)"
|
|
92
|
+
[options]="stoneOptions"
|
|
93
|
+
></td-stone-select>
|
|
94
|
+
</ng-container>
|
|
95
|
+
|
|
96
|
+
<ng-template #buttonSwatches>
|
|
97
|
+
<td-metal-swatches
|
|
98
|
+
[value]="metal"
|
|
99
|
+
(valueChange)="onMetalChange($event)"
|
|
100
|
+
[options]="metalOptions"
|
|
101
|
+
[variant]="buttonVariant"
|
|
102
|
+
></td-metal-swatches>
|
|
103
|
+
<td-stone-swatches
|
|
104
|
+
[value]="stone"
|
|
105
|
+
(valueChange)="onStoneChange($event)"
|
|
106
|
+
[options]="stoneOptions"
|
|
107
|
+
[variant]="buttonVariant"
|
|
108
|
+
></td-stone-swatches>
|
|
109
|
+
</ng-template>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
`, isInline: true, styles: ["\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n .td-customizer-card {\n display: flex;\n flex-direction: column;\n gap: 16px;\n background: #ffffff;\n border-radius: 16px;\n border: 1px solid #e2e8f0;\n padding: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);\n }\n .td-customizer-viewport {\n position: relative;\n width: 100%;\n border-radius: 12px;\n overflow: hidden;\n background: #f8fafc;\n }\n .td-customizer-controls {\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ViewerComponent, selector: "td-viewer", inputs: ["src", "source", "metalColor", "stoneColor", "materialColors", "partColors", "height", "minHeight", "background", "metalEnvUrl", "gemEnvUrl", "fov", "shadows", "options", "autoRotate", "quality", "state"], outputs: ["loaded", "modelLoaded", "progress", "partSelected", "error", "change"] }, { kind: "component", type: MetalSwatchesComponent, selector: "td-metal-swatches", inputs: ["value", "options", "category", "variant", "showLabel"], outputs: ["valueChange"] }, { kind: "component", type: MetalSelectComponent, selector: "td-metal-select", inputs: ["value", "options", "label"], outputs: ["valueChange"] }, { kind: "component", type: StoneSwatchesComponent, selector: "td-stone-swatches", inputs: ["value", "options", "category", "variant", "showLabel"], outputs: ["valueChange"] }, { kind: "component", type: StoneSelectComponent, selector: "td-stone-select", inputs: ["value", "options", "label"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
113
|
+
}
|
|
114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: JewelryCustomizerComponent, decorators: [{
|
|
115
|
+
type: Component,
|
|
116
|
+
args: [{ selector: 'td-jewelry-customizer', standalone: true, imports: [
|
|
117
|
+
CommonModule,
|
|
118
|
+
ViewerComponent,
|
|
119
|
+
MetalSwatchesComponent,
|
|
120
|
+
MetalSelectComponent,
|
|
121
|
+
StoneSwatchesComponent,
|
|
122
|
+
StoneSelectComponent,
|
|
123
|
+
], template: `
|
|
124
|
+
<div class="td-customizer-card">
|
|
125
|
+
<div class="td-customizer-viewport" [style.height]="formattedHeight">
|
|
126
|
+
<td-viewer
|
|
127
|
+
[src]="src"
|
|
128
|
+
[source]="source"
|
|
129
|
+
[metalColor]="metal"
|
|
130
|
+
[stoneColor]="stone"
|
|
131
|
+
[autoRotate]="autoRotate"
|
|
132
|
+
[quality]="quality"
|
|
133
|
+
(loaded)="loaded.emit($event)"
|
|
134
|
+
(partSelected)="partSelected.emit($event)"
|
|
135
|
+
></td-viewer>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="td-customizer-controls" *ngIf="controlsVariant !== 'none'">
|
|
139
|
+
<ng-container *ngIf="controlsVariant === 'select'; else buttonSwatches">
|
|
140
|
+
<td-metal-select
|
|
141
|
+
[value]="metal"
|
|
142
|
+
(valueChange)="onMetalChange($event)"
|
|
143
|
+
[options]="metalOptions"
|
|
144
|
+
></td-metal-select>
|
|
145
|
+
<td-stone-select
|
|
146
|
+
[value]="stone"
|
|
147
|
+
(valueChange)="onStoneChange($event)"
|
|
148
|
+
[options]="stoneOptions"
|
|
149
|
+
></td-stone-select>
|
|
150
|
+
</ng-container>
|
|
151
|
+
|
|
152
|
+
<ng-template #buttonSwatches>
|
|
153
|
+
<td-metal-swatches
|
|
154
|
+
[value]="metal"
|
|
155
|
+
(valueChange)="onMetalChange($event)"
|
|
156
|
+
[options]="metalOptions"
|
|
157
|
+
[variant]="buttonVariant"
|
|
158
|
+
></td-metal-swatches>
|
|
159
|
+
<td-stone-swatches
|
|
160
|
+
[value]="stone"
|
|
161
|
+
(valueChange)="onStoneChange($event)"
|
|
162
|
+
[options]="stoneOptions"
|
|
163
|
+
[variant]="buttonVariant"
|
|
164
|
+
></td-stone-swatches>
|
|
165
|
+
</ng-template>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["\n :host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;\n }\n .td-customizer-card {\n display: flex;\n flex-direction: column;\n gap: 16px;\n background: #ffffff;\n border-radius: 16px;\n border: 1px solid #e2e8f0;\n padding: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -2px rgba(0, 0, 0, 0.05);\n }\n .td-customizer-viewport {\n position: relative;\n width: 100%;\n border-radius: 12px;\n overflow: hidden;\n background: #f8fafc;\n }\n .td-customizer-controls {\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n"] }]
|
|
169
|
+
}], propDecorators: { src: [{
|
|
170
|
+
type: Input
|
|
171
|
+
}], source: [{
|
|
172
|
+
type: Input
|
|
173
|
+
}], metal: [{
|
|
174
|
+
type: Input
|
|
175
|
+
}], metalChange: [{
|
|
176
|
+
type: Output
|
|
177
|
+
}], stone: [{
|
|
178
|
+
type: Input
|
|
179
|
+
}], stoneChange: [{
|
|
180
|
+
type: Output
|
|
181
|
+
}], height: [{
|
|
182
|
+
type: Input
|
|
183
|
+
}], autoRotate: [{
|
|
184
|
+
type: Input
|
|
185
|
+
}], quality: [{
|
|
186
|
+
type: Input
|
|
187
|
+
}], controlsVariant: [{
|
|
188
|
+
type: Input
|
|
189
|
+
}], metalOptions: [{
|
|
190
|
+
type: Input
|
|
191
|
+
}], stoneOptions: [{
|
|
192
|
+
type: Input
|
|
193
|
+
}], loaded: [{
|
|
194
|
+
type: Output
|
|
195
|
+
}], partSelected: [{
|
|
196
|
+
type: Output
|
|
197
|
+
}] } });
|
|
198
|
+
//# sourceMappingURL=jewelry-customizer.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jewelry-customizer.component.js","sourceRoot":"","sources":["../../src/swatches/jewelry-customizer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,MAAM,EACN,YAAY,EACZ,uBAAuB,GACxB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EACL,uBAAuB,EACvB,uBAAuB,GAQxB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AACzF,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;;;AAEzF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BzB,CAAA;AA8DD,MAAM,OAAO,0BAA0B;IA5DvC;QA+DW,UAAK,GAAmB,iBAAiB,CAAA;QACxC,gBAAW,GAAG,IAAI,YAAY,EAAU,CAAA;QAEzC,UAAK,GAAmB,WAAW,CAAA;QAClC,gBAAW,GAAG,IAAI,YAAY,EAAU,CAAA;QAEzC,WAAM,GAAoB,GAAG,CAAA;QAC7B,eAAU,GAAG,IAAI,CAAA;QACjB,YAAO,GAA8B,MAAM,CAAA;QAC3C,oBAAe,GAAyC,OAAO,CAAA;QAE/D,iBAAY,GAAkB,uBAAuB,CAAA;QACrD,iBAAY,GAAkB,uBAAuB,CAAA;QAEpD,WAAM,GAAG,IAAI,YAAY,EAAc,CAAA;QACvC,iBAAY,GAAG,IAAI,YAAY,EAAsC,CAAA;KAmBhF;IAjBC,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,eAAe,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;IAC3D,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAA;IAC3E,CAAC;IAED,aAAa,CAAC,GAAW;QACvB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAA;QAChB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAED,aAAa,CAAC,GAAW;QACvB,IAAI,CAAC,KAAK,GAAG,GAAG,CAAA;QAChB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;+GApCU,0BAA0B;mGAA1B,0BAA0B,gbAjD3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CT,svBApDC,YAAY,mIACZ,eAAe,gWACf,sBAAsB,0JACtB,oBAAoB,6HACpB,sBAAsB,0JACtB,oBAAoB;;4FAmDX,0BAA0B;kBA5DtC,SAAS;+BACE,uBAAuB,cACrB,IAAI,WACP;wBACP,YAAY;wBACZ,eAAe;wBACf,sBAAsB;wBACtB,oBAAoB;wBACpB,sBAAsB;wBACtB,oBAAoB;qBACrB,YACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CT,mBAEgB,uBAAuB,CAAC,MAAM;8BAGtC,GAAG;sBAAX,KAAK;gBACG,MAAM;sBAAd,KAAK;gBACG,KAAK;sBAAb,KAAK;gBACI,WAAW;sBAApB,MAAM;gBAEE,KAAK;sBAAb,KAAK;gBACI,WAAW;sBAApB,MAAM;gBAEE,MAAM;sBAAd,KAAK;gBACG,UAAU;sBAAlB,KAAK;gBACG,OAAO;sBAAf,KAAK;gBACG,eAAe;sBAAvB,KAAK;gBAEG,YAAY;sBAApB,KAAK;gBACG,YAAY;sBAApB,KAAK;gBAEI,MAAM;sBAAf,MAAM;gBACG,YAAY;sBAArB,MAAM"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import { type MetalPreset, type MetalColorProp } from '@thinkersteps_labs/3d-viewer-core';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class MetalSwatchesComponent {
|
|
5
|
+
value?: MetalColorProp;
|
|
6
|
+
valueChange: EventEmitter<string>;
|
|
7
|
+
options: MetalPreset[];
|
|
8
|
+
category: 'all' | 'gold' | 'platinum-silver' | 'alternative';
|
|
9
|
+
variant: 'pills' | 'dots';
|
|
10
|
+
showLabel: boolean;
|
|
11
|
+
get visibleOptions(): MetalPreset[];
|
|
12
|
+
get activePreset(): MetalPreset | undefined;
|
|
13
|
+
isSelected(m: MetalPreset): boolean;
|
|
14
|
+
selectMetal(m: MetalPreset): void;
|
|
15
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetalSwatchesComponent, never>;
|
|
16
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MetalSwatchesComponent, "td-metal-swatches", never, { "value": { "alias": "value"; "required": false; }; "options": { "alias": "options"; "required": false; }; "category": { "alias": "category"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "showLabel": { "alias": "showLabel"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
17
|
+
}
|
|
18
|
+
export declare class MetalSelectComponent {
|
|
19
|
+
value?: MetalColorProp;
|
|
20
|
+
valueChange: EventEmitter<string>;
|
|
21
|
+
options: MetalPreset[];
|
|
22
|
+
label: string;
|
|
23
|
+
get activeValue(): string;
|
|
24
|
+
onSelectChange(event: Event): void;
|
|
25
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MetalSelectComponent, never>;
|
|
26
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MetalSelectComponent, "td-metal-select", never, { "value": { "alias": "value"; "required": false; }; "options": { "alias": "options"; "required": false; }; "label": { "alias": "label"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=metal-swatches.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metal-swatches.component.d.ts","sourceRoot":"","sources":["../../src/swatches/metal-swatches.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAEb,MAAM,eAAe,CAAA;AAEtB,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,mCAAmC,CAAA;;AAyH1C,qBAgCa,sBAAsB;IACxB,KAAK,CAAC,EAAE,cAAc,CAAA;IACrB,WAAW,uBAA6B;IAEzC,OAAO,EAAE,WAAW,EAAE,CAA0B;IAChD,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,iBAAiB,GAAG,aAAa,CAAQ;IACpE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAU;IACnC,SAAS,UAAO;IAEzB,IAAI,cAAc,IAAI,WAAW,EAAE,CAGlC;IAED,IAAI,YAAY,IAAI,WAAW,GAAG,SAAS,CAE1C;IAED,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO;IAMnC,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI;yCAxBtB,sBAAsB;2CAAtB,sBAAsB;CA4BlC;AAED,qBAiBa,oBAAoB;IACtB,KAAK,CAAC,EAAE,cAAc,CAAA;IACrB,WAAW,uBAA6B;IACzC,OAAO,EAAE,WAAW,EAAE,CAA0B;IAChD,KAAK,SAAiB;IAE/B,IAAI,WAAW,IAAI,MAAM,CAGxB;IAED,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;yCAXvB,oBAAoB;2CAApB,oBAAoB;CAgBhC"}
|