optimize comparison container sizing logic and reduce CSS duplication
This commit is contained in:
parent
92208b0513
commit
2a47e6a705
@ -170,7 +170,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, nextTick, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { useMessage } from 'naive-ui'
|
||||
import axios from 'axios'
|
||||
import { t } from '@/shared/i18n'
|
||||
@ -220,55 +220,43 @@ const isDraggingSplitLine = ref(false)
|
||||
|
||||
// 调整容器大小以匹配图片实际显示尺寸
|
||||
const adjustContainerSize = () => {
|
||||
nextTick(() => {
|
||||
if (!comparisonContainerRef.value) return
|
||||
const container = comparisonContainerRef.value
|
||||
if (!container) return
|
||||
|
||||
// 使用原图或结果图的尺寸(它们应该相同)
|
||||
const img = originalImageRef.value || resultImageRef.value
|
||||
if (!img) 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
|
||||
// 获取父元素 preview-section 的实际可用尺寸
|
||||
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)
|
||||
const previewRect = previewSection.getBoundingClientRect()
|
||||
// 考虑 padding (12px * 2 = 24px)
|
||||
const padding = 24
|
||||
const maxAvailableWidth = Math.max(0, previewRect.width - padding)
|
||||
const maxAvailableHeight = Math.max(0, previewRect.height - padding)
|
||||
|
||||
if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0) return
|
||||
|
||||
if (maxAvailableWidth <= 0 || maxAvailableHeight <= 0) return
|
||||
// 等待图片加载完成
|
||||
if (!img.complete) {
|
||||
img.addEventListener('load', adjustContainerSize, { once: true })
|
||||
return
|
||||
}
|
||||
|
||||
// 等待图片加载完成
|
||||
if (!img.complete) {
|
||||
// 如果图片还没加载完成,等待加载完成后再计算
|
||||
// 使用 once: true 确保只触发一次
|
||||
img.addEventListener('load', adjustContainerSize, { once: true })
|
||||
return
|
||||
}
|
||||
const { naturalWidth, naturalHeight } = img
|
||||
if (naturalWidth === 0 || naturalHeight === 0) return
|
||||
|
||||
const naturalWidth = img.naturalWidth
|
||||
const naturalHeight = img.naturalHeight
|
||||
// 计算缩放比例,保持宽高比且不超过父元素可用空间
|
||||
const scale = Math.min(
|
||||
maxAvailableWidth / naturalWidth,
|
||||
maxAvailableHeight / naturalHeight,
|
||||
1 // 不放大
|
||||
)
|
||||
|
||||
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`
|
||||
})
|
||||
// 设置容器大小为计算出的尺寸
|
||||
container.style.width = `${naturalWidth * scale}px`
|
||||
container.style.height = `${naturalHeight * scale}px`
|
||||
}
|
||||
|
||||
// 监听图片加载完成
|
||||
@ -973,7 +961,7 @@ h1 {
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
padding: 12px;
|
||||
padding: 12px; /* 用于计算可用空间 */
|
||||
}
|
||||
|
||||
|
||||
@ -1008,8 +996,6 @@ h1 {
|
||||
.comparison-view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -1035,6 +1021,7 @@ h1 {
|
||||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
||||
}
|
||||
|
||||
/* 所有对比图片容器的公共样式 */
|
||||
.comparison-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -1047,7 +1034,6 @@ h1 {
|
||||
|
||||
img {
|
||||
display: block;
|
||||
/* 图片限制在容器内,不超过父元素 */
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
@ -1057,44 +1043,13 @@ h1 {
|
||||
}
|
||||
|
||||
.original-image {
|
||||
/* 和 result-image 一样使用 absolute,确保填充 comparison-container */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
/* clip-path 通过内联样式动态设置,用于裁剪显示区域 */
|
||||
|
||||
img {
|
||||
display: block;
|
||||
/* 图片限制在容器内,不超过父元素 */
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.result-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
/* clip-path 通过内联样式动态设置,用于裁剪显示区域 */
|
||||
|
||||
img {
|
||||
display: block;
|
||||
/* 图片限制在容器内,不超过父元素 */
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
/* 拖动竖线 */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user