From f4a21e6974b025c4406a2682f9b0a387f63d54f4 Mon Sep 17 00:00:00 2001 From: Tot Maxim Date: Mon, 11 May 2026 14:22:05 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BB=D0=B0=D0=B3=20=D0=BB=D0=B5=D0=B9=D0=B0?= =?UTF-8?q?=D1=83=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/server/web/css/style.css | 49 ++++--------------- cmd/server/web/js/layout.js | 91 +++++++++++++----------------------- 2 files changed, 42 insertions(+), 98 deletions(-) diff --git a/cmd/server/web/css/style.css b/cmd/server/web/css/style.css index 06f0da8..5961092 100644 --- a/cmd/server/web/css/style.css +++ b/cmd/server/web/css/style.css @@ -218,7 +218,7 @@ h1 { opacity: 0; } -/* ===== SPLIT LAYOUT ===== */ +/* ===== SPLIT LAYOUT (FIXED) ===== */ .layout { display: flex; height: calc(100vh - 60px); @@ -227,44 +227,44 @@ h1 { padding: 0; } +/* панели */ .panel { height: 100%; overflow-y: auto; overflow-x: hidden; } +/* LEFT */ .left { - flex: 1 1 auto; + flex: 1; min-width: 300px; padding: 10px; - transition: flex 0.3s ease; } +/* RIGHT */ .right { flex: 0 0 40%; min-width: 0; background: black; position: relative; - transition: flex 0.3s ease, min-width 0.3s ease, opacity 0.3s ease; overflow: hidden; } .right.hidden { flex: 0 0 0 !important; - min-width: 0 !important; width: 0 !important; + min-width: 0 !important; opacity: 0; pointer-events: none; } -/* DRAG BAR */ +/* ===== RESIZER ===== */ .resizer { width: 8px; min-width: 8px; cursor: col-resize; background: #00ff88; opacity: 0.3; - transition: opacity 0.2s, width 0.3s ease, min-width 0.3s ease; flex-shrink: 0; z-index: 10; } @@ -273,10 +273,6 @@ h1 { opacity: 0.8; } -.resizer:active { - opacity: 1; -} - .resizer.hidden { width: 0 !important; min-width: 0 !important; @@ -284,24 +280,12 @@ h1 { pointer-events: none; } -/* Когда камера скрыта, левая панель занимает всё пространство */ -.layout:has(.right.hidden) .left { - flex: 1 1 100% !important; -} - -/* ===== CAMERA ===== */ +/* камера */ .cam-modal { height: 100%; display: flex; flex-direction: column; background: black; - opacity: 1; - transition: opacity 0.2s ease; -} - -.right.hidden .cam-modal { - opacity: 0; - transition: opacity 0.2s ease; } .cam-header { @@ -319,19 +303,12 @@ h1 { background: black; } -.cam-loading { - display: flex; - align-items: center; - justify-content: center; - color: #00ff88; -} - -/* ===== CAMERA BUTTON ===== */ +/* кнопка камеры */ .cam-btn { position: fixed; top: 20px; right: 20px; - z-index: 1001; + z-index: 9999; padding: 10px 15px; background: rgba(0, 0, 0, 0.8); color: #00ff88; @@ -343,16 +320,10 @@ h1 { display: flex; align-items: center; gap: 8px; - transition: all 0.3s; } .cam-btn:hover { background: rgba(0, 255, 136, 0.2); - box-shadow: 0 0 15px rgba(0, 255, 136, 0.3); -} - -.cam-btn-icon { - font-size: 18px; } /* ===== MOBILE ===== */ diff --git a/cmd/server/web/js/layout.js b/cmd/server/web/js/layout.js index 632c8df..7a1613f 100644 --- a/cmd/server/web/js/layout.js +++ b/cmd/server/web/js/layout.js @@ -1,51 +1,38 @@ //layout.js let leftPanel, rightPanel, dragBar; let isDragging = false; +let pendingX = null; export function initResize() { leftPanel = document.getElementById("leftPanel"); rightPanel = document.getElementById("rightPanel"); dragBar = document.getElementById("dragBar"); - if (!leftPanel || !rightPanel || !dragBar) { - console.warn("[layout] Элементы не найдены"); - return; - } + if (!leftPanel || !rightPanel || !dragBar) return; - console.log("[layout] Инициализация ресайза"); - - // Загрузка сохранённых пропорций const savedRatio = localStorage.getItem('layoutRatio'); if (savedRatio) { - const ratio = parseFloat(savedRatio); - applyRatio(ratio); + applyRatio(parseFloat(savedRatio)); } dragBar.addEventListener("mousedown", (e) => { if (rightPanel.classList.contains("hidden")) return; - - console.log("[layout] mousedown на resizer"); + isDragging = true; document.body.style.cursor = "col-resize"; - document.body.style.userSelect = "none"; e.preventDefault(); - e.stopPropagation(); }); document.addEventListener("mouseup", () => { - if (isDragging) { - console.log("[layout] mouseup - конец перетаскивания"); - isDragging = false; - document.body.style.cursor = "default"; - document.body.style.userSelect = ""; - - // Сохраняем пропорции только если камера открыта - if (!rightPanel.classList.contains("hidden")) { - const total = window.innerWidth; - const leftWidth = leftPanel.getBoundingClientRect().width; - const ratio = leftWidth / total; - localStorage.setItem('layoutRatio', ratio.toString()); - } + if (!isDragging) return; + + isDragging = false; + document.body.style.cursor = "default"; + + if (!rightPanel.classList.contains("hidden")) { + const total = window.innerWidth; + const leftWidth = leftPanel.getBoundingClientRect().width; + localStorage.setItem('layoutRatio', leftWidth / total); } }); @@ -53,58 +40,44 @@ export function initResize() { if (!isDragging) return; if (rightPanel.classList.contains("hidden")) return; - const total = window.innerWidth; - let leftWidth = e.clientX; + pendingX = e.clientX; - const minWidth = 300; - if (leftWidth < minWidth) leftWidth = minWidth; - if (leftWidth > total - minWidth) leftWidth = total - minWidth; + requestAnimationFrame(() => { + if (pendingX === null) return; - const rightWidth = total - leftWidth - dragBar.offsetWidth; + const total = window.innerWidth; + let leftWidth = pendingX; - leftPanel.style.flex = `0 0 ${leftWidth}px`; - leftPanel.style.width = `${leftWidth}px`; - rightPanel.style.flex = `0 0 ${rightWidth}px`; - rightPanel.style.width = `${rightWidth}px`; - }); + const min = 300; + if (leftWidth < min) leftWidth = min; + if (leftWidth > total - min) leftWidth = total - min; - window.addEventListener("resize", () => { - if (rightPanel.classList.contains("hidden")) return; - - const total = window.innerWidth; - const leftWidth = leftPanel.getBoundingClientRect().width; - const ratio = leftWidth / total; - if (ratio > 0.2 && ratio < 0.8) { - applyRatio(ratio); - } + const rightWidth = total - leftWidth - dragBar.offsetWidth; + + leftPanel.style.flex = `0 0 ${leftWidth}px`; + rightPanel.style.flex = `0 0 ${rightWidth}px`; + + pendingX = null; + }); }); } function applyRatio(ratio) { const total = window.innerWidth; const leftWidth = Math.floor(total * ratio); - const rightWidth = total - leftWidth - dragBar.offsetWidth; - + const rightWidth = total - leftWidth; + leftPanel.style.flex = `0 0 ${leftWidth}px`; - leftPanel.style.width = `${leftWidth}px`; rightPanel.style.flex = `0 0 ${rightWidth}px`; - rightPanel.style.width = `${rightWidth}px`; } export function updateResizerVisibility() { if (!dragBar || !rightPanel) return; - + if (rightPanel.classList.contains("hidden")) { dragBar.classList.add("hidden"); - // Сбрасываем инлайн-стили левой панели, чтобы CSS flex заработал - leftPanel.style.flex = ""; - leftPanel.style.width = ""; + leftPanel.style.flex = "1"; } else { dragBar.classList.remove("hidden"); - // Восстанавливаем сохранённые пропорции - const savedRatio = localStorage.getItem('layoutRatio'); - if (savedRatio) { - applyRatio(parseFloat(savedRatio)); - } } } \ No newline at end of file