исправлен лаг лейаута

This commit is contained in:
Tot Maxim
2026-05-11 14:22:05 +03:00
parent 5433a036aa
commit f4a21e6974
2 changed files with 42 additions and 98 deletions

View File

@@ -218,7 +218,7 @@ h1 {
opacity: 0; opacity: 0;
} }
/* ===== SPLIT LAYOUT ===== */ /* ===== SPLIT LAYOUT (FIXED) ===== */
.layout { .layout {
display: flex; display: flex;
height: calc(100vh - 60px); height: calc(100vh - 60px);
@@ -227,44 +227,44 @@ h1 {
padding: 0; padding: 0;
} }
/* панели */
.panel { .panel {
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
} }
/* LEFT */
.left { .left {
flex: 1 1 auto; flex: 1;
min-width: 300px; min-width: 300px;
padding: 10px; padding: 10px;
transition: flex 0.3s ease;
} }
/* RIGHT */
.right { .right {
flex: 0 0 40%; flex: 0 0 40%;
min-width: 0; min-width: 0;
background: black; background: black;
position: relative; position: relative;
transition: flex 0.3s ease, min-width 0.3s ease, opacity 0.3s ease;
overflow: hidden; overflow: hidden;
} }
.right.hidden { .right.hidden {
flex: 0 0 0 !important; flex: 0 0 0 !important;
min-width: 0 !important;
width: 0 !important; width: 0 !important;
min-width: 0 !important;
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
} }
/* DRAG BAR */ /* ===== RESIZER ===== */
.resizer { .resizer {
width: 8px; width: 8px;
min-width: 8px; min-width: 8px;
cursor: col-resize; cursor: col-resize;
background: #00ff88; background: #00ff88;
opacity: 0.3; opacity: 0.3;
transition: opacity 0.2s, width 0.3s ease, min-width 0.3s ease;
flex-shrink: 0; flex-shrink: 0;
z-index: 10; z-index: 10;
} }
@@ -273,10 +273,6 @@ h1 {
opacity: 0.8; opacity: 0.8;
} }
.resizer:active {
opacity: 1;
}
.resizer.hidden { .resizer.hidden {
width: 0 !important; width: 0 !important;
min-width: 0 !important; min-width: 0 !important;
@@ -284,24 +280,12 @@ h1 {
pointer-events: none; pointer-events: none;
} }
/* Когда камера скрыта, левая панель занимает всё пространство */ /* камера */
.layout:has(.right.hidden) .left {
flex: 1 1 100% !important;
}
/* ===== CAMERA ===== */
.cam-modal { .cam-modal {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: black; background: black;
opacity: 1;
transition: opacity 0.2s ease;
}
.right.hidden .cam-modal {
opacity: 0;
transition: opacity 0.2s ease;
} }
.cam-header { .cam-header {
@@ -319,19 +303,12 @@ h1 {
background: black; background: black;
} }
.cam-loading { /* кнопка камеры */
display: flex;
align-items: center;
justify-content: center;
color: #00ff88;
}
/* ===== CAMERA BUTTON ===== */
.cam-btn { .cam-btn {
position: fixed; position: fixed;
top: 20px; top: 20px;
right: 20px; right: 20px;
z-index: 1001; z-index: 9999;
padding: 10px 15px; padding: 10px 15px;
background: rgba(0, 0, 0, 0.8); background: rgba(0, 0, 0, 0.8);
color: #00ff88; color: #00ff88;
@@ -343,16 +320,10 @@ h1 {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
transition: all 0.3s;
} }
.cam-btn:hover { .cam-btn:hover {
background: rgba(0, 255, 136, 0.2); 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 ===== */ /* ===== MOBILE ===== */

View File

@@ -1,51 +1,38 @@
//layout.js //layout.js
let leftPanel, rightPanel, dragBar; let leftPanel, rightPanel, dragBar;
let isDragging = false; let isDragging = false;
let pendingX = null;
export function initResize() { export function initResize() {
leftPanel = document.getElementById("leftPanel"); leftPanel = document.getElementById("leftPanel");
rightPanel = document.getElementById("rightPanel"); rightPanel = document.getElementById("rightPanel");
dragBar = document.getElementById("dragBar"); dragBar = document.getElementById("dragBar");
if (!leftPanel || !rightPanel || !dragBar) { if (!leftPanel || !rightPanel || !dragBar) return;
console.warn("[layout] Элементы не найдены");
return;
}
console.log("[layout] Инициализация ресайза");
// Загрузка сохранённых пропорций
const savedRatio = localStorage.getItem('layoutRatio'); const savedRatio = localStorage.getItem('layoutRatio');
if (savedRatio) { if (savedRatio) {
const ratio = parseFloat(savedRatio); applyRatio(parseFloat(savedRatio));
applyRatio(ratio);
} }
dragBar.addEventListener("mousedown", (e) => { dragBar.addEventListener("mousedown", (e) => {
if (rightPanel.classList.contains("hidden")) return; if (rightPanel.classList.contains("hidden")) return;
console.log("[layout] mousedown на resizer");
isDragging = true; isDragging = true;
document.body.style.cursor = "col-resize"; document.body.style.cursor = "col-resize";
document.body.style.userSelect = "none";
e.preventDefault(); e.preventDefault();
e.stopPropagation();
}); });
document.addEventListener("mouseup", () => { document.addEventListener("mouseup", () => {
if (isDragging) { if (!isDragging) return;
console.log("[layout] mouseup - конец перетаскивания");
isDragging = false; isDragging = false;
document.body.style.cursor = "default"; document.body.style.cursor = "default";
document.body.style.userSelect = "";
if (!rightPanel.classList.contains("hidden")) {
// Сохраняем пропорции только если камера открыта const total = window.innerWidth;
if (!rightPanel.classList.contains("hidden")) { const leftWidth = leftPanel.getBoundingClientRect().width;
const total = window.innerWidth; localStorage.setItem('layoutRatio', leftWidth / total);
const leftWidth = leftPanel.getBoundingClientRect().width;
const ratio = leftWidth / total;
localStorage.setItem('layoutRatio', ratio.toString());
}
} }
}); });
@@ -53,58 +40,44 @@ export function initResize() {
if (!isDragging) return; if (!isDragging) return;
if (rightPanel.classList.contains("hidden")) return; if (rightPanel.classList.contains("hidden")) return;
const total = window.innerWidth; pendingX = e.clientX;
let leftWidth = e.clientX;
const minWidth = 300; requestAnimationFrame(() => {
if (leftWidth < minWidth) leftWidth = minWidth; if (pendingX === null) return;
if (leftWidth > total - minWidth) leftWidth = total - minWidth;
const rightWidth = total - leftWidth - dragBar.offsetWidth; const total = window.innerWidth;
let leftWidth = pendingX;
leftPanel.style.flex = `0 0 ${leftWidth}px`; const min = 300;
leftPanel.style.width = `${leftWidth}px`; if (leftWidth < min) leftWidth = min;
rightPanel.style.flex = `0 0 ${rightWidth}px`; if (leftWidth > total - min) leftWidth = total - min;
rightPanel.style.width = `${rightWidth}px`;
});
window.addEventListener("resize", () => { const rightWidth = total - leftWidth - dragBar.offsetWidth;
if (rightPanel.classList.contains("hidden")) return;
leftPanel.style.flex = `0 0 ${leftWidth}px`;
const total = window.innerWidth; rightPanel.style.flex = `0 0 ${rightWidth}px`;
const leftWidth = leftPanel.getBoundingClientRect().width;
const ratio = leftWidth / total; pendingX = null;
if (ratio > 0.2 && ratio < 0.8) { });
applyRatio(ratio);
}
}); });
} }
function applyRatio(ratio) { function applyRatio(ratio) {
const total = window.innerWidth; const total = window.innerWidth;
const leftWidth = Math.floor(total * ratio); 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.flex = `0 0 ${leftWidth}px`;
leftPanel.style.width = `${leftWidth}px`;
rightPanel.style.flex = `0 0 ${rightWidth}px`; rightPanel.style.flex = `0 0 ${rightWidth}px`;
rightPanel.style.width = `${rightWidth}px`;
} }
export function updateResizerVisibility() { export function updateResizerVisibility() {
if (!dragBar || !rightPanel) return; if (!dragBar || !rightPanel) return;
if (rightPanel.classList.contains("hidden")) { if (rightPanel.classList.contains("hidden")) {
dragBar.classList.add("hidden"); dragBar.classList.add("hidden");
// Сбрасываем инлайн-стили левой панели, чтобы CSS flex заработал leftPanel.style.flex = "1";
leftPanel.style.flex = "";
leftPanel.style.width = "";
} else { } else {
dragBar.classList.remove("hidden"); dragBar.classList.remove("hidden");
// Восстанавливаем сохранённые пропорции
const savedRatio = localStorage.getItem('layoutRatio');
if (savedRatio) {
applyRatio(parseFloat(savedRatio));
}
} }
} }