封装组件
<template>
<div id="bottomImg" class="bottomImg" :style="{ height: imgHeigth, width: imgWidth, backgroundImage: 'url(' + props.bottomImg + ')' }">
<span class="imgLabel">{{ props.bottomLabel }}</span>
<div v-if="props.upperImg" class="upperImg" :style="{ backgroundImage: 'url(' + props.upperImg + ')', width: 100 - upperImgWidth + '%' }">
<span class="imgLabel">{{ props.upperLabel }}</span>
</div>
<div v-else class="upperUndefined" :style="{ width: 100 - upperImgWidth + '%' }">
<span class="undefinedSpan">暂无结果</span>
</div>
<span class="spanHandle" :style="{ left: 'calc(' + upperImgWidth + '% - 24px)' }"></span>
<input class="inputRange" type="range" v-model="upperImgWidth" min="0" max="100" />
</div>
</template>
<script lang="ts" setup>
import { ref, watch, onMounted } from 'vue'
const imgHeigth = ref('100%')
const imgWidth = ref('100%')
const upperImgWidth = ref(50)
const props = defineProps({
bottomImg: {
type: String,
default: '',
},
upperImg: {
type: String,
default: '',
},
bottomLabel: {
type: String,
default: '原图',
},
upperLabel: {
type: String,
default: '效果图',
},
})
// 跟踪底层图片的变化,因为底层图片是基础
watch(
() => props.bottomImg,
() => {
getImgSize()
upperImgWidth.value = 50
}
)
// 首次加载时初始化
onMounted(() => {
getImgSize()
})
function getImgSize () {
// 加载图片获取图片真实宽度和高度
const image = new Image()
image.onload = function () {
// imgHeigth.value = image.height + '100px'
imgWidth.value = image.width + 'px'
}
// image.onload = function () {
// imgHeigth.value = image.height + 'px'
// imgWidth.value = image.width + 'px'
// }
image.src = props.bottomImg // img.src 应该是放在 onload 方法后边的, 因为当image的src发生改变,浏览器就会跑去加载这个src里的资源,先告诉浏览器图片加载完要怎么处理,再让它去加载图片
}
</script>
<style>
.bottomImg {
position: relative;
overflow: hidden;
background-size: 100%;
background-repeat: no-repeat;
}
.upperImg {
position: absolute;
top: 0;
right: 0;
z-index: 1;
height: 650px;
background-position: right top;
border-left: 2px solid rgb(255, 255, 255, 0.5);
background-size: 100%;
background-repeat: no-repeat;
}
.imgLabel {
font-size: 20px;
color: aliceblue;
text-shadow: 1px 1px #533d4a, 2px 2px #533d4a;
}
.upperUndefined {
position: absolute;
top: 0;
right: 0;
height: 100%;
z-index: 1;
font-size: 60px;
background-color: rgb(255, 255, 255, 0.8);
background-position: right top;
border-left: 2px solid rgb(255, 255, 255, 0.5);
}
.undefinedSpan {
display: flex;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
color: #999;
overflow: hidden;
}
.inputRange {
position: absolute;
height: 100%;
z-index: 3;
left: -4px;
touch-action: auto;
width: calc(100% + 4px);
opacity: 0;
}
.spanHandle {
position: absolute;
z-index: 2;
height: 48px;
width: 48px;
position: center;
font-size: 24px;
border: 1px;
border-radius: 50%;
top: calc(50% - 24px);
background-color: rgb(255, 255, 255, 0.5);
}
.spanHandle:before {
left: 5px;
transform: rotate(-45deg);
}
.spanHandle:after {
right: -5px;
transform: rotate(135deg);
}
.spanHandle:after,
.spanHandle:before {
border-left: 2px solid;
border-top: 2px solid;
content: "";
height: 10px;
position: absolute;
top: 50%;
transform-origin: 0 0;
width: 10px;
}
</style>
引入所需的页面
最后根据自己需要的结果调整样式