ensure comparison container size matches image display size and respects parent

This commit is contained in:
jingrow 2025-11-19 21:48:54 +08:00
parent ccf84eb031
commit 92208b0513

View File

@ -72,7 +72,12 @@
class="comparison-image original-image"
:style="{ clipPath: `inset(0 ${100 - splitPosition}% 0 0)` }"
>
<img :src="uploadedImageUrl" alt="Original" />
<img
ref="originalImageRef"
:src="uploadedImageUrl"
alt="Original"
@load="adjustContainerSize"
/>
</div>
<!-- 去背景后的图片显示右侧部分 -->
@ -80,7 +85,12 @@
class="comparison-image result-image"
:style="{ clipPath: `inset(0 0 0 ${splitPosition}%)` }"
>
<img :src="resultImageUrl" alt="Result" />
<img
ref="resultImageRef"
:src="resultImageUrl"
alt="Result"
@load="adjustContainerSize"
/>
</div>
<!-- 拖动竖线 -->
@ -160,7 +170,7 @@
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { ref, computed, nextTick, watch, onMounted, onUnmounted } from 'vue'
import { useMessage } from 'naive-ui'
import axios from 'axios'
import { t } from '@/shared/i18n'
@ -204,8 +214,81 @@ const dragCounter = ref(0)
const processing = ref(false)
const splitPosition = ref(0) // 线0
const comparisonContainerRef = ref<HTMLElement | null>(null)
const originalImageRef = ref<HTMLImageElement | null>(null)
const resultImageRef = ref<HTMLImageElement | null>(null)
const isDraggingSplitLine = ref(false)
//
const adjustContainerSize = () => {
nextTick(() => {
if (!comparisonContainerRef.value) return
// 使
const img = originalImageRef.value || resultImageRef.value
if (!img) return
// preview-section
const container = comparisonContainerRef.value
const previewSection = container.closest('.preview-section') as HTMLElement
if (!previewSection) return
const previewRect = previewSection.getBoundingClientRect()
// padding (12px * 2 = 24px)
const maxAvailableWidth = Math.max(0, previewRect.width - 24)
const maxAvailableHeight = Math.max(0, previewRect.height - 24)
if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0) return
//
if (!img.complete) {
//
// 使 once: true
img.addEventListener('load', adjustContainerSize, { once: true })
return
}
const naturalWidth = img.naturalWidth
const naturalHeight = img.naturalHeight
if (naturalWidth === 0 || naturalHeight === 0) return
//
//
const scaleX = maxAvailableWidth / naturalWidth
const scaleY = maxAvailableHeight / naturalHeight
const scale = Math.min(scaleX, scaleY, 1) // 1
const displayWidth = naturalWidth * scale
const displayHeight = naturalHeight * scale
//
const finalWidth = Math.min(displayWidth, maxAvailableWidth)
const finalHeight = Math.min(displayHeight, maxAvailableHeight)
//
comparisonContainerRef.value.style.width = `${finalWidth}px`
comparisonContainerRef.value.style.height = `${finalHeight}px`
})
}
//
watch([uploadedImageUrl, resultImageUrl], () => {
adjustContainerSize()
}, { immediate: true })
//
const handleResize = () => {
adjustContainerSize()
}
onMounted(() => {
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
})
//
const triggerFileInput = () => {
if (fileInputRef.value) {
@ -306,6 +389,11 @@ const resetUpload = () => {
if (fileInputRef.value) {
fileInputRef.value.value = ''
}
//
if (comparisonContainerRef.value) {
comparisonContainerRef.value.style.width = ''
comparisonContainerRef.value.style.height = ''
}
}
//
@ -920,17 +1008,19 @@ h1 {
.comparison-view {
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.comparison-container {
position: relative;
display: inline-block;
/* 固定尺寸,避免子元素高度计算错误 */
width: min(90vw, calc(100vh - 200px));
height: min(90vw, calc(100vh - 200px));
/* 容器大小由 JavaScript 动态设置,匹配图片实际显示尺寸 */
/* 同时设置 max-width 和 max-height 作为安全限制,确保不超过父元素 */
max-width: 100%;
max-height: 100%;
overflow: hidden;
@ -957,6 +1047,7 @@ h1 {
img {
display: block;
/* 图片限制在容器内,不超过父元素 */
max-width: 100%;
max-height: 100%;
width: auto;
@ -977,6 +1068,7 @@ h1 {
img {
display: block;
/* 图片限制在容器内,不超过父元素 */
max-width: 100%;
max-height: 100%;
width: auto;
@ -996,6 +1088,7 @@ h1 {
img {
display: block;
/* 图片限制在容器内,不超过父元素 */
max-width: 100%;
max-height: 100%;
width: auto;