Initial import of NODEDC BIM Viewer

This commit is contained in:
CODEX
2026-06-04 13:25:42 +03:00
commit 9aaf82862f
2075 changed files with 3592575 additions and 0 deletions
+228
View File
@@ -0,0 +1,228 @@
<!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=3">
</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>
<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="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"></script>
</body>
</html>