feat: 新增文字移动实时显示网格辅助线
This commit is contained in:
102
js/script.js
102
js/script.js
@@ -38,6 +38,7 @@
|
||||
document.body.appendChild(overlayInput);
|
||||
const guideH = document.getElementById('guideH');
|
||||
const guideV = document.getElementById('guideV');
|
||||
const gridLines = document.getElementById('gridLines');
|
||||
|
||||
let currentImage = null;
|
||||
let bgImageScale = 1;
|
||||
@@ -207,6 +208,9 @@
|
||||
// 初始化文本编辑器工具栏
|
||||
initTextEditorToolbar();
|
||||
|
||||
// 初始化键盘微调功能
|
||||
initKeyboardNudge();
|
||||
|
||||
// 加载默认背景图
|
||||
loadDefaultBackground();
|
||||
|
||||
@@ -450,27 +454,23 @@
|
||||
const dx = clientX - startX;
|
||||
const dy = clientY - startY;
|
||||
|
||||
const moveDistance = Math.sqrt(dx * dx + dy * dy);
|
||||
if (moveDistance > 5) {
|
||||
let newLeft = startLeft + dx;
|
||||
let newTop = startTop + dy;
|
||||
// 移除移动距离限制,实现 1px 精确移动
|
||||
let newLeft = startLeft + dx;
|
||||
let newTop = startTop + dy;
|
||||
|
||||
// 使用吸附功能
|
||||
const snapped = getSnapPosition(overlayEl, newLeft, newTop);
|
||||
newLeft = snapped.left;
|
||||
newTop = snapped.top;
|
||||
// 使用吸附功能
|
||||
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.top = newTop + 'px';
|
||||
// 显示对齐辅助线(网格线已在 getSnapPosition 中显示)
|
||||
if (snapped.showGuide) {
|
||||
showAlignmentGuides(overlayEl);
|
||||
}
|
||||
|
||||
overlayEl.style.left = newLeft + 'px';
|
||||
overlayEl.style.top = newTop + 'px';
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
@@ -974,7 +974,8 @@
|
||||
Math.pow(clientY - clickStartY, 2)
|
||||
);
|
||||
|
||||
if (moveDistance > 5) {
|
||||
// 只要有移动就开始拖拽,实现 1px 精确移动
|
||||
if (moveDistance > 0) {
|
||||
hasMoved = true;
|
||||
if (dragTimer) {
|
||||
clearTimeout(dragTimer);
|
||||
@@ -997,11 +998,9 @@
|
||||
element.style.left = snapped.left + 'px';
|
||||
element.style.top = snapped.top + 'px';
|
||||
|
||||
// 显示对齐辅助线
|
||||
// 显示对齐辅助线(网格线已在 getSnapPosition 中显示)
|
||||
if (snapped.showGuide) {
|
||||
showAlignmentGuides(element);
|
||||
} else {
|
||||
hideGuides();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1217,11 +1216,16 @@
|
||||
const cCenterX = cWidth / 2;
|
||||
const cCenterY = cHeight / 2;
|
||||
|
||||
const threshold = 5;
|
||||
const threshold = 1;
|
||||
let snapLeft = newLeft;
|
||||
let snapTop = newTop;
|
||||
let showGuide = false;
|
||||
|
||||
// 显示网格线
|
||||
if (gridLines) {
|
||||
gridLines.classList.add('visible');
|
||||
}
|
||||
|
||||
// 水平垂直分别检测
|
||||
let snapX = false;
|
||||
let snapY = false;
|
||||
@@ -1257,7 +1261,7 @@
|
||||
}
|
||||
|
||||
// 检测其他元素对齐(输入框和层叠图)
|
||||
const otherInputs = [input1, input2].filter(el => el && el !== draggedEl);
|
||||
const otherInputs = [input1, input2, input3].filter(el => el && el !== draggedEl);
|
||||
const otherOverlays = Array.from(overlayLayer.querySelectorAll('.overlay-image'))
|
||||
.filter(el => el !== draggedEl);
|
||||
|
||||
@@ -1420,7 +1424,7 @@
|
||||
const elCenterX = elLeft + elWidth / 2;
|
||||
const elCenterY = elTop + elHeight / 2;
|
||||
|
||||
const threshold = 5;
|
||||
const threshold = 1;
|
||||
let guideHPos = null;
|
||||
let guideVPos = null;
|
||||
|
||||
@@ -1571,6 +1575,9 @@
|
||||
function hideGuides() {
|
||||
guideH.classList.remove('visible');
|
||||
guideV.classList.remove('visible');
|
||||
if (gridLines) {
|
||||
gridLines.classList.remove('visible');
|
||||
}
|
||||
}
|
||||
|
||||
// 取消所有选中
|
||||
@@ -1738,6 +1745,53 @@
|
||||
}, { passive: false });
|
||||
}
|
||||
|
||||
// 初始化键盘微调功能(方向键 1px 移动)
|
||||
function initKeyboardNudge() {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
// 如果正在编辑文本,不处理方向键
|
||||
if (editingInput) return;
|
||||
|
||||
// 获取当前选中的元素
|
||||
const targetEl = selectedInput || selectedOverlay;
|
||||
if (!targetEl) return;
|
||||
|
||||
// 防止默认行为(页面滚动)
|
||||
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
let currentLeft = parseInt(targetEl.style.left) || targetEl.offsetLeft;
|
||||
let currentTop = parseInt(targetEl.style.top) || targetEl.offsetTop;
|
||||
|
||||
switch(e.key) {
|
||||
case 'ArrowUp':
|
||||
currentTop -= 1;
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
currentTop += 1;
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
currentLeft -= 1;
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
currentLeft += 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// 应用新位置
|
||||
targetEl.style.left = currentLeft + 'px';
|
||||
targetEl.style.top = currentTop + 'px';
|
||||
|
||||
// 显示对齐辅助线(网格线已在 getSnapPosition 中显示)
|
||||
const snapped = getSnapPosition(targetEl, currentLeft, currentTop);
|
||||
if (snapped.showGuide) {
|
||||
showAlignmentGuides(targetEl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 显示右键菜单
|
||||
function showContextMenu(x, y) {
|
||||
hideContextMenu();
|
||||
|
||||
Reference in New Issue
Block a user