fix: 修复背景图无法左右移动的问题

This commit is contained in:
Zhukj
2026-04-17 15:16:33 +08:00
parent 56e5aad22f
commit a4360e5d3b
3 changed files with 134 additions and 5 deletions

View File

@@ -54,7 +54,7 @@
14. 字号逻辑调整,输入框字号只在自身原本字号上增减 14. 字号逻辑调整,输入框字号只在自身原本字号上增减
15. 文本输入框添加辅助线,完善辅助线的吸附逻辑更加精准,辅助线颜色为红色 15. 文本输入框添加辅助线,完善辅助线的吸附逻辑更加精准,辅助线颜色为红色
16. 顶部工具栏新增层叠图,可添加多张层叠图,单击选中状态可缩放删除自由移动位置,置于背景图之上,输入框与层叠图点击只能同时选中一个 16. 顶部工具栏新增层叠图,可添加多张层叠图,单击选中状态可缩放删除自由移动位置,置于背景图之上,输入框与层叠图点击只能同时选中一个
17. 层叠图添加辅助线

View File

@@ -229,7 +229,7 @@ html, body {
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
pointer-events: auto; pointer-events: none;
z-index: 6; z-index: 6;
} }

View File

@@ -251,6 +251,8 @@
function handleDragStart(e) { function handleDragStart(e) {
if (e.target.classList.contains('delete-btn') || e.target.classList.contains('resize-handle')) return; if (e.target.classList.contains('delete-btn') || e.target.classList.contains('resize-handle')) return;
e.stopPropagation(); // 阻止事件冒泡到 imageContainer
const isTouch = e.type === 'touchstart'; const isTouch = e.type === 'touchstart';
const clientX = isTouch ? e.touches[0].clientX : e.clientX; const clientX = isTouch ? e.touches[0].clientX : e.clientX;
const clientY = isTouch ? e.touches[0].clientY : e.clientY; const clientY = isTouch ? e.touches[0].clientY : e.clientY;
@@ -263,6 +265,9 @@
overlayEl.classList.add('dragging'); overlayEl.classList.add('dragging');
// 拖动时设置为选中状态
selectOverlay(overlayEl);
document.addEventListener('mousemove', handleDragMove); document.addEventListener('mousemove', handleDragMove);
document.addEventListener('mouseup', handleDragEnd); document.addEventListener('mouseup', handleDragEnd);
document.addEventListener('touchmove', handleDragMove, { passive: false }); document.addEventListener('touchmove', handleDragMove, { passive: false });
@@ -284,8 +289,17 @@
let newLeft = startLeft + dx; let newLeft = startLeft + dx;
let newTop = startTop + dy; let newTop = startTop + dy;
newLeft = Math.max(-overlayEl.offsetWidth + minSize, Math.min(newLeft, imageContainer.offsetWidth - minSize)); // 使用吸附功能
newTop = Math.max(-overlayEl.offsetHeight + minSize, Math.min(newTop, imageContainer.offsetHeight - minSize)); const snapped = getSnapPosition(overlayEl, newLeft, newTop);
newLeft = snapped.left;
newTop = snapped.top;
// 显示对齐辅助线
if (snapped.showGuide) {
showAlignmentGuides(overlayEl);
} else {
hideGuides();
}
overlayEl.style.left = newLeft + 'px'; overlayEl.style.left = newLeft + 'px';
overlayEl.style.top = newTop + 'px'; overlayEl.style.top = newTop + 'px';
@@ -297,6 +311,7 @@
function handleDragEnd() { function handleDragEnd() {
isDragging = false; isDragging = false;
overlayEl.classList.remove('dragging'); overlayEl.classList.remove('dragging');
hideGuides();
document.removeEventListener('mousemove', handleDragMove); document.removeEventListener('mousemove', handleDragMove);
document.removeEventListener('mouseup', handleDragEnd); document.removeEventListener('mouseup', handleDragEnd);
@@ -897,8 +912,10 @@
snapYPos = cHeight; snapYPos = cHeight;
} }
// 检测其他元素对齐 // 检测其他元素对齐(输入框和层叠图)
const otherInputs = [input1, input2].filter(el => el && el !== draggedEl); const otherInputs = [input1, input2].filter(el => el && el !== draggedEl);
const otherOverlays = Array.from(overlayLayer.querySelectorAll('.overlay-image'))
.filter(el => el !== draggedEl);
for (const otherEl of otherInputs) { for (const otherEl of otherInputs) {
if (!otherEl) continue; if (!otherEl) continue;
@@ -959,6 +976,66 @@
} }
} }
// 检测层叠图之间对齐
for (const otherEl of otherOverlays) {
if (!otherEl) continue;
const oLeft = otherEl.offsetLeft;
const oTop = otherEl.offsetTop;
const oWidth = otherEl.offsetWidth;
const oHeight = otherEl.offsetHeight;
const oRight = oLeft + oWidth;
const oBottom = oTop + oHeight;
const oCenterX = oLeft + oWidth / 2;
const oCenterY = oTop + oHeight / 2;
// 垂直边缘对齐
if (Math.abs(elLeft - oLeft) < threshold) {
snapX = true;
snapXPos = oLeft;
}
if (Math.abs(elRight - oRight) < threshold) {
snapX = true;
snapXPos = oRight - elWidth;
}
if (Math.abs(elLeft - oRight) < threshold) {
snapX = true;
snapXPos = oRight;
}
if (Math.abs(elRight - oLeft) < threshold) {
snapX = true;
snapXPos = oLeft - elWidth;
}
// 水平边缘对齐
if (Math.abs(elTop - oTop) < threshold) {
snapY = true;
snapYPos = oTop;
}
if (Math.abs(elBottom - oBottom) < threshold) {
snapY = true;
snapYPos = oBottom - elHeight;
}
if (Math.abs(elTop - oBottom) < threshold) {
snapY = true;
snapYPos = oBottom;
}
if (Math.abs(elBottom - oTop) < threshold) {
snapY = true;
snapYPos = oTop - elHeight;
}
// 中心对齐
if (Math.abs(elCenterX - oCenterX) < threshold) {
snapX = true;
snapXPos = oCenterX - elWidth / 2;
}
if (Math.abs(elCenterY - oCenterY) < threshold) {
snapY = true;
snapYPos = oCenterY - elHeight / 2;
}
}
// 应用吸附 // 应用吸附
if (snapX && snapXPos !== null) { if (snapX && snapXPos !== null) {
snapLeft = snapXPos; snapLeft = snapXPos;
@@ -1030,6 +1107,8 @@
// 其他输入框对齐检测 // 其他输入框对齐检测
const otherInputs = [input1, input2].filter(el => el && el !== draggedEl); const otherInputs = [input1, input2].filter(el => el && el !== draggedEl);
const otherOverlays = Array.from(overlayLayer.querySelectorAll('.overlay-image'))
.filter(el => el !== draggedEl);
for (const otherEl of otherInputs) { for (const otherEl of otherInputs) {
if (!otherEl) continue; if (!otherEl) continue;
@@ -1080,6 +1159,56 @@
} }
} }
// 其他层叠图对齐检测
for (const otherEl of otherOverlays) {
if (!otherEl) continue;
const oLeft = otherEl.offsetLeft;
const oTop = otherEl.offsetTop;
const oWidth = otherEl.offsetWidth;
const oHeight = otherEl.offsetHeight;
const oRight = oLeft + oWidth;
const oBottom = oTop + oHeight;
const oCenterX = oLeft + oWidth / 2;
const oCenterY = oTop + oHeight / 2;
// 垂直边缘对齐
if (Math.abs(elLeft - oLeft) < threshold) {
guideVPos = oLeft;
}
if (Math.abs(elRight - oRight) < threshold) {
guideVPos = oRight;
}
if (Math.abs(elLeft - oRight) < threshold) {
guideVPos = oRight;
}
if (Math.abs(elRight - oLeft) < threshold) {
guideVPos = oLeft;
}
// 水平边缘对齐
if (Math.abs(elTop - oTop) < threshold) {
guideHPos = oTop;
}
if (Math.abs(elBottom - oBottom) < threshold) {
guideHPos = oBottom;
}
if (Math.abs(elTop - oBottom) < threshold) {
guideHPos = oBottom;
}
if (Math.abs(elBottom - oTop) < threshold) {
guideHPos = oTop;
}
// 中心对齐
if (Math.abs(elCenterX - oCenterX) < threshold) {
guideVPos = oCenterX;
}
if (Math.abs(elCenterY - oCenterY) < threshold) {
guideHPos = oCenterY;
}
}
if (guideHPos !== null) { if (guideHPos !== null) {
guideH.style.top = guideHPos + 'px'; guideH.style.top = guideHPos + 'px';
guideH.classList.add('visible'); guideH.classList.add('visible');