fix: align image container sizing and page width consistency

- Set tool page max-width to 1400px to match remove_background page
- Fix single image view to use same sizing logic as comparison view
- Add dynamic size calculation for processing images to match result view
- Ensure images maintain aspect ratio instead of filling container width
This commit is contained in:
jingrow 2025-12-21 14:35:55 +08:00
parent 8a4431075a
commit cf2c2022de

View File

@ -49,6 +49,8 @@ const splitPosition = ref(0)
const comparisonContainerRef = ref<HTMLElement | null>(null)
const originalImageRef = ref<HTMLImageElement | null>(null)
const resultImageRef = ref<HTMLImageElement | null>(null)
const singleImageWrapperRef = ref<HTMLElement | null>(null)
const singleImageRef = ref<HTMLImageElement | null>(null)
const isDraggingSplitLine = ref(false)
const handleDragEnter = (e: DragEvent) => {
@ -236,6 +238,10 @@ const resetUpload = () => {
comparisonContainerRef.value.style.width = ''
comparisonContainerRef.value.style.height = ''
}
if (singleImageWrapperRef.value) {
singleImageWrapperRef.value.style.width = ''
singleImageWrapperRef.value.style.height = ''
}
}
const adjustContainerSize = async () => {
@ -243,43 +249,86 @@ const adjustContainerSize = async () => {
// DOM
await new Promise(resolve => setTimeout(resolve, 0))
//
const container = comparisonContainerRef.value
if (!container) return
const img = originalImageRef.value || resultImageRef.value
if (!img) return
const previewSection = container.closest('.preview-section') as HTMLElement
if (!previewSection) return
// 使 getBoundingClientRect
const previewRect = previewSection.getBoundingClientRect()
const padding = 24
const maxAvailableWidth = Math.max(0, previewRect.width - padding)
const maxAvailableHeight = Math.max(0, previewRect.height - padding)
if (container) {
const img = originalImageRef.value || resultImageRef.value
if (img) {
const previewSection = container.closest('.preview-section') as HTMLElement
if (previewSection) {
const previewRect = previewSection.getBoundingClientRect()
const padding = 24
const maxAvailableWidth = Math.max(0, previewRect.width - padding)
const maxAvailableHeight = Math.max(0, previewRect.height - padding)
if (maxAvailableWidth > 0 && maxAvailableHeight > 0 && maxAvailableHeight >= 100) {
if (img.complete) {
const { naturalWidth, naturalHeight } = img
if (naturalWidth > 0 && naturalHeight > 0) {
const scale = Math.min(
maxAvailableWidth / naturalWidth,
maxAvailableHeight / naturalHeight,
1
)
container.style.width = `${naturalWidth * scale}px`
container.style.height = `${naturalHeight * scale}px`
}
} else {
img.addEventListener('load', adjustContainerSize, { once: true })
}
} else {
setTimeout(adjustContainerSize, 100)
}
}
}
}
// 0
if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0 || maxAvailableHeight < 100) {
setTimeout(adjustContainerSize, 100)
return
//
const singleWrapper = singleImageWrapperRef.value
if (singleWrapper) {
const img = singleImageRef.value
if (img) {
const previewSection = singleWrapper.closest('.preview-section') as HTMLElement
if (previewSection) {
const previewRect = previewSection.getBoundingClientRect()
const padding = 24
const maxAvailableWidth = Math.max(0, previewRect.width - padding)
const maxAvailableHeight = Math.max(0, previewRect.height - padding)
// 0
if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0 || maxAvailableHeight < 100) {
setTimeout(adjustContainerSize, 100)
return
}
if (!img.complete) {
img.addEventListener('load', adjustContainerSize, { once: true })
return
}
const { naturalWidth, naturalHeight } = img
if (naturalWidth === 0 || naturalHeight === 0) {
setTimeout(adjustContainerSize, 100)
return
}
const scale = Math.min(
maxAvailableWidth / naturalWidth,
maxAvailableHeight / naturalHeight,
1
)
singleWrapper.style.width = `${naturalWidth * scale}px`
singleWrapper.style.height = `${naturalHeight * scale}px`
} else {
// preview-section
setTimeout(adjustContainerSize, 100)
}
} else {
//
setTimeout(adjustContainerSize, 100)
}
}
if (!img.complete) {
img.addEventListener('load', adjustContainerSize, { once: true })
return
}
const { naturalWidth, naturalHeight } = img
if (naturalWidth === 0 || naturalHeight === 0) return
const scale = Math.min(
maxAvailableWidth / naturalWidth,
maxAvailableHeight / naturalHeight,
1
)
container.style.width = `${naturalWidth * scale}px`
container.style.height = `${naturalHeight * scale}px`
}
watch([uploadedImageUrl, resultImageUrl], adjustContainerSize, { immediate: true })
@ -567,8 +616,10 @@ onUnmounted(() => {
</div>
</div>
<div v-else class="single-image-view">
<div class="image-wrapper">
<img :src="uploadedImageUrl" alt="原图" />
<div class="image-wrapper" ref="singleImageWrapperRef">
<div class="single-image-container">
<img ref="singleImageRef" :src="uploadedImageUrl" alt="原图" @load="adjustContainerSize" />
</div>
<div v-if="processing" class="processing-overlay">
<div class="spinner"></div>
<p>处理中...</p>
@ -798,7 +849,10 @@ onUnmounted(() => {
display: flex;
flex-direction: column;
flex: 1;
min-height: 600px; /* 设置最小高度确保容器足够大 */
min-height: 600px;
max-width: 1400px;
margin: 0 auto;
width: 100%;
}
.page-header {
@ -1179,10 +1233,10 @@ onUnmounted(() => {
.image-wrapper {
position: relative;
width: 100%;
height: 100%;
display: inline-block;
max-width: 100%;
max-height: 100%;
min-height: 500px;
overflow: hidden;
border-radius: 8px;
border: 1px solid #e5e7eb;
@ -1193,15 +1247,25 @@ onUnmounted(() => {
linear-gradient(-45deg, transparent 75%, #f1f5f9 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
}
.single-image-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
object-fit: contain;
}
}