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 comparisonContainerRef = ref<HTMLElement | null>(null)
|
||||||
const originalImageRef = ref<HTMLImageElement | null>(null)
|
const originalImageRef = ref<HTMLImageElement | null>(null)
|
||||||
const resultImageRef = 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 isDraggingSplitLine = ref(false)
|
||||||
|
|
||||||
const handleDragEnter = (e: DragEvent) => {
|
const handleDragEnter = (e: DragEvent) => {
|
||||||
@ -236,6 +238,10 @@ const resetUpload = () => {
|
|||||||
comparisonContainerRef.value.style.width = ''
|
comparisonContainerRef.value.style.width = ''
|
||||||
comparisonContainerRef.value.style.height = ''
|
comparisonContainerRef.value.style.height = ''
|
||||||
}
|
}
|
||||||
|
if (singleImageWrapperRef.value) {
|
||||||
|
singleImageWrapperRef.value.style.width = ''
|
||||||
|
singleImageWrapperRef.value.style.height = ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const adjustContainerSize = async () => {
|
const adjustContainerSize = async () => {
|
||||||
@ -243,43 +249,86 @@ const adjustContainerSize = async () => {
|
|||||||
// 等待多个渲染周期确保 DOM 完全更新
|
// 等待多个渲染周期确保 DOM 完全更新
|
||||||
await new Promise(resolve => setTimeout(resolve, 0))
|
await new Promise(resolve => setTimeout(resolve, 0))
|
||||||
|
|
||||||
|
// 处理对比视图容器
|
||||||
const container = comparisonContainerRef.value
|
const container = comparisonContainerRef.value
|
||||||
if (!container) return
|
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)
|
||||||
|
|
||||||
const img = originalImageRef.value || resultImageRef.value
|
if (maxAvailableWidth > 0 && maxAvailableHeight > 0 && maxAvailableHeight >= 100) {
|
||||||
if (!img) return
|
if (img.complete) {
|
||||||
|
const { naturalWidth, naturalHeight } = img
|
||||||
const previewSection = container.closest('.preview-section') as HTMLElement
|
if (naturalWidth > 0 && naturalHeight > 0) {
|
||||||
if (!previewSection) return
|
const scale = Math.min(
|
||||||
|
maxAvailableWidth / naturalWidth,
|
||||||
// 使用 getBoundingClientRect 获取实际渲染尺寸
|
maxAvailableHeight / naturalHeight,
|
||||||
const previewRect = previewSection.getBoundingClientRect()
|
1
|
||||||
const padding = 24
|
)
|
||||||
const maxAvailableWidth = Math.max(0, previewRect.width - padding)
|
container.style.width = `${naturalWidth * scale}px`
|
||||||
const maxAvailableHeight = Math.max(0, previewRect.height - padding)
|
container.style.height = `${naturalHeight * scale}px`
|
||||||
|
}
|
||||||
// 如果高度为0或太小,多次重试
|
} else {
|
||||||
if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0 || maxAvailableHeight < 100) {
|
img.addEventListener('load', adjustContainerSize, { once: true })
|
||||||
setTimeout(adjustContainerSize, 100)
|
}
|
||||||
return
|
} else {
|
||||||
|
setTimeout(adjustContainerSize, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!img.complete) {
|
// 处理单图视图容器
|
||||||
img.addEventListener('load', adjustContainerSize, { once: true })
|
const singleWrapper = singleImageWrapperRef.value
|
||||||
return
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 })
|
watch([uploadedImageUrl, resultImageUrl], adjustContainerSize, { immediate: true })
|
||||||
@ -567,8 +616,10 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="single-image-view">
|
<div v-else class="single-image-view">
|
||||||
<div class="image-wrapper">
|
<div class="image-wrapper" ref="singleImageWrapperRef">
|
||||||
<img :src="uploadedImageUrl" alt="原图" />
|
<div class="single-image-container">
|
||||||
|
<img ref="singleImageRef" :src="uploadedImageUrl" alt="原图" @load="adjustContainerSize" />
|
||||||
|
</div>
|
||||||
<div v-if="processing" class="processing-overlay">
|
<div v-if="processing" class="processing-overlay">
|
||||||
<div class="spinner"></div>
|
<div class="spinner"></div>
|
||||||
<p>处理中...</p>
|
<p>处理中...</p>
|
||||||
@ -798,7 +849,10 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 600px; /* 设置最小高度确保容器足够大 */
|
min-height: 600px;
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
@ -1179,10 +1233,10 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
.image-wrapper {
|
.image-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
display: inline-block;
|
||||||
height: 100%;
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
min-height: 500px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid #e5e7eb;
|
border: 1px solid #e5e7eb;
|
||||||
@ -1193,15 +1247,25 @@ onUnmounted(() => {
|
|||||||
linear-gradient(-45deg, transparent 75%, #f1f5f9 75%);
|
linear-gradient(-45deg, transparent 75%, #f1f5f9 75%);
|
||||||
background-size: 20px 20px;
|
background-size: 20px 20px;
|
||||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
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;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: contain;
|
|
||||||
display: block;
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user