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:
parent
8a4431075a
commit
cf2c2022de
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user