fix(ui): prevent block content overlap

main
AlexsandrSnytkin 5 hours ago
parent 9a5fef27b8
commit 87f468bfd8

@ -2133,6 +2133,31 @@ HTML = """<!doctype html>
const scale = Math.max(.5, Math.min(2, Math.sqrt(area) * block._configUserScale));
block.style.setProperty('--block-scale', scale.toFixed(3));
}
function resolveConfigOverlaps() {
const gap = 14;
const items = configBlocks.filter(block => block && !configBlockState(block)).sort((a, b) => {
const top = (block => parseFloat(block.style.top) || block.offsetTop || 0);
return top(a) - top(b) || (parseFloat(a.style.left) || a.offsetLeft || 0) - (parseFloat(b.style.left) || b.offsetLeft || 0);
});
let moved = false;
items.forEach((block, index) => {
let top = parseFloat(block.style.top) || block.offsetTop || 0;
const left = parseFloat(block.style.left) || block.offsetLeft || 0;
const width = block.offsetWidth;
const height = block.offsetHeight;
items.slice(0, index).forEach(previous => {
const previousLeft = parseFloat(previous.style.left) || previous.offsetLeft || 0;
const previousTop = parseFloat(previous.style.top) || previous.offsetTop || 0;
const horizontal = left < previousLeft + previous.offsetWidth && previousLeft < left + width;
if (horizontal && top < previousTop + previous.offsetHeight + gap && top + height > previousTop) top = previousTop + previous.offsetHeight + gap;
});
if (top <= (parseFloat(block.style.top) || block.offsetTop || 0) + .5) return;
block.style.top = `${Math.round(top)}px`;
captureConfigLayout(block);
moved = true;
});
return moved;
}
function applyConfigContentScale(value) {
configContentScale = Math.max(.5, Math.min(2, (Number(value) || 100) / 100));
const block = selectedConfigBlock;
@ -2145,6 +2170,8 @@ HTML = """<!doctype html>
setText('configContentScaleValue', `${Math.round(configContentScale * 100)}%`);
updateConfigBlockScale(block);
updateConfigScaleToggle(block);
resolveConfigOverlaps();
updateConfigCanvasHeight();
saveConfigLayout();
}
function updateConfigScaleToggle(block) {
@ -2316,7 +2343,8 @@ HTML = """<!doctype html>
});
let fitted = false;
configBlocks.forEach(block => { fitted = fitConfigBlockContent(block) || fitted; updateConfigBlockScale(block); });
if (fitted) saveConfigLayout();
const separated = resolveConfigOverlaps();
if (fitted || separated) saveConfigLayout();
updateConfigCanvasHeight();
}
function setConfigBlockStates(blocks, state) {
@ -2562,6 +2590,7 @@ HTML = """<!doctype html>
group.forEach(item => captureConfigLayout(item));
if (droppedOnTrash) setConfigBlockStates(group, 'deleted');
else {
resolveConfigOverlaps();
saveConfigLayout();
setText('configLayoutState', `${configBlocks.length - configBlocks.filter(item => configBlockState(item)).length} блоков · раскладка сохранена`);
}
@ -2678,6 +2707,7 @@ HTML = """<!doctype html>
block.removeEventListener('pointercancel', end);
block.classList.remove('is-resizing');
captureConfigLayout(block);
resolveConfigOverlaps();
saveConfigLayout();
block._suppressSummaryClick = true;
window.setTimeout(() => { block._suppressSummaryClick = false; }, 0);
@ -2910,6 +2940,31 @@ HTML = """<!doctype html>
block._networkUserScale = Math.max(.5, Math.min(2, userScale));
block.style.setProperty('--block-scale', Math.max(.5, Math.min(2, Math.sqrt(area) * block._networkUserScale)).toFixed(3));
}
function resolveNetworkOverlaps() {
const gap = 14;
const items = networkBlocks.filter(block => block && !networkState(block)).sort((a, b) => {
const top = block => parseFloat(block.style.top) || block.offsetTop || 0;
return top(a) - top(b) || (parseFloat(a.style.left) || a.offsetLeft || 0) - (parseFloat(b.style.left) || b.offsetLeft || 0);
});
let moved = false;
items.forEach((block, index) => {
let top = parseFloat(block.style.top) || block.offsetTop || 0;
const left = parseFloat(block.style.left) || block.offsetLeft || 0;
const width = block.offsetWidth;
const height = block.offsetHeight;
items.slice(0, index).forEach(previous => {
const previousLeft = parseFloat(previous.style.left) || previous.offsetLeft || 0;
const previousTop = parseFloat(previous.style.top) || previous.offsetTop || 0;
const horizontal = left < previousLeft + previous.offsetWidth && previousLeft < left + width;
if (horizontal && top < previousTop + previous.offsetHeight + gap && top + height > previousTop) top = previousTop + previous.offsetHeight + gap;
});
if (top <= (parseFloat(block.style.top) || block.offsetTop || 0) + .5) return;
block.style.top = `${Math.round(top)}px`;
captureNetworkLayout(block);
moved = true;
});
return moved;
}
function selectNetworkBlock(block) {
selectedNetworkBlocks = new Set(block && !networkState(block) ? [block] : []);
updateNetworkSelection(block);
@ -2953,6 +3008,8 @@ HTML = """<!doctype html>
setText('networkContentScaleValue', `${Math.round(networkContentScale * 100)}%`);
updateNetworkBlockScale(block);
updateNetworkScaleToggle(block);
resolveNetworkOverlaps();
updateNetworkCanvasHeight();
saveNetworkLayout();
}
function updateNetworkScaleToggle(block) {
@ -3022,6 +3079,8 @@ HTML = """<!doctype html>
if (Number.isFinite(Number(entry.z))) { block.style.zIndex = String(Math.max(1, Number(entry.z))); networkZIndex = Math.max(networkZIndex, Number(entry.z)); }
updateNetworkBlockScale(block);
});
const separated = resolveNetworkOverlaps();
if (separated) saveNetworkLayout();
updateNetworkCanvasHeight();
}
function bringNetworkBlockFront(block) {
@ -3219,7 +3278,7 @@ HTML = """<!doctype html>
if (!dragged) return;
group.forEach(item => captureNetworkLayout(item));
if (droppedOnTrash) setNetworkBlockStates(group, 'deleted');
else { saveNetworkLayout(); renderNetworkStructure(); }
else { resolveNetworkOverlaps(); saveNetworkLayout(); renderNetworkStructure(); }
group.forEach(item => {
item._networkSuppressClick = true;
window.setTimeout(() => { item._networkSuppressClick = false; }, 0);
@ -3370,6 +3429,7 @@ HTML = """<!doctype html>
block.removeEventListener('pointercancel', end);
block.classList.remove('is-resizing');
captureNetworkLayout(block);
resolveNetworkOverlaps();
saveNetworkLayout();
block._networkSuppressClick = true;
window.setTimeout(() => { block._networkSuppressClick = false; }, 0);

Loading…
Cancel
Save