feat: 添加图片编辑器工具栏

This commit is contained in:
Zhukj
2026-04-18 13:56:53 +08:00
parent cb6b88d455
commit 10bbf83e82
4 changed files with 119 additions and 19 deletions

View File

@@ -15,11 +15,13 @@
const longPressTip = document.getElementById('longPressTip');
const canvasArea = document.getElementById('canvasArea');
const textEditorToolbar = document.getElementById('textEditorToolbar');
const imageEditorToolbar = document.getElementById('imageEditorToolbar');
const boldBtn = document.getElementById('boldBtn');
const italicBtn = document.getElementById('italicBtn');
const colorPicker = document.getElementById('colorPicker');
const fontPicker = document.getElementById('fontPicker');
const fontSizePicker = document.getElementById('fontSizePicker');
const opacityPicker = document.getElementById('opacityPicker');
const overlayLayer = document.getElementById('overlayLayer');
const overlayInput = document.createElement('input');
overlayInput.type = 'file';
@@ -142,8 +144,9 @@
}
// 隐藏辅助线
hideGuides();
// 隐藏文本编辑器工具栏
// 隐藏文本编辑器工具栏和图片编辑器工具栏
textEditorToolbar.classList.remove('active');
imageEditorToolbar.classList.remove('active');
}
// 点击空白区域(不是层叠图和输入框)
@@ -307,12 +310,16 @@
let isDragging = false;
let isResizing = false;
let startX, startY, startLeft, startTop, startWidth, startHeight;
let hasMoved = false;
const minSize = 30;
// 点击选中(区分点击和拖拽)
overlayEl.addEventListener('click', (e) => {
e.stopPropagation();
selectOverlay(overlayEl);
if (!hasMoved) {
selectOverlay(overlayEl);
}
hasMoved = false;
});
// 拖拽移动(不选中也可拖动)
@@ -329,6 +336,7 @@
const clientY = isTouch ? e.touches[0].clientY : e.clientY;
isDragging = true;
hasMoved = false;
startX = clientX;
startY = clientY;
startLeft = overlayEl.offsetLeft;
@@ -336,7 +344,6 @@
overlayEl.classList.add('dragging');
// 拖动时设置为选中状态
selectOverlay(overlayEl);
document.addEventListener('mousemove', handleDragMove);
@@ -357,21 +364,10 @@
const moveDistance = Math.sqrt(dx * dx + dy * dy);
if (moveDistance > 5) {
hasMoved = true;
let newLeft = startLeft + dx;
let newTop = startTop + dy;
// 使用吸附功能
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';
}
@@ -382,7 +378,6 @@
function handleDragEnd() {
isDragging = false;
overlayEl.classList.remove('dragging');
hideGuides();
document.removeEventListener('mousemove', handleDragMove);
document.removeEventListener('mouseup', handleDragEnd);
@@ -506,6 +501,15 @@
}
selectedOverlay = overlayEl;
overlayEl.classList.add('selected');
// 显示图片编辑器工具栏,隐藏文本编辑器工具栏
imageEditorToolbar.classList.add('active');
textEditorToolbar.classList.remove('active');
// 更新透明度值显示
const currentOpacity = Math.round(parseFloat(overlayEl.style.opacity || 1) * 100);
opacityValue = currentOpacity;
opacityValueEl.textContent = currentOpacity;
}
// 计算图片滑动边界
@@ -597,6 +601,11 @@
return;
}
// 如果点击的是层叠图,不处理图片滑动(让层叠图的拖拽处理)
if (e.target.closest('.overlay-image')) {
return;
}
// 如果正在编辑,先退出编辑状态
if (editingInput) {
deselectAll();
@@ -837,8 +846,9 @@
element.classList.remove('editing');
element.contentEditable = 'false';
// 显示文本编辑器工具栏
// 显示文本编辑器工具栏,隐藏图片编辑器工具栏
textEditorToolbar.classList.add('active');
imageEditorToolbar.classList.remove('active');
// 更新工具栏状态
updateToolbarState(element);
@@ -857,8 +867,9 @@
element.classList.remove('selected');
element.contentEditable = 'true';
// 显示文本编辑器工具栏
// 显示文本编辑器工具栏,隐藏图片编辑器工具栏
textEditorToolbar.classList.add('active');
imageEditorToolbar.classList.remove('active');
// 更新工具栏状态
updateToolbarState(element);
@@ -1314,8 +1325,13 @@
selectedInput.classList.remove('selected');
selectedInput = null;
}
// 隐藏文本编辑器工具栏
if (selectedOverlay) {
selectedOverlay.classList.remove('selected');
selectedOverlay = null;
}
// 隐藏所有工具栏
textEditorToolbar.classList.remove('active');
imageEditorToolbar.classList.remove('active');
}
// 初始化长按保存(只在3:5预览区域)
@@ -1468,6 +1484,45 @@
updateFontSize(currentSize + delta, true);
}
}, { passive: false });
// 透明度选择器 - 密码锁式滚轮
let opacityValue = 100;
const opacityRoller = document.getElementById('opacityPicker');
const opacityValueEl = opacityRoller.querySelector('.roller-value');
const opacityUpBtn = opacityRoller.querySelector('.roller-up');
const opacityDownBtn = opacityRoller.querySelector('.roller-down');
function updateOpacity(newOpacity, forceUpdate = false) {
newOpacity = Math.max(0, Math.min(100, newOpacity));
if (selectedOverlay) {
selectedOverlay.style.opacity = newOpacity / 100;
opacityValue = newOpacity;
opacityValueEl.textContent = newOpacity;
} else {
opacityValue = newOpacity;
opacityValueEl.textContent = newOpacity;
}
}
opacityUpBtn.addEventListener('click', () => {
if (selectedOverlay) {
updateOpacity(opacityValue + 5, true);
}
});
opacityDownBtn.addEventListener('click', () => {
if (selectedOverlay) {
updateOpacity(opacityValue - 5, true);
}
});
opacityRoller.addEventListener('wheel', (e) => {
e.preventDefault();
if (selectedOverlay) {
const delta = e.deltaY > 0 ? -5 : 5;
updateOpacity(opacityValue + delta, true);
}
}, { passive: false });
}
// 显示右键菜单