Refine BIM section controls and styling
This commit is contained in:
parent
e343412468
commit
84b28ba12c
|
|
@ -51,6 +51,16 @@
|
|||
--measure-label: #c4ff67;
|
||||
--measure-label-text: #292929;
|
||||
--measure-dot: #c4ff67;
|
||||
--section-axis-x: #ff2b2b;
|
||||
--section-axis-y: #35ff4f;
|
||||
--section-axis-z: #285bff;
|
||||
--section-gizmo-diameter: 1;
|
||||
--section-plane-fill: #606060;
|
||||
--section-plane-alpha: 0.32;
|
||||
--section-plane-edge: #0d0d0d;
|
||||
--section-plane-edge-alpha: 0.8;
|
||||
--section-toolbar-left: calc(12px + var(--tb-size, 25px) + var(--tb-gap, 10px));
|
||||
--section-toolbar-bottom: 123px;
|
||||
--nodedc-glass-control-bg: var(--modal-element);
|
||||
--nodedc-glass-control-hover: color-mix(in srgb, var(--modal-element) 86%, white 8%);
|
||||
--nodedc-glass-control-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.01);
|
||||
|
|
@ -1928,19 +1938,20 @@ body[data-viewer-mode="guest"] .inspector-restore-tray {
|
|||
|
||||
.section-toolbar {
|
||||
position: fixed;
|
||||
left: calc(12px + var(--tb-size, 52px) + 10px);
|
||||
bottom: 12px;
|
||||
left: var(--section-toolbar-left);
|
||||
bottom: var(--section-toolbar-bottom);
|
||||
z-index: 16;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px;
|
||||
border: 1px solid var(--toolbar-border);
|
||||
border-radius: var(--tb-radius, 12px);
|
||||
background: color-mix(in srgb, var(--toolbar-bg) 88%, transparent);
|
||||
box-shadow: 0 18px 34px rgba(0, 0, 0, 0.28);
|
||||
backdrop-filter: blur(18px) saturate(124%);
|
||||
-webkit-backdrop-filter: blur(18px) saturate(124%);
|
||||
gap: var(--tb-gap, 10px);
|
||||
height: var(--tb-size, 25px);
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
-webkit-backdrop-filter: none;
|
||||
}
|
||||
|
||||
.section-toolbar.hidden {
|
||||
|
|
@ -1948,26 +1959,30 @@ body[data-viewer-mode="guest"] .inspector-restore-tray {
|
|||
}
|
||||
|
||||
.section-tool-btn {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
width: var(--tb-size, 25px);
|
||||
height: var(--tb-size, 25px);
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
border: 1px solid transparent;
|
||||
border-radius: calc(var(--tb-radius, 12px) - 4px);
|
||||
background: transparent;
|
||||
border: 1px solid var(--toolbar-border);
|
||||
border-radius: var(--tb-radius, 7px);
|
||||
background: var(--toolbar-bg);
|
||||
color: var(--text);
|
||||
font-size: 13px;
|
||||
font-size: var(--tb-icon-size, 13px);
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
transition: background 120ms ease, border-color 120ms ease, transform 100ms ease;
|
||||
padding: var(--tb-icon-pad, 5px);
|
||||
transition: transform 120ms ease, border-color 120ms ease, box-shadow 120ms ease, background 120ms ease;
|
||||
}
|
||||
|
||||
.section-tool-btn:hover,
|
||||
.section-tool-btn.active {
|
||||
.section-tool-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: var(--toolbar-outline, rgba(76, 224, 210, 0.7));
|
||||
box-shadow: 0 10px 20px color-mix(in srgb, var(--toolbar-outline, rgba(76, 224, 210, 0.7)) 30%, transparent);
|
||||
}
|
||||
|
||||
.section-tool-btn.active {
|
||||
background: var(--toolbar-bg-active);
|
||||
color: var(--modal-btn-primary-contrast, #15170f);
|
||||
}
|
||||
|
||||
.section-tool-btn:active {
|
||||
|
|
@ -1976,8 +1991,8 @@ body[data-viewer-mode="guest"] .inspector-restore-tray {
|
|||
|
||||
.section-tool-btn svg {
|
||||
display: block;
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
width: var(--tb-svg-size, 24px);
|
||||
height: var(--tb-svg-size, 24px);
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 1.8;
|
||||
|
|
@ -1990,21 +2005,14 @@ body[data-viewer-mode="guest"] .inspector-restore-tray {
|
|||
}
|
||||
|
||||
.section-overview {
|
||||
position: fixed;
|
||||
left: calc(12px + var(--tb-size, 52px) + 10px);
|
||||
bottom: 66px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
z-index: 14;
|
||||
display: none;
|
||||
border: 1px solid var(--toolbar-border);
|
||||
border-radius: 12px;
|
||||
background: color-mix(in srgb, var(--toolbar-bg) 84%, transparent);
|
||||
box-shadow: 0 18px 34px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
body[data-section-mode="active"] .section-overview {
|
||||
width: var(--tb-size, 25px);
|
||||
height: var(--tb-size, 25px);
|
||||
flex: 0 0 var(--tb-size, 25px);
|
||||
display: block;
|
||||
border: 1px solid var(--toolbar-border);
|
||||
border-radius: var(--tb-radius, 7px);
|
||||
background: var(--toolbar-bg);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.templates-panel {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
const SDK_VERSION = "2.6.78"; // соответствует package.json
|
||||
const SDK_URL = "./lib/dc-camera-context.es.js";
|
||||
const SDK_URL = "./lib/dc-camera-context.es.js?v=2";
|
||||
|
||||
import { createLogo } from "./src/ui/logo.js";
|
||||
import { toolbarConfig, applyToolbarVars } from "./src/ui/toolbar.js";
|
||||
import { createTemplatesMenu } from "./src/ui/templatesMenu.js?v=2";
|
||||
import { createSettingsMenu } from "./src/ui/settingsMenu.js?v=5";
|
||||
import { createSettingsMenu } from "./src/ui/settingsMenu.js?v=6";
|
||||
import { createMeasurementModal } from "./src/ui/measurementModal.js";
|
||||
import { createGlassSelect } from "./src/ui/glassSelect.js";
|
||||
import { createSliderControl } from "./src/ui/controls/slider.js";
|
||||
|
|
@ -943,6 +943,12 @@ const cssValue = (name, fallback = "") => {
|
|||
return (v && v.trim()) || fallback;
|
||||
};
|
||||
|
||||
const clampNumber = (value, min, max, fallback) => {
|
||||
const num = Number(value);
|
||||
if (!Number.isFinite(num)) return fallback;
|
||||
return Math.max(min, Math.min(max, num));
|
||||
};
|
||||
|
||||
const hexToRgb01 = (hex) => {
|
||||
if (!hex) return [1, 1, 1];
|
||||
const clean = hex.trim();
|
||||
|
|
@ -998,6 +1004,56 @@ const applyMeasureTheme = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const sectionPlaneThemeFromCSS = () => ({
|
||||
axes: {
|
||||
x: hexToRgb01(cssValue("--section-axis-x", "#ff2b2b")),
|
||||
y: hexToRgb01(cssValue("--section-axis-y", "#35ff4f")),
|
||||
z: hexToRgb01(cssValue("--section-axis-z", "#285bff")),
|
||||
},
|
||||
gizmoDiameter: clampNumber(parseFloat(cssValue("--section-gizmo-diameter", "1")), 0.5, 1.8, 1),
|
||||
planeFillColor: hexToRgb01(cssValue("--section-plane-fill", "#606060")),
|
||||
planeFillAlpha: clampNumber(parseFloat(cssValue("--section-plane-alpha", "0.32")), 0, 1, 0.32),
|
||||
planeEdgeColor: hexToRgb01(cssValue("--section-plane-edge", "#0d0d0d")),
|
||||
planeEdgeAlpha: clampNumber(parseFloat(cssValue("--section-plane-edge-alpha", "0.8")), 0, 1, 0.8),
|
||||
});
|
||||
|
||||
const applySectionPlaneTheme = () => {
|
||||
if (!sectionPlanesPlugin) return;
|
||||
const theme = sectionPlaneThemeFromCSS();
|
||||
Object.values(sectionPlanesPlugin._controls || {}).forEach((control) => {
|
||||
control?.setStyle?.(theme);
|
||||
});
|
||||
Object.values(sectionPlanesPlugin._overview?._planes || {}).forEach((plane) => {
|
||||
const mesh = plane?._mesh;
|
||||
if (!mesh) return;
|
||||
if (mesh.material) {
|
||||
mesh.material.diffuse = theme.planeFillColor;
|
||||
mesh.material.emissive = theme.planeFillColor;
|
||||
mesh.material.alpha = theme.planeFillAlpha;
|
||||
mesh.material.alphaMode = theme.planeFillAlpha < 1 ? "blend" : "opaque";
|
||||
}
|
||||
if (mesh.edgeMaterial) {
|
||||
mesh.edgeMaterial.edgeColor = theme.planeEdgeColor;
|
||||
mesh.edgeMaterial.edgeAlpha = theme.planeEdgeAlpha;
|
||||
}
|
||||
if (mesh.highlightMaterial) {
|
||||
mesh.highlightMaterial.fillColor = theme.planeFillColor;
|
||||
mesh.highlightMaterial.fillAlpha = theme.planeFillAlpha;
|
||||
mesh.highlightMaterial.edgeColor = theme.planeEdgeColor;
|
||||
mesh.highlightMaterial.edgeAlpha = theme.planeEdgeAlpha;
|
||||
}
|
||||
if (mesh.selectedMaterial) {
|
||||
mesh.selectedMaterial.fillColor = theme.planeFillColor;
|
||||
mesh.selectedMaterial.fillAlpha = theme.planeFillAlpha;
|
||||
mesh.selectedMaterial.edgeColor = theme.planeEdgeColor;
|
||||
mesh.selectedMaterial.edgeAlpha = theme.planeEdgeAlpha;
|
||||
}
|
||||
mesh.opacity = theme.planeFillAlpha;
|
||||
});
|
||||
viewer?.scene?.glRedraw?.();
|
||||
sectionPlanesPlugin._overview?._scene?.glRedraw?.();
|
||||
};
|
||||
|
||||
const applyHighlightTheme = () => {
|
||||
if (!viewer?.scene?.highlightMaterial) return;
|
||||
const hexToRGB = (hex) => {
|
||||
|
|
@ -1229,8 +1285,21 @@ const setSectionAxisActive = (axis) => {
|
|||
});
|
||||
};
|
||||
|
||||
const positionSectionToolbar = () => {
|
||||
if (!sectionButton || !sectionToolbar) return;
|
||||
const rect = sectionButton.getBoundingClientRect();
|
||||
if (!rect.width || !rect.height) return;
|
||||
const gap = parseFloat(cssValue("--tb-gap", "10")) || 10;
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty("--section-toolbar-left", `${Math.round(rect.right + gap)}px`);
|
||||
root.style.setProperty("--section-toolbar-bottom", `${Math.round(Math.max(8, window.innerHeight - rect.bottom))}px`);
|
||||
};
|
||||
|
||||
const setSectionModeActive = (active) => {
|
||||
sectionModeActive = !!active && !!sectionPlanesPlugin && getSectionPlaneIds().length > 0 && !isGuestMode();
|
||||
if (sectionModeActive) {
|
||||
positionSectionToolbar();
|
||||
}
|
||||
sectionButton?.classList.toggle("active", sectionModeActive);
|
||||
sectionToolbar?.classList.toggle("hidden", !sectionModeActive);
|
||||
document.body.dataset.sectionMode = sectionModeActive ? "active" : "";
|
||||
|
|
@ -1287,6 +1356,7 @@ const createOrUpdateSectionPlane = (axis = "camera") => {
|
|||
activeSectionPlaneId = sectionPlane.id || activeSectionPlaneId;
|
||||
}
|
||||
|
||||
applySectionPlaneTheme();
|
||||
sectionPlanesPlugin.showControl(activeSectionPlaneId);
|
||||
setSectionModeActive(true);
|
||||
setSectionAxisActive(axis);
|
||||
|
|
@ -1569,6 +1639,11 @@ window.addEventListener("pointerup", scheduleCameraRearm, true);
|
|||
window.addEventListener("mouseup", scheduleCameraRearm, true);
|
||||
window.addEventListener("touchend", scheduleCameraRearm, true);
|
||||
window.addEventListener("touchcancel", scheduleCameraRearm, true);
|
||||
window.addEventListener("resize", () => {
|
||||
if (sectionModeActive) {
|
||||
positionSectionToolbar();
|
||||
}
|
||||
});
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (!document.hidden) {
|
||||
scheduleCameraRearm();
|
||||
|
|
@ -3099,6 +3174,7 @@ const initViewer = async () => {
|
|||
overviewVisible: false,
|
||||
});
|
||||
sectionPlanesPlugin.setOverviewVisible(false);
|
||||
applySectionPlaneTheme();
|
||||
setSectionModeActive(false);
|
||||
} else {
|
||||
console.warn("SectionPlanesPlugin is not available in the loaded SDK build");
|
||||
|
|
@ -3971,6 +4047,9 @@ const loadProjectSnapshot = async (project) => {
|
|||
if (key && key.startsWith("measure")) {
|
||||
applyMeasureTheme();
|
||||
}
|
||||
if (key && key.startsWith("section")) {
|
||||
applySectionPlaneTheme();
|
||||
}
|
||||
focusCanvasAndControls();
|
||||
},
|
||||
onShow: () => {
|
||||
|
|
@ -3986,6 +4065,7 @@ const loadProjectSnapshot = async (project) => {
|
|||
rebuildNavCube(sdk);
|
||||
applyHighlightTheme();
|
||||
applyMeasureTheme();
|
||||
applySectionPlaneTheme();
|
||||
if (displayModeControl && displayModeSelectHost) {
|
||||
displayModeSelect = createGlassSelect({
|
||||
host: displayModeSelectHost,
|
||||
|
|
|
|||
|
|
@ -81,6 +81,14 @@
|
|||
set("--measure-label", s.measureLabel);
|
||||
set("--measure-label-text", s.measureLabelText);
|
||||
set("--measure-dot", s.measureDot);
|
||||
set("--section-axis-x", s.sectionAxisX);
|
||||
set("--section-axis-y", s.sectionAxisY);
|
||||
set("--section-axis-z", s.sectionAxisZ);
|
||||
set("--section-gizmo-diameter", s.sectionGizmoDiameter);
|
||||
set("--section-plane-fill", s.sectionPlaneFill);
|
||||
set("--section-plane-alpha", s.sectionPlaneAlpha);
|
||||
set("--section-plane-edge", s.sectionPlaneEdge);
|
||||
set("--section-plane-edge-alpha", s.sectionPlaneEdgeAlpha);
|
||||
} catch (e) {
|
||||
// ignore corrupted settings
|
||||
}
|
||||
|
|
@ -89,7 +97,7 @@
|
|||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="./dcViewer.css?v=18">
|
||||
<link rel="stylesheet" href="./dcViewer.css?v=19">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
|
|
@ -107,7 +115,6 @@
|
|||
<section class="viewer-wrapper">
|
||||
<canvas id="viewerCanvas"></canvas>
|
||||
<canvas id="navCube"></canvas>
|
||||
<canvas id="sectionPlanesOverview" class="section-overview" width="150" height="150"></canvas>
|
||||
<div class="drop-hint" id="dropZone">
|
||||
<div class="drop-center">
|
||||
<div class="drop-plus">+</div>
|
||||
|
|
@ -318,6 +325,7 @@
|
|||
</div>
|
||||
|
||||
<div id="sectionToolbar" class="section-toolbar hidden" aria-label="Управление разрезом">
|
||||
<canvas id="sectionPlanesOverview" class="section-overview" width="80" height="80"></canvas>
|
||||
<button class="section-tool-btn" data-section-action="camera" type="button" title="По камере" aria-label="По камере">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M4.5 12s2.75-5 7.5-5 7.5 5 7.5 5-2.75 5-7.5 5-7.5-5-7.5-5Z"></path>
|
||||
|
|
@ -349,6 +357,6 @@
|
|||
<input id="fileInput" class="hidden" type="file"
|
||||
accept=".xkt,.glb,.gltf,.bim,.las,.laz,.obj,.stl">
|
||||
|
||||
<script type="module" src="./dcViewer.js?v=23"></script>
|
||||
<script type="module" src="./dcViewer.js?v=24"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -126510,6 +126510,9 @@ class TransformControl {
|
|||
scale: [5, 5, 5],
|
||||
isObject: false
|
||||
});
|
||||
this._rootNode = rootNode;
|
||||
this._styleScale = 1;
|
||||
this._baseRootScale = 5;
|
||||
|
||||
const pos = math.vec3();
|
||||
this._setPosition = (function() {
|
||||
|
|
@ -126831,6 +126834,16 @@ class TransformControl {
|
|||
return {
|
||||
setPositionActive: (a) => { positionActive = a; updatePositionHandle(); },
|
||||
setRotationActive: (a) => { rotationActive = a; updateRotationHandle(); },
|
||||
setColor: (color) => {
|
||||
if (!color) {
|
||||
return;
|
||||
}
|
||||
material.diffuse = color;
|
||||
material.emissive = color;
|
||||
if (hoop.highlightMaterial) {
|
||||
hoop.highlightMaterial.fillColor = color;
|
||||
}
|
||||
},
|
||||
set visible(v) {
|
||||
visible = v;
|
||||
updatePositionHandle();
|
||||
|
|
@ -126868,13 +126881,16 @@ class TransformControl {
|
|||
{ // Keep gizmo screen size constant
|
||||
let lastDist = -1;
|
||||
const setRootNodeScale = size => {
|
||||
if (rootNode.scale[0] !== size) {
|
||||
rootNode.scale = [size, size, size];
|
||||
this._baseRootScale = size;
|
||||
const styledSize = size * (this._styleScale || 1);
|
||||
if (rootNode.scale[0] !== styledSize) {
|
||||
rootNode.scale = [styledSize, styledSize, styledSize];
|
||||
if (this._handlers && this._handlers.onScreenScale) {
|
||||
this._handlers.onScreenScale(rootNode.scale);
|
||||
}
|
||||
}
|
||||
};
|
||||
this._applyRootScale = () => setRootNodeScale(this._baseRootScale || rootNode.scale[0] || 5);
|
||||
const onSceneTick = scene.on("tick", () => {
|
||||
const camera = scene.camera;
|
||||
const dist = Math.abs(math.distVec3(camera.eye, pos));
|
||||
|
|
@ -127030,6 +127046,19 @@ class TransformControl {
|
|||
this.__destroy();
|
||||
}
|
||||
|
||||
setStyle(style = {}) {
|
||||
if (style.gizmoDiameter !== undefined) {
|
||||
this._styleScale = style.gizmoDiameter;
|
||||
this._applyRootScale?.();
|
||||
}
|
||||
if (style.axes) {
|
||||
this._displayMeshes.x?.setColor?.(style.axes.x);
|
||||
this._displayMeshes.y?.setColor?.(style.axes.y);
|
||||
this._displayMeshes.z?.setColor?.(style.axes.z);
|
||||
}
|
||||
this._rootNode?.scene?.glRedraw?.();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to assign this Control to Handlers.
|
||||
* Call with a null or undefined value to disconnect the Control from whatever Handlers it was assigned to.
|
||||
|
|
@ -127703,7 +127732,7 @@ class SectionPlanesPlugin extends Plugin {
|
|||
const planeRoot = (function() {
|
||||
const rootNode = new Node$1(scene, { isObject: false });
|
||||
|
||||
rootNode.addChild(new Mesh(rootNode, { // plane
|
||||
const planeMesh = rootNode.addChild(new Mesh(rootNode, { // plane
|
||||
geometry: new ReadableGeometry(rootNode, {
|
||||
primitive: "triangles",
|
||||
positions: [
|
||||
|
|
@ -127737,7 +127766,7 @@ class SectionPlanesPlugin extends Plugin {
|
|||
isObject: false
|
||||
}));
|
||||
|
||||
rootNode.addChild(new Mesh(rootNode, { // Visible frame
|
||||
const frameMesh = rootNode.addChild(new Mesh(rootNode, { // Visible frame
|
||||
geometry: new ReadableGeometry(rootNode, buildTorusGeometry({
|
||||
center: [0, 0, 0],
|
||||
radius: 1.7,
|
||||
|
|
@ -127769,6 +127798,38 @@ class SectionPlanesPlugin extends Plugin {
|
|||
isObject: false
|
||||
}));
|
||||
|
||||
const setPhongMaterial = (material, color, alpha) => {
|
||||
if (!material) {
|
||||
return;
|
||||
}
|
||||
if (color) {
|
||||
material.diffuse = color;
|
||||
material.emissive = color;
|
||||
}
|
||||
if (alpha !== undefined) {
|
||||
material.alpha = alpha;
|
||||
material.alphaMode = alpha < 1 ? "blend" : "opaque";
|
||||
}
|
||||
};
|
||||
|
||||
const setEmphasisMaterial = (material, fillColor, fillAlpha, edgeColor, edgeAlpha) => {
|
||||
if (!material) {
|
||||
return;
|
||||
}
|
||||
if (fillColor) {
|
||||
material.fillColor = fillColor;
|
||||
}
|
||||
if (fillAlpha !== undefined) {
|
||||
material.fillAlpha = fillAlpha;
|
||||
}
|
||||
if (edgeColor) {
|
||||
material.edgeColor = edgeColor;
|
||||
}
|
||||
if (edgeAlpha !== undefined) {
|
||||
material.edgeAlpha = edgeAlpha;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
setPosition: (function() {
|
||||
const origin = math.vec3();
|
||||
|
|
@ -127781,7 +127842,26 @@ class SectionPlanesPlugin extends Plugin {
|
|||
})(),
|
||||
setQuaternion: q => { rootNode.quaternion = q; },
|
||||
setScale: s => { rootNode.scale = s; },
|
||||
setVisible: v => { rootNode.visible = v; }
|
||||
setVisible: v => { rootNode.visible = v; },
|
||||
setStyle: (style = {}) => {
|
||||
setPhongMaterial(planeMesh.material, style.planeFillColor, style.planeFillAlpha);
|
||||
setEmphasisMaterial(
|
||||
planeMesh.ghostMaterial,
|
||||
style.planeFillColor,
|
||||
style.planeFillAlpha,
|
||||
style.planeEdgeColor,
|
||||
style.planeEdgeAlpha
|
||||
);
|
||||
planeMesh.opacity = style.planeFillAlpha;
|
||||
setPhongMaterial(frameMesh.material, style.planeEdgeColor, style.planeEdgeAlpha);
|
||||
setEmphasisMaterial(
|
||||
frameMesh.highlightMaterial,
|
||||
style.planeEdgeColor,
|
||||
style.planeEdgeAlpha,
|
||||
style.planeEdgeColor,
|
||||
style.planeEdgeAlpha
|
||||
);
|
||||
}
|
||||
};
|
||||
})();
|
||||
let unbindSectionPlane = () => { };
|
||||
|
|
@ -127803,6 +127883,10 @@ class SectionPlanesPlugin extends Plugin {
|
|||
},
|
||||
setCulled: c => { culled = c; updateVisible(); },
|
||||
setVisible: v => { visible = v; updateVisible(); },
|
||||
setStyle: style => {
|
||||
planeRoot.setStyle?.(style);
|
||||
ctrl.setStyle?.(style);
|
||||
},
|
||||
_setSectionPlane: sectionPlane => {
|
||||
unbindSectionPlane();
|
||||
if (sectionPlane) {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,14 @@ const defaultSettings = {
|
|||
measureLabel: "#c4ff67",
|
||||
measureLabelText: "#292929",
|
||||
measureDot: "#c4ff67",
|
||||
sectionAxisX: "#ff2b2b",
|
||||
sectionAxisY: "#35ff4f",
|
||||
sectionAxisZ: "#285bff",
|
||||
sectionGizmoDiameter: 1,
|
||||
sectionPlaneFill: "#606060",
|
||||
sectionPlaneAlpha: 0.32,
|
||||
sectionPlaneEdge: "#0d0d0d",
|
||||
sectionPlaneEdgeAlpha: 0.8,
|
||||
};
|
||||
|
||||
const STORAGE_KEY = "bimdc-settings-v3";
|
||||
|
|
@ -109,6 +117,14 @@ const applySettings = (s) => {
|
|||
root.style.setProperty("--measure-label", s.measureLabel);
|
||||
root.style.setProperty("--measure-label-text", s.measureLabelText);
|
||||
root.style.setProperty("--measure-dot", s.measureDot);
|
||||
root.style.setProperty("--section-axis-x", s.sectionAxisX);
|
||||
root.style.setProperty("--section-axis-y", s.sectionAxisY);
|
||||
root.style.setProperty("--section-axis-z", s.sectionAxisZ);
|
||||
root.style.setProperty("--section-gizmo-diameter", s.sectionGizmoDiameter);
|
||||
root.style.setProperty("--section-plane-fill", s.sectionPlaneFill);
|
||||
root.style.setProperty("--section-plane-alpha", s.sectionPlaneAlpha);
|
||||
root.style.setProperty("--section-plane-edge", s.sectionPlaneEdge);
|
||||
root.style.setProperty("--section-plane-edge-alpha", s.sectionPlaneEdgeAlpha);
|
||||
// подсветка объектов
|
||||
root.style.setProperty("--highlight-color", s.highlight);
|
||||
};
|
||||
|
|
@ -352,6 +368,50 @@ export function createSettingsMenu({ panel, controls = {}, onChange = null, onSh
|
|||
});
|
||||
panel.appendChild(navCube);
|
||||
|
||||
const sectionCut = section("Разрез / сечение");
|
||||
addColor(sectionCut, "Ось X", "sectionAxisX");
|
||||
addColor(sectionCut, "Ось Y", "sectionAxisY");
|
||||
addColor(sectionCut, "Ось Z", "sectionAxisZ");
|
||||
addSettingsSlider({
|
||||
parent: sectionCut,
|
||||
label: "Диаметр гизмо",
|
||||
value: Math.round(Math.max(0.5, Math.min(1.8, Number(state.sectionGizmoDiameter ?? 1))) * 100),
|
||||
min: 50,
|
||||
max: 180,
|
||||
step: 5,
|
||||
formatValue: (val) => `${Math.round(val)}%`,
|
||||
onChange: (val) => {
|
||||
setVal("sectionGizmoDiameter", Math.max(0.5, Math.min(1.8, Number(val) / 100)));
|
||||
},
|
||||
});
|
||||
addColor(sectionCut, "Плоскость", "sectionPlaneFill");
|
||||
addSettingsSlider({
|
||||
parent: sectionCut,
|
||||
label: "Прозрачность плоскости",
|
||||
value: Math.round(Math.max(0, Math.min(1, Number(state.sectionPlaneAlpha ?? 0.32))) * 100),
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 5,
|
||||
formatValue: (val) => `${Math.round(val)}%`,
|
||||
onChange: (val) => {
|
||||
setVal("sectionPlaneAlpha", Math.max(0, Math.min(1, Number(val) / 100)));
|
||||
},
|
||||
});
|
||||
addColor(sectionCut, "Обводка", "sectionPlaneEdge");
|
||||
addSettingsSlider({
|
||||
parent: sectionCut,
|
||||
label: "Прозрачность обводки",
|
||||
value: Math.round(Math.max(0, Math.min(1, Number(state.sectionPlaneEdgeAlpha ?? 0.8))) * 100),
|
||||
min: 0,
|
||||
max: 100,
|
||||
step: 5,
|
||||
formatValue: (val) => `${Math.round(val)}%`,
|
||||
onChange: (val) => {
|
||||
setVal("sectionPlaneEdgeAlpha", Math.max(0, Math.min(1, Number(val) / 100)));
|
||||
},
|
||||
});
|
||||
panel.appendChild(sectionCut);
|
||||
|
||||
const measure = section("Линейка");
|
||||
addColor(measure, "Линия/бордер", "measureLine");
|
||||
addColor(measure, "Плашка", "measureLabel");
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@ const PROJECT_THEME = {
|
|||
measureLabel: "#c4ff67",
|
||||
measureLabelText: "#292929",
|
||||
measureDot: "#c4ff67",
|
||||
sectionAxisX: "#ff2b2b",
|
||||
sectionAxisY: "#35ff4f",
|
||||
sectionAxisZ: "#285bff",
|
||||
sectionGizmoDiameter: 1,
|
||||
sectionPlaneFill: "#606060",
|
||||
sectionPlaneAlpha: 0.32,
|
||||
sectionPlaneEdge: "#0d0d0d",
|
||||
sectionPlaneEdgeAlpha: 0.8,
|
||||
};
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
|
|
|
|||
Loading…
Reference in New Issue