From 621958c0d442bf9012f67741d3d21882810bb7d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A5=D0=B0=D0=BB=D0=B8=D0=BC=D0=BE=D0=B2=20=D0=A0=D1=83?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BC?= Date: Sun, 11 Jan 2026 00:25:25 +0300 Subject: [PATCH] Font size for sizes --- src/components/LayoutStep.tsx | 111 ++++++++++++++++------------------ 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/src/components/LayoutStep.tsx b/src/components/LayoutStep.tsx index 25f691e..4d83fec 100644 --- a/src/components/LayoutStep.tsx +++ b/src/components/LayoutStep.tsx @@ -61,37 +61,40 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { }; const selectedData = getSelectedPartition(); - // Найти ближайшие границы для перегородки (или точки) - const getNearestNeighbors = (lx: number, ly: number, axis: Axis, parts: Partition[]) => { + // --- ИСПРАВЛЕННЫЙ РАСЧЕТ СОСЕДЕЙ ДЛЯ РАЗМЕРОВ --- + // targetOffset: позиция стенки (0..1) по её основной оси + // crossPos: позиция центра стенки по перпендикулярной оси (чтобы понять, пересекаются ли они) + // axis: ось самой стенки ('x' или 'y') + const getNearestNeighbors = (targetOffset: number, crossPos: number, axis: Axis, parts: Partition[]) => { let min = 0; let max = 1; parts.forEach(p => { - // Игнорируем саму себя, если это проверка для существующей стенки (но здесь мы передаем lx/ly точки) - const pMin = p.min ?? 0; const pMax = p.max ?? 1; - // Если мы ищем границы по X (для вертикальной стенки или пространства слева/справа) - // То нас интересуют другие ВЕРТИКАЛЬНЫЕ стенки (axis === 'x'), которые перекрывают нас по Y if (axis === 'x') { + // Мы - вертикальная стенка (X). Ищем другие ВЕРТИКАЛЬНЫЕ стенки слева/справа. if (p.axis === 'x') { - // Перекрываются ли диапазоны высоты? - // ly для точки - это просто координата. Для стенки это min-max. - // Здесь мы ищем границы для точки (lx, ly). - // Стенка P идет от pMin до pMax по Y. - if (ly > pMin && ly < pMax) { - if (p.offset < lx) min = Math.max(min, p.offset); - if (p.offset > lx) max = Math.min(max, p.offset); + // Они должны перекрываться с нами по высоте (Y) + // Наша "высота" - это точка crossPos (середина). + // Стенка P занимает по Y от pMin до pMax. + if (crossPos > pMin && crossPos < pMax) { + // Стенка P находится слева от нас? + if (p.offset < targetOffset) min = Math.max(min, p.offset); + // Стенка P находится справа от нас? + if (p.offset > targetOffset) max = Math.min(max, p.offset); } } } else { - // Ищем границы по Y (для горизонтальной стенки) - // Нас интересуют ГОРИЗОНТАЛЬНЫЕ стенки + // Мы - горизонтальная стенка (Y). Ищем другие ГОРИЗОНТАЛЬНЫЕ стенки сверху/снизу. if (p.axis === 'y') { - if (lx > pMin && lx < pMax) { - if (p.offset < ly) min = Math.max(min, p.offset); - if (p.offset > ly) max = Math.min(max, p.offset); + // Они должны перекрываться с нами по ширине (X) + // Наша "ширина" - это точка crossPos (середина). + // Стенка P занимает по X от pMin до pMax. + if (crossPos > pMin && crossPos < pMax) { + if (p.offset < targetOffset) min = Math.max(min, p.offset); + if (p.offset > targetOffset) max = Math.min(max, p.offset); } } } @@ -99,7 +102,7 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { return { min, max }; }; - // Расчет границ для НОВОЙ линии (перпендикулярной) + // Расчет границ для НОВОЙ линии (T-соединения) const getHoveredBoundaries = (lx: number, ly: number, parts: Partition[]) => { let minX = 0, maxX = 1; let minY = 0, maxY = 1; @@ -181,9 +184,8 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { const cellY1 = sortedY[j]; const cellY2 = sortedY[j+1]; let newOffset = 0; - // Текущие границы перетаскиваемой стенки (чтобы не выехать за пределы соседей) - // Для простоты пока используем границы ячейки (0-1), так как сложный пересчет соседей в реалтайме - это дорого - // Но визуально мы ограничим 2-98% + // Ограничиваем перетаскивание пределами "родительской" зоны + // Для T-соединений это сложнее, но пока ограничим ячейкой (0-1) if (dragging.axis === 'x') { newOffset = (nx - cellX1) / (cellX2 - cellX1); } else { @@ -330,24 +332,19 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { const parts = safePartitions[key] || []; const isSelected = parts.some(p => p.id === selectedPartitionId); - // Реальные размеры ячейки в мм + // Реальные размеры const realW = (x2 - x1) * drawerW; const realD = (y2 - y1) * drawerD; - // --- ЛЕЙБЛ РАЗМЕРА --- - // Если перегородок нет, показываем общий размер по центру + // Если перегородок нет - размер по центру if (parts.length === 0) { const labelX = cellX + cellW / 2; const labelY = cellY + cellH / 2; - // Учитываем толщину внешних стенок (или соседних) - // Упрощенно: вычитаем толщину (1 раз, т.к. 0.5 с каждой стороны) const textW = Math.max(0, realW - thickness).toFixed(0); const textD = Math.max(0, realD - thickness).toFixed(0); - - // Рисуем текст только если есть место if (cellH > 40 && cellW > 60) { elements.push( - + {textW} × {textD} ); @@ -360,11 +357,13 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { {parts.map(p => { const pMin = p.min ?? 0; const pMax = p.max ?? 1; - let lx1, ly1, lx2, ly2; // Координаты линии - let tx, ty; // Координаты текста - let dist1 = 0, dist2 = 0; // Расстояния до соседей (в мм) + let lx1, ly1, lx2, ly2; + let tx, ty; + let dist1 = 0, dist2 = 0; - // Находим соседей для расчета размеров + // Используем правильные координаты для поиска соседей + // axis='x' -> offset - это X, center - это Y + // axis='y' -> offset - это Y, center - это X const neighbors = getNearestNeighbors(p.offset, (pMin + pMax)/2, p.axis, parts); if (p.axis === 'x') { @@ -372,27 +371,23 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { lx1 = px; lx2 = px; ly1 = cellY + (cellH * pMin); ly2 = cellY + (cellH * pMax); - // Размеры слева и справа - const leftRatio = p.offset - neighbors.min; - const rightRatio = neighbors.max - p.offset; - dist1 = (leftRatio * realW) - thickness; // Left - dist2 = (rightRatio * realW) - thickness; // Right + // Distances Left/Right + // p.offset is 0..1. neighbor.min is 0..1. + // Distance = (current - neighbor) * width + dist1 = (p.offset - neighbors.min) * realW - thickness; + dist2 = (neighbors.max - p.offset) * realW - thickness; - tx = px; - ty = (ly1 + ly2) / 2; + tx = px; ty = (ly1 + ly2) / 2; } else { const py = cellY + (cellH * p.offset); ly1 = py; ly2 = py; lx1 = cellX + (cellW * pMin); lx2 = cellX + (cellW * pMax); - // Размеры сверху и снизу - const topRatio = p.offset - neighbors.min; - const botRatio = neighbors.max - p.offset; - dist1 = (topRatio * realD) - thickness; // Top - dist2 = (botRatio * realD) - thickness; // Bottom + // Distances Top/Bottom + dist1 = (p.offset - neighbors.min) * realD - thickness; + dist2 = (neighbors.max - p.offset) * realD - thickness; - tx = (lx1 + lx2) / 2; - ty = py; + tx = (lx1 + lx2) / 2; ty = py; } const isSel = selectedPartitionId === p.id; @@ -400,23 +395,22 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { return ( - {/* Сама линия */} { e.stopPropagation(); removePartition(key, p.id); }}> - {/* Текст размеров (Слева/Справа или Сверху/Снизу) */} - + {/* Размеры (только если есть место) */} + {p.axis === 'x' ? ( <> - {dist1.toFixed(0)} - {dist2.toFixed(0)} + {Math.max(0, dist1).toFixed(0)} + {Math.max(0, dist2).toFixed(0)} ) : ( <> - {dist1.toFixed(0)} - {dist2.toFixed(0)} + {Math.max(0, dist1).toFixed(0)} + {Math.max(0, dist2).toFixed(0)} )} @@ -480,7 +474,7 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { > setDragging(null)} onMouseLeave={() => setDragging(null)} onContextMenu={(e) => e.preventDefault()} + onMouseMove={handleGlobalMouseMove} onMouseDown={handleMouseDown} onMouseUp={() => setDragging(null)} onMouseLeave={() => setDragging(null)} onContextMenu={(e) => e.preventDefault()} > @@ -500,9 +494,8 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { ))} {/* Phantoms */} - {mode === 'lines' && !hoveredMainSplit && !dragging && phantomMainAxis && ( - - )} + {mode === 'lines' && !hoveredMainSplit && !dragging && phantomMainAxis === 'x' && } + {mode === 'lines' && !hoveredMainSplit && !dragging && phantomMainAxis === 'y' && }