代码如下:
<template>
<div class="img_wrapper" ref="imgWrapper">
<img
class="original_img"
src="@/assets/images/testImg.jpg"
alt="测试图片"
@mousemove="handleMouseMove"
@mouseleave="handleMouseLeave"
@contextmenu.prevent.stop
@load="initImage"
ref="refImg"
/>
<div
v-if="isInside"
:style="{
backgroundSize: `${imgRealWidth * realGlassScale}px ${
imgRealHeight * realGlassScale
}px`,
...glassStyle
}"
class="cx-cropper-selection-glass"
>
<div class="cx-cropper-selection-glass__line is-horizontal"></div>
<div class="cx-cropper-selection-glass__line is-vertical"></div>
<div class="cx-cropper-selection-glass__mark"></div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isInside: false,
imgRealWidth: 0, // 图片实际宽度
imgRealHeight: 0, // 图片实际高度
realGlassScale: 2,
glassStyle: {
// 放大镜坐标
backgroundPosition: '0 0',
left: 0,
top: 0
}
}
},
methods: {
initImage() {
this.$nextTick(() => {
this.imgRealWidth = this.$refs.refImg.clientWidth
this.imgRealHeight = this.$refs.refImg.clientHeight
})
},
handleMouseMove(e) {
this.isInside = true
this.setGlassPosition(e.offsetX, e.offsetY)
},
handleMouseLeave() {
this.isInside = false
},
setGlassPosition(left, top) {
const { realGlassScale } = this
this.glassStyle.backgroundPosition = `-${left * realGlassScale - 75}px -${
top * realGlassScale - 50
}px`
this.glassStyle.left = left + 10 + 'px'
this.glassStyle.top = top + 10 + 'px'
}
}
}
</script>
<style lang="scss" scoped>
.img_wrapper {
margin: 0 auto;
width: 600px;
border: 1px solid red;
position: relative;
.original_img {
width: 100%;
cursor: crosshair;
}
.cx-cropper-selection-glass {
width: 150px;
height: 100px;
position: absolute;
border: 1px solid #000;
z-index: 30;
background: url('@/assets/images/testImg.jpg');
pointer-events: none;
background-repeat: no-repeat;
box-sizing: border-box;
background-color: #fff;
.cx-cropper-selection-glass__line {
position: absolute;
background: rgba(#447ed9, 0.5);
&.is-vertical {
width: 6px;
height: 100%;
top: 0;
left: 50%;
transform: translateX(-50%);
}
&.is-horizontal {
width: 100%;
height: 6px;
top: 50%;
left: 0;
transform: translateY(-50%);
}
}
.cx-cropper-selection-glass__mark {
width: 5px;
height: 5px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #000;
background: #fff;
}
}
}
</style>