重构uiController的图片查看器,增加键盘和触摸滑动导航功能
This commit is contained in:
310
script.js
310
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');
|
||||
|
||||
42
styles.css
42
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;
|
||||
|
||||
Reference in New Issue
Block a user