@selvajs/ui 4.6.2-beta.1 → 4.7.0-beta.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/dist/components/viewer/SceneManager.svelte +8 -1
- package/dist/components/viewer/Viewer.svelte +32 -2
- package/dist/components/viewer/Viewer.svelte.d.ts +2 -0
- package/package.json +3 -3
- package/src/lib/components/viewer/SceneManager.svelte +8 -1
- package/src/lib/components/viewer/Viewer.svelte +32 -2
|
@@ -10,10 +10,17 @@
|
|
|
10
10
|
|
|
11
11
|
let { scene = $bindable(), sceneVersion = 0 }: Props = $props();
|
|
12
12
|
|
|
13
|
+
// Viewer aids (grid, floor, measurement overlay, CSS2D label layer) are tagged with these ids by
|
|
14
|
+
// @selvajs/compute. They aren't scene content, so they're hidden from the object list.
|
|
15
|
+
const HELPER_IDS = new Set(['grid', 'floor', 'label-layer', 'measure']);
|
|
16
|
+
|
|
13
17
|
const getSceneObjects = () => {
|
|
14
18
|
void sceneVersion;
|
|
15
19
|
return scene.children.filter(
|
|
16
|
-
(obj) =>
|
|
20
|
+
(obj) =>
|
|
21
|
+
!(obj instanceof THREE.Camera) &&
|
|
22
|
+
!(obj instanceof THREE.Light) &&
|
|
23
|
+
!HELPER_IDS.has(obj.userData?.id)
|
|
17
24
|
);
|
|
18
25
|
};
|
|
19
26
|
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
type CameraController,
|
|
9
9
|
type CameraProjection,
|
|
10
10
|
type MeasureTool,
|
|
11
|
-
type ViewPreset
|
|
11
|
+
type ViewPreset,
|
|
12
|
+
type Grid
|
|
12
13
|
} from '@selvajs/compute/visualization';
|
|
13
14
|
import {
|
|
14
15
|
Maximize,
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
Square,
|
|
21
22
|
Frame,
|
|
22
23
|
Ruler,
|
|
24
|
+
Grid3x3,
|
|
23
25
|
Check,
|
|
24
26
|
ChevronRight
|
|
25
27
|
} from '@lucide/svelte';
|
|
@@ -35,6 +37,8 @@
|
|
|
35
37
|
showFullscreenButton?: boolean;
|
|
36
38
|
showSceneManager?: boolean;
|
|
37
39
|
showToolsMenu?: boolean;
|
|
40
|
+
/** Expose the grid show/hide toggle in the tools menu. Grid starts hidden. */
|
|
41
|
+
showGridToggle?: boolean;
|
|
38
42
|
enableMeshClick?: boolean;
|
|
39
43
|
backgroundColor?: string;
|
|
40
44
|
}
|
|
@@ -53,6 +57,7 @@
|
|
|
53
57
|
showFullscreenButton: true,
|
|
54
58
|
showSceneManager: true,
|
|
55
59
|
showToolsMenu: true,
|
|
60
|
+
showGridToggle: true,
|
|
56
61
|
enableMeshClick: true,
|
|
57
62
|
backgroundColor: '#E6E6E6'
|
|
58
63
|
};
|
|
@@ -74,6 +79,7 @@
|
|
|
74
79
|
let controls: OrbitControls | null = null;
|
|
75
80
|
let cameraController: CameraController | null = null;
|
|
76
81
|
let measureTool: MeasureTool | null = null;
|
|
82
|
+
let grid: Grid | null = null;
|
|
77
83
|
let fitToView: (() => void) | null = null;
|
|
78
84
|
let viewerInitialized = false;
|
|
79
85
|
let sceneVersion = $state(0);
|
|
@@ -81,6 +87,7 @@
|
|
|
81
87
|
let sceneManagerOpen = $state(false);
|
|
82
88
|
let projection: CameraProjection = $state('perspective');
|
|
83
89
|
let measureActive = $state(false);
|
|
90
|
+
let gridVisible = $state(false);
|
|
84
91
|
let selectedMeshMetadata: Record<string, any> | null = $state(null);
|
|
85
92
|
let selectedMeshName: string | null = $state(null);
|
|
86
93
|
|
|
@@ -112,7 +119,8 @@
|
|
|
112
119
|
const opts: ThreeInitializerOptions = {
|
|
113
120
|
environment: { backgroundColor: config.backgroundColor },
|
|
114
121
|
controls: {},
|
|
115
|
-
grid
|
|
122
|
+
// Build the grid so it can be toggled at runtime, but start hidden (off by default).
|
|
123
|
+
grid: { enabled: config.showToolsMenu && config.showGridToggle },
|
|
116
124
|
gizmo: { enabled: false },
|
|
117
125
|
measure: { enabled: config.showToolsMenu },
|
|
118
126
|
events: {
|
|
@@ -133,6 +141,8 @@
|
|
|
133
141
|
controls = init.controls;
|
|
134
142
|
cameraController = init.cameraController;
|
|
135
143
|
measureTool = init.measureTool;
|
|
144
|
+
grid = init.grid;
|
|
145
|
+
grid?.setVisible(gridVisible);
|
|
136
146
|
fitToView = init.fitToView;
|
|
137
147
|
projection = init.cameraController.getProjection();
|
|
138
148
|
|
|
@@ -156,6 +166,12 @@
|
|
|
156
166
|
measureTool.setEnabled(measureActive);
|
|
157
167
|
}
|
|
158
168
|
|
|
169
|
+
function toggleGrid() {
|
|
170
|
+
if (!grid) return;
|
|
171
|
+
gridVisible = !gridVisible;
|
|
172
|
+
grid.setVisible(gridVisible);
|
|
173
|
+
}
|
|
174
|
+
|
|
159
175
|
$effect(() => {
|
|
160
176
|
if (scene && camera && controls) {
|
|
161
177
|
updateScene(scene, meshes, camera, controls, viewerInitialized);
|
|
@@ -309,6 +325,20 @@
|
|
|
309
325
|
{/if}
|
|
310
326
|
</DropdownMenu.Item>
|
|
311
327
|
|
|
328
|
+
{#if config.showGridToggle}
|
|
329
|
+
<DropdownMenu.Item
|
|
330
|
+
closeOnSelect={false}
|
|
331
|
+
class="{itemClass} {gridVisible ? 'text-primary' : ''}"
|
|
332
|
+
onSelect={toggleGrid}
|
|
333
|
+
>
|
|
334
|
+
<Grid3x3 class="h-4 w-4" />
|
|
335
|
+
<span class="flex-1">Grid</span>
|
|
336
|
+
{#if gridVisible}
|
|
337
|
+
<Check class="h-4 w-4" />
|
|
338
|
+
{/if}
|
|
339
|
+
</DropdownMenu.Item>
|
|
340
|
+
{/if}
|
|
341
|
+
|
|
312
342
|
<!-- Scene tools -->
|
|
313
343
|
{#if config.showSceneManager || config.showScreenshotButton || config.showFullscreenButton}
|
|
314
344
|
<DropdownMenu.Separator class="my-1 h-px bg-border" />
|
|
@@ -3,6 +3,8 @@ export interface ViewerConfig {
|
|
|
3
3
|
showFullscreenButton?: boolean;
|
|
4
4
|
showSceneManager?: boolean;
|
|
5
5
|
showToolsMenu?: boolean;
|
|
6
|
+
/** Expose the grid show/hide toggle in the tools menu. Grid starts hidden. */
|
|
7
|
+
showGridToggle?: boolean;
|
|
6
8
|
enableMeshClick?: boolean;
|
|
7
9
|
backgroundColor?: string;
|
|
8
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selvajs/ui",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0-beta.2",
|
|
4
4
|
"description": "Shared UI components and utilities for Selva applications",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
"svelte": "5.55.5",
|
|
73
73
|
"tailwind-variants": "^3.2.2",
|
|
74
74
|
"vitest": "^3.2.4",
|
|
75
|
-
"@selvajs/
|
|
76
|
-
"@selvajs/
|
|
75
|
+
"@selvajs/config": "0.0.0",
|
|
76
|
+
"@selvajs/schemas": "4.5.0"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"dev": "vite dev",
|
|
@@ -10,10 +10,17 @@
|
|
|
10
10
|
|
|
11
11
|
let { scene = $bindable(), sceneVersion = 0 }: Props = $props();
|
|
12
12
|
|
|
13
|
+
// Viewer aids (grid, floor, measurement overlay, CSS2D label layer) are tagged with these ids by
|
|
14
|
+
// @selvajs/compute. They aren't scene content, so they're hidden from the object list.
|
|
15
|
+
const HELPER_IDS = new Set(['grid', 'floor', 'label-layer', 'measure']);
|
|
16
|
+
|
|
13
17
|
const getSceneObjects = () => {
|
|
14
18
|
void sceneVersion;
|
|
15
19
|
return scene.children.filter(
|
|
16
|
-
(obj) =>
|
|
20
|
+
(obj) =>
|
|
21
|
+
!(obj instanceof THREE.Camera) &&
|
|
22
|
+
!(obj instanceof THREE.Light) &&
|
|
23
|
+
!HELPER_IDS.has(obj.userData?.id)
|
|
17
24
|
);
|
|
18
25
|
};
|
|
19
26
|
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
type CameraController,
|
|
9
9
|
type CameraProjection,
|
|
10
10
|
type MeasureTool,
|
|
11
|
-
type ViewPreset
|
|
11
|
+
type ViewPreset,
|
|
12
|
+
type Grid
|
|
12
13
|
} from '@selvajs/compute/visualization';
|
|
13
14
|
import {
|
|
14
15
|
Maximize,
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
Square,
|
|
21
22
|
Frame,
|
|
22
23
|
Ruler,
|
|
24
|
+
Grid3x3,
|
|
23
25
|
Check,
|
|
24
26
|
ChevronRight
|
|
25
27
|
} from '@lucide/svelte';
|
|
@@ -35,6 +37,8 @@
|
|
|
35
37
|
showFullscreenButton?: boolean;
|
|
36
38
|
showSceneManager?: boolean;
|
|
37
39
|
showToolsMenu?: boolean;
|
|
40
|
+
/** Expose the grid show/hide toggle in the tools menu. Grid starts hidden. */
|
|
41
|
+
showGridToggle?: boolean;
|
|
38
42
|
enableMeshClick?: boolean;
|
|
39
43
|
backgroundColor?: string;
|
|
40
44
|
}
|
|
@@ -53,6 +57,7 @@
|
|
|
53
57
|
showFullscreenButton: true,
|
|
54
58
|
showSceneManager: true,
|
|
55
59
|
showToolsMenu: true,
|
|
60
|
+
showGridToggle: true,
|
|
56
61
|
enableMeshClick: true,
|
|
57
62
|
backgroundColor: '#E6E6E6'
|
|
58
63
|
};
|
|
@@ -74,6 +79,7 @@
|
|
|
74
79
|
let controls: OrbitControls | null = null;
|
|
75
80
|
let cameraController: CameraController | null = null;
|
|
76
81
|
let measureTool: MeasureTool | null = null;
|
|
82
|
+
let grid: Grid | null = null;
|
|
77
83
|
let fitToView: (() => void) | null = null;
|
|
78
84
|
let viewerInitialized = false;
|
|
79
85
|
let sceneVersion = $state(0);
|
|
@@ -81,6 +87,7 @@
|
|
|
81
87
|
let sceneManagerOpen = $state(false);
|
|
82
88
|
let projection: CameraProjection = $state('perspective');
|
|
83
89
|
let measureActive = $state(false);
|
|
90
|
+
let gridVisible = $state(false);
|
|
84
91
|
let selectedMeshMetadata: Record<string, any> | null = $state(null);
|
|
85
92
|
let selectedMeshName: string | null = $state(null);
|
|
86
93
|
|
|
@@ -112,7 +119,8 @@
|
|
|
112
119
|
const opts: ThreeInitializerOptions = {
|
|
113
120
|
environment: { backgroundColor: config.backgroundColor },
|
|
114
121
|
controls: {},
|
|
115
|
-
grid
|
|
122
|
+
// Build the grid so it can be toggled at runtime, but start hidden (off by default).
|
|
123
|
+
grid: { enabled: config.showToolsMenu && config.showGridToggle },
|
|
116
124
|
gizmo: { enabled: false },
|
|
117
125
|
measure: { enabled: config.showToolsMenu },
|
|
118
126
|
events: {
|
|
@@ -133,6 +141,8 @@
|
|
|
133
141
|
controls = init.controls;
|
|
134
142
|
cameraController = init.cameraController;
|
|
135
143
|
measureTool = init.measureTool;
|
|
144
|
+
grid = init.grid;
|
|
145
|
+
grid?.setVisible(gridVisible);
|
|
136
146
|
fitToView = init.fitToView;
|
|
137
147
|
projection = init.cameraController.getProjection();
|
|
138
148
|
|
|
@@ -156,6 +166,12 @@
|
|
|
156
166
|
measureTool.setEnabled(measureActive);
|
|
157
167
|
}
|
|
158
168
|
|
|
169
|
+
function toggleGrid() {
|
|
170
|
+
if (!grid) return;
|
|
171
|
+
gridVisible = !gridVisible;
|
|
172
|
+
grid.setVisible(gridVisible);
|
|
173
|
+
}
|
|
174
|
+
|
|
159
175
|
$effect(() => {
|
|
160
176
|
if (scene && camera && controls) {
|
|
161
177
|
updateScene(scene, meshes, camera, controls, viewerInitialized);
|
|
@@ -309,6 +325,20 @@
|
|
|
309
325
|
{/if}
|
|
310
326
|
</DropdownMenu.Item>
|
|
311
327
|
|
|
328
|
+
{#if config.showGridToggle}
|
|
329
|
+
<DropdownMenu.Item
|
|
330
|
+
closeOnSelect={false}
|
|
331
|
+
class="{itemClass} {gridVisible ? 'text-primary' : ''}"
|
|
332
|
+
onSelect={toggleGrid}
|
|
333
|
+
>
|
|
334
|
+
<Grid3x3 class="h-4 w-4" />
|
|
335
|
+
<span class="flex-1">Grid</span>
|
|
336
|
+
{#if gridVisible}
|
|
337
|
+
<Check class="h-4 w-4" />
|
|
338
|
+
{/if}
|
|
339
|
+
</DropdownMenu.Item>
|
|
340
|
+
{/if}
|
|
341
|
+
|
|
312
342
|
<!-- Scene tools -->
|
|
313
343
|
{#if config.showSceneManager || config.showScreenshotButton || config.showFullscreenButton}
|
|
314
344
|
<DropdownMenu.Separator class="my-1 h-px bg-border" />
|