исправлен лаг лейаута
This commit is contained in:
@@ -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 ===== */
|
||||||
|
|||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user