NODEDC_BIM_VIEWER/frontend/index.html

245 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BIM DC Viewer</title>
<link rel="icon" href="./assets/logo.svg">
<style id="preload-hidden">body{opacity:0;}</style>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700&display=swap">
<script src="./theme.js"></script>
<script>
// Apply persisted theme ASAP to avoid initial flash of defaults
(function () {
const STORAGE_KEY = "bimdc-settings-v3";
const LEGACY_KEYS = ["bimdc-settings", "bimdc-settings-v2"];
try {
LEGACY_KEYS.forEach((k) => localStorage.removeItem(k));
const project = window.__BIMDC_THEME__ || {};
const raw = localStorage.getItem(STORAGE_KEY);
let stored = null;
try {
stored = raw ? JSON.parse(raw) : null;
} catch (e) {
stored = null;
}
const storedVersion = stored && stored.themeVersion;
const projectVersion = project && project.themeVersion;
if (!stored || storedVersion !== projectVersion) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(project));
stored = { ...project };
}
const s = { ...(project || {}), ...(stored || {}) };
if (!Object.keys(s).length) return;
const root = document.documentElement;
const set = (k, v) => v !== undefined && root.style.setProperty(k, v);
set("--bg-outer", s.bgOuter);
set("--canvas-top", s.canvasTop);
set("--canvas-bottom", s.canvasBottom);
set("--loading-top", s.loadingTop);
set("--loading-bottom", s.loadingBottom);
set("--accent", s.accent);
set("--accent-2", s.accent2);
set("--template-fill", s.templateFill);
set("--template-outline", s.templateOutline);
set("--template-outline-hover", s.templateOutlineHover);
set("--template-glow-strength", `${s.templateGlow}%`);
set("--toolbar-bg", s.toolbarBg);
set("--toolbar-bg-active", s.toolbarBgActive);
set("--toolbar-border", s.toolbarBorder);
set("--toolbar-outline", s.toolbarOutline);
set("--modal-bg", s.modalBg);
set("--modal-focus", s.modalFocus);
set("--modal-border", s.modalBorder);
set("--modal-element", s.modalElement);
set("--modal-element-outline", s.modalElementOutline);
set("--modal-radius", s.modalRadius);
set("--project-btn-fill", s.projectBtnFill);
set("--project-btn-border", s.projectBtnBorder);
set("--project-btn-hover", s.projectBtnHover);
set("--modal-btn-primary", s.modalBtnPrimary);
set("--modal-btn-secondary", s.modalBtnSecondary);
set("--loader-color", s.loaderColor);
set("--border", s.border);
set("--text", s.text);
set("--panel", s.panel);
set("--panel-2", s.panel2);
set("--highlight-color", s.highlight);
set("--cube-text", s.navCubeText || s.cubeText);
set("--cube-edges", s.navCubeBase || s.cubeEdges);
set("--cube-base", s.navCubeBase || s.cubeEdges);
set("--cube-hover", s.navCubeHover);
set("--cube-edge-color", s.navCubeEdge);
set("--cube-edge-alpha", s.navCubeEdgeAlpha);
set("--plus-color", s.plus);
set("--measure-line", s.measureLine);
set("--measure-label", s.measureLabel);
set("--measure-label-text", s.measureLabelText);
set("--measure-dot", s.measureDot);
} catch (e) {
// ignore corrupted settings
}
}());
</script>
<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=8">
</head>
<body>
<header>
<button class="logo-btn" id="homeButton" title="Вернуться к старту"></button>
<div class="toolbar"></div>
<div class="hidden-controls" style="display:none">
<input type="checkbox" id="toggleEdges" checked>
<input type="checkbox" id="toggleTransparent" checked>
<input type="checkbox" id="addMode" checked>
<button id="fitView"></button>
</div>
</header>
<main class="main">
<section class="viewer-wrapper">
<canvas id="viewerCanvas"></canvas>
<canvas id="navCube"></canvas>
<div class="drop-hint" id="dropZone">
<div class="drop-center">
<div class="drop-plus">+</div>
<div class="drop-formats">
<div class="muted">IFC · BIM · LAS · LAZ</div>
<div class="muted">GLB · GLTF · OBJ · STL</div>
</div>
</div>
</div>
<div class="status-bar" id="status">
<span class="dot"></span>
<span id="statusText">Готов к загрузке</span>
</div>
<div class="loader hidden" id="loader">
<div class="loader__figure"></div>
<p class="loader__label">DC</p>
</div>
</section>
<aside class="side-panel">
<div class="panel-section">
<h3>Инспектор</h3>
<div id="treeContainer" class="tree"></div>
<div class="inspector-controls">
<div class="inspector-control-row inspector-control-row--half" id="displayModeControl">
<div class="inspector-control-label">Режим отображения</div>
<div class="inspector-select-host" id="displayModeSelect"></div>
</div>
<div class="inspector-control-row inspector-control-row--half" id="lightingModeControl">
<div class="inspector-control-label">Свет</div>
<div class="inspector-select-host" id="lightingModeSelect"></div>
</div>
<div class="inspector-control-row inspector-control-row--full" id="navigationAxisControl">
<div class="inspector-control-label">Ось навигации</div>
<div class="inspector-select-host" id="navigationAxisSelect"></div>
</div>
<div class="inspector-control-row inspector-control-row--full inspector-control-row--slider" id="zoomSpeedControl"></div>
</div>
</div>
<div class="panel-section" id="projectNameSection">
<h3>Название проекта</h3>
<input type="text" id="projectNameInput" class="project-name-input" placeholder="Проект" autocomplete="off">
<div class="error-text inline-error" id="projectNameError"></div>
</div>
<div class="panel-section">
<h3>Глобальные координаты</h3>
<div class="muted" style="margin-bottom:6px;">Центр выделения (мировые)</div>
<div class="transform-grid">
<label>X <input type="text" id="globalX"></label>
<label>Y <input type="text" id="globalY"></label>
<label>Z <input type="text" id="globalZ"></label>
</div>
</div>
<div class="panel-section">
<h3>Трансформации</h3>
<div class="muted" style="margin-bottom:6px;">Перемещение</div>
<div class="transform-grid">
<label>X <input type="text" id="posX"></label>
<label>Y <input type="text" id="posY"></label>
<label>Z <input type="text" id="posZ"></label>
</div>
<div class="muted" style="margin:8px 0 6px;">Вращение (deg)</div>
<div class="transform-grid">
<label>X <input type="text" id="rotX"></label>
<label>Y <input type="text" id="rotY"></label>
<label>Z <input type="text" id="rotZ"></label>
</div>
<div class="muted" style="margin:8px 0 6px;">Масштаб</div>
<div class="transform-grid">
<label>X <input type="text" id="scaleX"></label>
<label>Y <input type="text" id="scaleY"></label>
<label>Z <input type="text" id="scaleZ"></label>
</div>
<small id="transformHint" class="muted">Выберите объект в инспекторе или сцене, чтобы редактировать.</small>
</div>
<div class="panel-section">
<h3>Журнал</h3>
<div id="logList" class="log"></div>
</div>
<div class="panel-section" id="saveProjectSection">
<button class="secondary-btn model-settings-btn" id="saveModelSettingsButton" type="button">Сохранить настройки</button>
<button class="primary-btn" id="saveProjectButton" type="button">Сохранить проект</button>
<button class="secondary-btn danger-btn" id="deleteProjectButton" type="button">Удалить проект</button>
</div>
</aside>
</main>
<div id="templatesPanel" class="templates-panel hidden"></div>
<div id="settingsPanel" class="settings-panel hidden"></div>
<div id="measureModalBackdrop" class="modal-backdrop hidden"></div>
<div id="measureModal" class="templates-panel measurement-modal hidden"></div>
<div id="objectModalBackdrop" class="modal-backdrop hidden"></div>
<div id="objectModal" class="templates-panel measurement-modal hidden"></div>
<div id="saveProjectBackdrop" class="modal-backdrop hidden"></div>
<div id="saveProjectModal" class="save-project-modal hidden">
<div class="modal-header">
<div class="modal-title">Сохранить проект</div>
<button class="modal-close" id="saveProjectClose" aria-label="Закрыть">×</button>
</div>
<label for="saveProjectName" class="input-label">Имя проекта</label>
<input type="text" id="saveProjectName" placeholder="Новый проект" autocomplete="off">
<div class="input-hint" id="saveProjectHint">Введите имя, чтобы сохранить проект в хранилище</div>
<div class="modal-actions">
<button class="secondary-btn" id="saveProjectCancel" type="button">Отмена</button>
<button class="primary-btn" id="saveProjectConfirm" type="button" disabled>Сохранить</button>
<button class="secondary-btn" id="saveProjectDuplicate" type="button" disabled>Сохранить как новый</button>
</div>
<div class="error-text" id="saveProjectError"></div>
</div>
<div id="deleteProjectBackdrop" class="modal-backdrop hidden"></div>
<div id="deleteProjectModal" class="save-project-modal hidden">
<div class="modal-header">
<div class="modal-title">Удалить проект</div>
<button class="modal-close" id="deleteProjectClose" aria-label="Закрыть">×</button>
</div>
<div class="input-hint">Вы уверены, что хотите удалить проект?</div>
<div class="modal-actions">
<button class="secondary-btn" id="deleteProjectCancel" type="button">Отмена</button>
<button class="primary-btn danger-btn" id="deleteProjectConfirm" type="button">Удалить</button>
</div>
<div class="error-text" id="deleteProjectError"></div>
</div>
<div id="bottomToolbar" class="bottom-toolbar">
<button class="tb-btn" data-action="settings" title="Настройки"></button>
<button class="tb-btn" data-action="templates" title="Примеры">📂</button>
<button class="tb-btn" data-action="measure" title="Линейка">📏</button>
<button class="tb-btn" data-action="projection" title="Перспектива / аксонометрия">A</button>
<button class="tb-btn" data-action="add" title="Добавить файл"></button>
</div>
<input id="fileInput" class="hidden" type="file"
accept=".xkt,.glb,.gltf,.bim,.las,.laz,.obj,.stl">
<script type="module" src="./dcViewer.js?v=13"></script>
</body>
</html>