@leverege/tpi-viz 0.2.0 → 0.2.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/package.json +1 -1
- package/src/main.js +2 -1
- package/src/styles/scene_viewer.css +3 -3
- package/src/styles/viewer_common.css +64 -34
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leverege/tpi-viz",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "3D scene viewer for TPI manufacturing data — renders blade geometry, PTZ cameras, defects, ply layers, and flows. Exports mountViewer()/destroy() for embedding (e.g. an Imaginarium React route); also runs standalone.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
package/src/main.js
CHANGED
|
@@ -2580,6 +2580,7 @@ function fmtN(v, d) {
|
|
|
2580
2580
|
export async function mountViewer( container, opts = {} ) {
|
|
2581
2581
|
if ( _alive ) { destroy(); } // idempotent re-mount
|
|
2582
2582
|
_container = container || document.body;
|
|
2583
|
+
_container.classList.add( 'tpi-viz' ); // scopes all viewer CSS to this subtree
|
|
2583
2584
|
if ( !_container.querySelector( '#app' ) ) { _container.innerHTML = VIEWER_SKELETON; }
|
|
2584
2585
|
_opts = opts || {};
|
|
2585
2586
|
_alive = true;
|
|
@@ -2612,5 +2613,5 @@ export function destroy() {
|
|
|
2612
2613
|
selectedCameraIdx = -1;
|
|
2613
2614
|
povCameraIdx = -1;
|
|
2614
2615
|
activeFlowName = null;
|
|
2615
|
-
if ( _container ) { _container.innerHTML = ''; _container = null; }
|
|
2616
|
+
if ( _container ) { _container.classList.remove( 'tpi-viz' ); _container.innerHTML = ''; _container = null; }
|
|
2616
2617
|
}
|
|
@@ -747,7 +747,7 @@
|
|
|
747
747
|
font-weight: bold;
|
|
748
748
|
}
|
|
749
749
|
|
|
750
|
-
input[type="range"] {
|
|
750
|
+
.tpi-viz input[type="range"] {
|
|
751
751
|
width: 100%;
|
|
752
752
|
height: 4px;
|
|
753
753
|
appearance: none;
|
|
@@ -757,7 +757,7 @@ input[type="range"] {
|
|
|
757
757
|
cursor: pointer;
|
|
758
758
|
}
|
|
759
759
|
|
|
760
|
-
input[type="range"]::-webkit-slider-thumb {
|
|
760
|
+
.tpi-viz input[type="range"]::-webkit-slider-thumb {
|
|
761
761
|
appearance: none;
|
|
762
762
|
width: 14px;
|
|
763
763
|
height: 14px;
|
|
@@ -766,7 +766,7 @@ input[type="range"]::-webkit-slider-thumb {
|
|
|
766
766
|
cursor: pointer;
|
|
767
767
|
}
|
|
768
768
|
|
|
769
|
-
input[type="range"]::-moz-range-thumb {
|
|
769
|
+
.tpi-viz input[type="range"]::-moz-range-thumb {
|
|
770
770
|
width: 14px;
|
|
771
771
|
height: 14px;
|
|
772
772
|
background: var(--accent-blue);
|
|
@@ -7,27 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
:root {
|
|
10
|
-
/*
|
|
11
|
-
--bg-canvas: #0b0d14;
|
|
12
|
-
--bg-sidebar: #11141d;
|
|
13
|
-
--bg-panel: #161a26;
|
|
14
|
-
--bg-panel-strong: #1c2030;
|
|
15
|
-
--bg-hover: #1d2230;
|
|
16
|
-
--bg-active: #232a3d;
|
|
17
|
-
--bg-overlay: rgba(10, 12, 20, 0.88);
|
|
18
|
-
|
|
19
|
-
/* Borders — barely-there to subtly-visible */
|
|
20
|
-
--border-hairline: #1a1d28;
|
|
21
|
-
--border-subtle: #232733;
|
|
22
|
-
--border-strong: #2e3344;
|
|
23
|
-
|
|
24
|
-
/* Text scale */
|
|
25
|
-
--text-1: #e7e9ef; /* body / primary */
|
|
26
|
-
--text-2: #aab1c0; /* labels */
|
|
27
|
-
--text-3: #7b8294; /* secondary, counts */
|
|
28
|
-
--text-4: #6b7488; /* hints, disabled — bumped from #535a6b for legibility on dark bg */
|
|
29
|
-
|
|
30
|
-
/* Accents (paired w/ semantic uses across the app) */
|
|
10
|
+
/* Accents (semantic; theme-independent — read on both light + dark) */
|
|
31
11
|
--accent-blue: #7a9bff; /* elements / general info */
|
|
32
12
|
--accent-blue-soft: #5063a8;
|
|
33
13
|
--accent-pink: #ff95c2; /* flows */
|
|
@@ -46,21 +26,71 @@
|
|
|
46
26
|
--r-sm: 4px;
|
|
47
27
|
--r-md: 6px;
|
|
48
28
|
--r-lg: 10px;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Surfaces / borders / text / shadows follow the host's light–dark theme.
|
|
32
|
+
Imaginarium toggles `.dark` on <html> (shadcn `darkMode:["class"]`), so the
|
|
33
|
+
embedded viewer tracks the app by keying off the SAME class. Light is the
|
|
34
|
+
default; standalone (index.html) forces `.dark` to keep its original look.
|
|
35
|
+
The 3D WebGL clear-color stays dark in both — a dark viewport reads best for
|
|
36
|
+
the varied-hue ply contours — so only the chrome re-themes. */
|
|
37
|
+
.tpi-viz {
|
|
38
|
+
/* Light surfaces — cool grays mirroring the dark scale */
|
|
39
|
+
--bg-canvas: #eceef3;
|
|
40
|
+
--bg-sidebar: #f5f6f9;
|
|
41
|
+
--bg-panel: #ffffff;
|
|
42
|
+
--bg-panel-strong: #eef0f4;
|
|
43
|
+
--bg-hover: #e9edf4;
|
|
44
|
+
--bg-active: #dde6f7;
|
|
45
|
+
--bg-overlay: rgba(244, 246, 250, 0.92);
|
|
46
|
+
|
|
47
|
+
--border-hairline: #e8eaef;
|
|
48
|
+
--border-subtle: #dde0e7;
|
|
49
|
+
--border-strong: #c7cdd8;
|
|
50
|
+
|
|
51
|
+
--text-1: #181b24; /* body / primary */
|
|
52
|
+
--text-2: #424a59; /* labels */
|
|
53
|
+
--text-3: #667083; /* secondary, counts */
|
|
54
|
+
--text-4: #8891a1; /* hints, disabled */
|
|
55
|
+
|
|
56
|
+
--shadow-soft: 0 2px 10px rgba(20, 28, 50, 0.10);
|
|
57
|
+
--shadow-med: 0 4px 18px rgba(20, 28, 50, 0.16);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.dark .tpi-viz {
|
|
61
|
+
/* Dark surfaces — the original palette */
|
|
62
|
+
--bg-canvas: #0b0d14;
|
|
63
|
+
--bg-sidebar: #11141d;
|
|
64
|
+
--bg-panel: #161a26;
|
|
65
|
+
--bg-panel-strong: #1c2030;
|
|
66
|
+
--bg-hover: #1d2230;
|
|
67
|
+
--bg-active: #232a3d;
|
|
68
|
+
--bg-overlay: rgba(10, 12, 20, 0.88);
|
|
69
|
+
|
|
70
|
+
--border-hairline: #1a1d28;
|
|
71
|
+
--border-subtle: #232733;
|
|
72
|
+
--border-strong: #2e3344;
|
|
73
|
+
|
|
74
|
+
--text-1: #e7e9ef;
|
|
75
|
+
--text-2: #aab1c0;
|
|
76
|
+
--text-3: #7b8294;
|
|
77
|
+
--text-4: #6b7488;
|
|
49
78
|
|
|
50
|
-
/* Shadows */
|
|
51
79
|
--shadow-soft: 0 2px 10px rgba(0, 0, 0, 0.35);
|
|
52
80
|
--shadow-med: 0 4px 18px rgba(0, 0, 0, 0.45);
|
|
53
81
|
}
|
|
54
82
|
|
|
55
|
-
/* Reset and base
|
|
56
|
-
|
|
83
|
+
/* Reset and base. Everything is scoped under .tpi-viz (the viewer root that
|
|
84
|
+
mountViewer adds to its container) so these rules NEVER leak into a host app
|
|
85
|
+
when the viewer is embedded — only the viewer's own subtree is affected. */
|
|
86
|
+
.tpi-viz, .tpi-viz * { margin: 0; padding: 0; box-sizing: border-box; }
|
|
57
87
|
|
|
58
|
-
|
|
88
|
+
.tpi-viz {
|
|
59
89
|
font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
|
|
60
90
|
font-feature-settings: 'tnum' 1, 'cv11' 1; /* tabular numerals */
|
|
61
91
|
background: var(--bg-canvas);
|
|
62
92
|
color: var(--text-1);
|
|
63
|
-
height: 100vh;
|
|
93
|
+
height: 100%; /* fill the mount container (standalone: #viewer-root @ 100vh; embedded: the host's sized div) */
|
|
64
94
|
overflow: hidden;
|
|
65
95
|
-webkit-font-smoothing: antialiased;
|
|
66
96
|
text-rendering: optimizeLegibility;
|
|
@@ -82,35 +112,35 @@ body {
|
|
|
82
112
|
}
|
|
83
113
|
|
|
84
114
|
/* Custom scrollbars — thin, blend with the dark surface */
|
|
85
|
-
* {
|
|
115
|
+
.tpi-viz, .tpi-viz * {
|
|
86
116
|
scrollbar-width: thin;
|
|
87
117
|
scrollbar-color: var(--border-strong) transparent;
|
|
88
118
|
}
|
|
89
|
-
|
|
119
|
+
.tpi-viz ::-webkit-scrollbar {
|
|
90
120
|
width: 8px;
|
|
91
121
|
height: 8px;
|
|
92
122
|
}
|
|
93
|
-
|
|
94
|
-
|
|
123
|
+
.tpi-viz ::-webkit-scrollbar-track { background: transparent; }
|
|
124
|
+
.tpi-viz ::-webkit-scrollbar-thumb {
|
|
95
125
|
background: var(--border-subtle);
|
|
96
126
|
border-radius: 999px;
|
|
97
127
|
border: 2px solid transparent;
|
|
98
128
|
background-clip: padding-box;
|
|
99
129
|
}
|
|
100
|
-
|
|
130
|
+
.tpi-viz ::-webkit-scrollbar-thumb:hover {
|
|
101
131
|
background: var(--border-strong);
|
|
102
132
|
background-clip: padding-box;
|
|
103
133
|
border: 2px solid transparent;
|
|
104
134
|
}
|
|
105
135
|
|
|
106
136
|
/* Selection styling */
|
|
107
|
-
::selection {
|
|
137
|
+
.tpi-viz ::selection {
|
|
108
138
|
background: rgba(122, 155, 255, 0.32);
|
|
109
139
|
color: var(--text-1);
|
|
110
140
|
}
|
|
111
141
|
|
|
112
142
|
/* Focus ring for keyboard nav (subtle but visible) */
|
|
113
|
-
:focus-visible {
|
|
143
|
+
.tpi-viz :focus-visible {
|
|
114
144
|
outline: 2px solid var(--accent-blue);
|
|
115
145
|
outline-offset: 2px;
|
|
116
146
|
border-radius: var(--r-sm);
|
|
@@ -119,7 +149,7 @@ body {
|
|
|
119
149
|
/* Layout */
|
|
120
150
|
.container {
|
|
121
151
|
display: flex;
|
|
122
|
-
height:
|
|
152
|
+
height: 100%;
|
|
123
153
|
}
|
|
124
154
|
|
|
125
155
|
.sidebar {
|