diff --git a/script.js b/script.js index c7531b1..07b1358 100644 --- a/script.js +++ b/script.js @@ -1012,137 +1012,59 @@ const uiController = { // 设置删除按钮功能 if (deleteButton) { - deleteButton.onclick = function() { - // 保存当前图像ID + deleteButton.onclick = async () => { const currentImageId = generatedImages[currentImageIndex].id; + await app.removeGeneratedImage(currentImageId); - // 删除当前图像 - app.removeGeneratedImage(currentImageId).then(() => { - // 检查删除后是否还有图像 - if (generatedImages.length === 0) { - // 没有图像了,关闭模态框 - currentModalInstance.hide(); - } else { - // 更新当前图像索引 - if (currentImageIndex >= generatedImages.length) { - // 如果删除的是最后一张,显示上一张 - currentImageIndex = generatedImages.length - 1; - } - // 如果索引仍然有效,显示图像 - if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) { - modalImage.src = generatedImages[currentImageIndex].url; - // 更新删除按钮对应的图像ID - deleteButton.onclick = function() { - const newCurrentImageId = generatedImages[currentImageIndex].id; - app.removeGeneratedImage(newCurrentImageId).then(() => { - // 再次检查删除后是否还有图像 - if (generatedImages.length === 0) { - currentModalInstance.hide(); - } else { - // 更新当前图像索引 - if (currentImageIndex >= generatedImages.length) { - currentImageIndex = generatedImages.length - 1; - } - // 如果索引仍然有效,显示图像 - if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) { - modalImage.src = generatedImages[currentImageIndex].url; - // 更新删除按钮对应的图像ID - deleteButton.onclick = arguments.callee; - } - } - }); - }; - } - - // 更新翻页按钮状态 - uiController.updateNavigationButtons(); + if (generatedImages.length === 0) { + currentModalInstance.hide(); + } else { + // 调整索引 + if (currentImageIndex >= generatedImages.length) { + currentImageIndex = generatedImages.length - 1; } - }); + + // 重新加载当前图像 + if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) { + modalImage.src = generatedImages[currentImageIndex].url; + } + + this.updateNavigationButtons(); + } }; } // 设置翻页按钮功能 if (prevButton) { - prevButton.onclick = function() { - if (currentImageIndex > 0) { - currentImageIndex--; - modalImage.src = generatedImages[currentImageIndex].url; - // 更新删除按钮对应的图像ID - deleteButton.onclick =async function() { - // 保存当前图像ID - const currentImageId = generatedImages[currentImageIndex].id; - - // 删除当前图像 - await app.removeGeneratedImage(currentImageId); - - // 检查删除后是否还有图像 - if (generatedImages.length === 0) { - // 没有图像了,关闭模态框 - currentModalInstance.hide(); - } else { - // 更新当前图像索引 - if (currentImageIndex >= generatedImages.length) { - // 如果删除的是最后一张,显示上一张 - currentImageIndex = generatedImages.length - 1; - } - // 如果索引仍然有效,显示图像 - if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) { - modalImage.src = generatedImages[currentImageIndex].url; - // 更新删除按钮对应的图像ID - deleteButton.onclick = arguments.callee; - } - - // 更新翻页按钮状态 - uiController.updateNavigationButtons(); - } - }; - } + prevButton.onclick = () => { + this.navigateToImage(-1); }; } if (nextButton) { - nextButton.onclick = function() { - if (currentImageIndex < generatedImages.length - 1) { - currentImageIndex++; - modalImage.src = generatedImages[currentImageIndex].url; - // 更新删除按钮对应的图像ID - deleteButton.onclick = function() { - // 保存当前图像ID - const currentImageId = generatedImages[currentImageIndex].id; - - // 删除当前图像 - app.removeGeneratedImage(currentImageId).then(() => { - // 检查删除后是否还有图像 - if (generatedImages.length === 0) { - // 没有图像了,关闭模态框 - currentModalInstance.hide(); - } else { - // 更新当前图像索引 - if (currentImageIndex >= generatedImages.length) { - // 如果删除的是最后一张,显示上一张 - currentImageIndex = generatedImages.length - 1; - } - // 如果索引仍然有效,显示图像 - if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) { - modalImage.src = generatedImages[currentImageIndex].url; - // 更新删除按钮对应的图像ID - deleteButton.onclick = arguments.callee; - } - - // 更新翻页按钮状态 - uiController.updateNavigationButtons(); - } - }); - }; - } + nextButton.onclick = () => { + this.navigateToImage(1); }; } // 更新翻页按钮状态 this.updateNavigationButtons(); + // 添加键盘事件监听器 + this.addModalKeyboardListeners(); + + // 添加触摸事件监听器 + this.addModalTouchListeners(modalImage); + // 创建并显示模态框 currentModalInstance = new bootstrap.Modal(modalElement); + + // 添加模态框关闭事件监听器 + modalElement.addEventListener('hidden.bs.modal', () => { + this.removeModalKeyboardListeners(); + this.removeModalTouchListeners(modalImage); + }); + currentModalInstance.show(); } catch (error) { @@ -1162,15 +1084,177 @@ const uiController = { const prevButton = document.getElementById('prevImageBtn'); const nextButton = document.getElementById('nextImageBtn'); + // 如果有多张图片,始终显示翻页按钮(因为支持循环导航) if (prevButton) { - prevButton.style.display = currentImageIndex > 0 ? 'block' : 'none'; + prevButton.style.display = generatedImages.length > 1 ? 'block' : 'none'; } if (nextButton) { - nextButton.style.display = currentImageIndex < generatedImages.length - 1 ? 'block' : 'none'; + nextButton.style.display = generatedImages.length > 1 ? 'block' : 'none'; } }, + // 添加模态框键盘事件监听器 + addModalKeyboardListeners: function() { + // 移除之前的监听器(如果存在) + this.removeModalKeyboardListeners(); + + // 添加键盘事件监听器 + this.modalKeyboardHandler = (e) => { + if (!currentModalInstance || !document.getElementById('imageViewerModal').classList.contains('show')) { + return; + } + + switch(e.key) { + case 'ArrowLeft': + case 'ArrowUp': + e.preventDefault(); + this.navigateToImage(-1); + break; + case 'ArrowRight': + case 'ArrowDown': + e.preventDefault(); + this.navigateToImage(1); + break; + case 'Escape': + e.preventDefault(); + currentModalInstance.hide(); + break; + } + }; + + document.addEventListener('keydown', this.modalKeyboardHandler); + }, + + // 移除模态框键盘事件监听器 + removeModalKeyboardListeners: function() { + if (this.modalKeyboardHandler) { + document.removeEventListener('keydown', this.modalKeyboardHandler); + this.modalKeyboardHandler = null; + } + }, + + // 添加模态框触摸事件监听器 + addModalTouchListeners: function(modalImage) { + if (!modalImage) return; + + // 移除之前的监听器(如果存在) + this.removeModalTouchListeners(modalImage); + + let startX = 0; + let startY = 0; + let isMoving = false; + const minSwipeDistance = 50; // 最小滑动距离 + const maxVerticalDistance = 100; // 最大垂直距离,超过则不视为翻页 + + this.modalTouchStartHandler = (e) => { + if (e.touches.length === 1) { + startX = e.touches[0].clientX; + startY = e.touches[0].clientY; + isMoving = false; + } + }; + + this.modalTouchMoveHandler = (e) => { + if (e.touches.length === 1) { + isMoving = true; + // 防止默认滚动行为 + e.preventDefault(); + } + }; + + this.modalTouchEndHandler = (e) => { + if (isMoving && e.changedTouches.length === 1) { + const endX = e.changedTouches[0].clientX; + const endY = e.changedTouches[0].clientY; + const deltaX = endX - startX; + const deltaY = endY - startY; + + // 检查是否为有效的水平滑动 + if (Math.abs(deltaX) > minSwipeDistance && Math.abs(deltaY) < maxVerticalDistance) { + if (deltaX > 0) { + // 向右滑动 - 上一张图片 + this.navigateToImage(-1); + } else { + // 向左滑动 - 下一张图片 + this.navigateToImage(1); + } + } + } + isMoving = false; + }; + + modalImage.addEventListener('touchstart', this.modalTouchStartHandler, { passive: false }); + modalImage.addEventListener('touchmove', this.modalTouchMoveHandler, { passive: false }); + modalImage.addEventListener('touchend', this.modalTouchEndHandler, { passive: true }); + }, + + // 移除模态框触摸事件监听器 + removeModalTouchListeners: function(modalImage) { + if (!modalImage) return; + + if (this.modalTouchStartHandler) { + modalImage.removeEventListener('touchstart', this.modalTouchStartHandler); + this.modalTouchStartHandler = null; + } + if (this.modalTouchMoveHandler) { + modalImage.removeEventListener('touchmove', this.modalTouchMoveHandler); + this.modalTouchMoveHandler = null; + } + if (this.modalTouchEndHandler) { + modalImage.removeEventListener('touchend', this.modalTouchEndHandler); + this.modalTouchEndHandler = null; + } + }, + + // 导航到指定图片 + navigateToImage: function(direction) { + if (generatedImages.length <= 1) return; + + let newIndex = currentImageIndex + direction; + + // 循环导航 + if (newIndex < 0) { + newIndex = generatedImages.length - 1; + } else if (newIndex >= generatedImages.length) { + newIndex = 0; + } + + currentImageIndex = newIndex; + + // 更新图片 + const modalImage = document.getElementById('viewerModalImage'); + const deleteButton = document.getElementById('viewerDeleteImage'); + + if (modalImage && generatedImages[currentImageIndex]) { + modalImage.src = generatedImages[currentImageIndex].url; + + // 更新删除按钮对应的图像ID + if (deleteButton) { + deleteButton.onclick = async function() { + const currentImageId = generatedImages[currentImageIndex].id; + await app.removeGeneratedImage(currentImageId); + + if (generatedImages.length === 0) { + currentModalInstance.hide(); + } else { + if (currentImageIndex >= generatedImages.length) { + currentImageIndex = generatedImages.length - 1; + } + if (currentImageIndex >= 0 && currentImageIndex < generatedImages.length) { + modalImage.src = generatedImages[currentImageIndex].url; + deleteButton.onclick = arguments.callee; + } + uiController.updateNavigationButtons(); + } + }; + } + } + + // 更新导航按钮状态 + this.updateNavigationButtons(); + }, + // 显示图像预览 displayImagePreview: function(imageData) { const preview = document.getElementById('imagePreview'); diff --git a/styles.css b/styles.css index e2c4182..f0e852a 100644 --- a/styles.css +++ b/styles.css @@ -434,6 +434,21 @@ body { align-items: center; justify-content: center; background-color: #000; + position: relative; +} + +/* 模态框图片触摸优化 */ +#viewerModalImage { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + touch-action: pan-x pan-y; + cursor: grab; +} + +#viewerModalImage:active { + cursor: grabbing; } /* 翻页按钮样式 */ @@ -471,6 +486,33 @@ body { color: white; } +/* 触摸反馈 */ +.modal-fullscreen .modal-body .btn-light:active { + transform: scale(0.95); +} + +/* 移动端响应式样式 */ +@media (max-width: 768px) { + .modal-fullscreen .modal-body .btn-light { + width: 40px; + height: 40px; + font-size: 16px; + } + + #prevImageBtn { + left: 10px; + } + + #nextImageBtn { + right: 10px; + } + + /* 为触摸设备优化图片显示 */ + #viewerModalImage { + touch-action: manipulation; + } +} + /* 图像查看模态框特定样式 */ #imageViewerModal .modal-content { border-radius: 15px;