利用浮动和overflow: hidden的效果
<template>
<div class="picBox" @mouseenter="isHover = true" @mouseleave="isHover = false">
<div id="mousemoveBox">
<div id="line" />
<img
v-show="isHover"
id="move"
src="./move.png"
alt=""
>
</div>
<div id="before">
<img id="beforeImg" :src="imgList.imgFirst" alt="">
</div>
<div id="after">
<img id="afterImg" :src="imgList.imgSecond" alt="">
</div>
</div>
</template>
<script setup>
import { ref, onUnmounted, onMounted, nextTick } from 'vue'
const props = defineProps({
imgList: {
type: Object,
default: () => {}
}
})
const contentWidth = ref('')
const contentHeight = ref('')
const imgWidth = ref('40px')
const imgHeight = ref(0)
const isHover = ref(false)
onMounted(() => {
const picBox = document.querySelector('.picBox')
contentWidth.value = picBox.offsetWidth + 'px'
contentHeight.value = picBox.offsetHeight + 'px'
contrastImg(props.imgIdList)
})
let line = null // domLine
let move = null // domMove
let after = null // domAfter
let before = null // domBefore
let picBox = null // domPicBox
let afterImg = null // domAfterImg
let beforeImg = null // domBeforeImg
let x = 0 // 鼠标在页面中的位置
let afterX = 0 // after在页面中的位置
let picBoxWidth = 0 // picBox的宽度
let beforeWidth = 0 // before的宽度
let afterWidth = 0 // after的宽度
let moveFlag = false // 鼠标是否抬起
let lineLeft = 0 // line在页面中的位置
let picBoxX = 0 // picBox在页面中的位置
// before移动
const beforeMove = (beforeWidth) => {
before.style.width = beforeWidth + 'px'
}
// after移动
const afterMove = (mousemoveDistance) => {
after.style.width = (afterWidth - mousemoveDistance) + 'px'
after.style.left = (afterX + mousemoveDistance) + 'px'
afterImg.style.left = -(afterX + mousemoveDistance) + 'px'
}
const mousedown = (event) => {
picBoxX = picBox.getBoundingClientRect().left
moveFlag = false
x = event.pageX // 鼠标在页面中的位置
beforeWidth = before.offsetWidth // before的宽度
afterWidth = after.offsetWidth // after的宽度
picBoxWidth = picBox.offsetWidth // before宽度
afterX = after.offsetLeft // after在页面中的位置
lineLeft = line.offsetLeft // line在页面中的位置
line.addEventListener('mousemove', mousemove)
}
const mousemove = (e) => {
if (moveFlag) return
if (e.pageX <= picBoxX || e.pageX >= picBoxX + picBoxWidth) return
const mousemoveDistance = e.pageX - x // 鼠标移动的距离
line.style.left = (mousemoveDistance + lineLeft) + 'px'
move.style.left = (mousemoveDistance + lineLeft + 34) + 'px'
const beforeMoveWidth = beforeWidth + mousemoveDistance // before移动的距离
beforeMove(beforeMoveWidth)
afterMove(mousemoveDistance)
}
const mouseup = () => {
moveFlag = true
}
const contrastImg = (event) => {
line = document.getElementById('line')
move = document.getElementById('move')
after = document.getElementById('after')
before = document.getElementById('before')
picBox = document.querySelector('.picBox')
afterImg = document.getElementById('afterImg')
beforeImg = document.getElementById('beforeImg')
// 检测鼠标按下操作
line.addEventListener('mousedown', mousedown)
// 检测鼠标松开操作
document.addEventListener('mouseup', mouseup)
}
onUnmounted(() => {
line.removeEventListener('mousemove', mousemove)
line.removeEventListener('mousedown', mousedown)
document.removeEventListener('mouseup', mouseup)
})
</script>
<style scoped lang="scss">
.picBox {
position: relative;
font-size: 0;
width: 100%;
height: 100%;
#mousemoveBox {
position: absolute;
width: 100px;
height: 100%;
left: calc(50% - 50px);
z-index: 4;
#line {
position: absolute;
width: 100px;
height: 30px;
top: calc(50% - 15px);
z-index: 5;
}
#move {
position: absolute;
left: 34px;
width: 32px;
top: calc(50% - 15px);
z-index: 4;
}
}
#before {
position: absolute;
width: 50%;
height: 100%;
overflow: hidden;
#beforeImg {
position: absolute;
width: v-bind(contentWidth);
height: 100%;
}
}
#after {
position: absolute;
left: 50%;
width: 50%;
height: 100%;
overflow: hidden;
#afterImg {
position: absolute;
left: -100%;
width: v-bind(contentWidth);
height: 100%;
}
}
}
</style>