<template>
<div class="spec-preview">
<img :src="imgUrl" alt="">
<div class="event" @mousemove="handler" />
<div class="big">
<img ref="big" :src="imgUrl" alt="">
</div>
<!-- 遮罩层 -->
<div ref="mask" class="mask" />
</div>
</template>
<script>
export default {
name: 'Zoom',
data() {
return {
imgUrl: 'https://file.vedeng.com/file/ba0a86b178674c37a46fbebc2dac10eb/w=360_h=360.jpg'
}
},
methods: {
handler(event) {
const mask = this.$refs.mask
const bigImg = this.$refs.big
// 遮罩层可移动的范围:鼠标的当前坐标到该元素的距离(左侧、顶部)减去 遮罩层宽、高的一半(遮罩层始终是一个以鼠标为中心的正方形)
let left = event.offsetX - mask.offsetWidth / 2
let top = event.offsetY - mask.offsetHeight / 2
// 约束遮罩层可移动的范围
if (left <= 0) left = 0
if (left >= mask.offsetWidth) left = mask.offsetWidth
if (top <= 0) top = 0
if (top >= mask.offsetHeight) top = mask.offsetHeight
// 修改元素的left|top属性值
mask.style.left = left + 'px'
mask.style.top = top + 'px'
bigImg.style.left = -2 * left + 'px'
bigImg.style.top = -2 * top + 'px'
}
}
}
</script>
<style lang="scss">
.spec-preview {
position: relative;
width: 400px;
height: 400px;
border: 1px solid #ccc;
img {
width: 100%;
height: 100%;
}
.event {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 998;
}
.mask {
width: 50%;
height: 50%;
background-color: rgba(0, 255, 0, 0.3);
position: absolute;
left: 0;
top: 0;
display: none;
}
.big {
width: 100%;
height: 100%;
position: absolute;
top: -1px;
left: 100%;
border: 1px solid #aaa;
overflow: hidden;
z-index: 998;
display: none;
background: white;
img {
width: 200%;
max-width: 200%;
height: 200%;
position: absolute;
left: 0;
top: 0;
}
}
.event:hover ~ .mask,
.event:hover ~ .big {
display: block;
}
}
</style>
El código anterior está completo, puede mostrar directamente el efecto en una página en blanco y empaquetarlo en un componente