实现效果
实现思路
我们实现动图的淘宝放大镜的效果需要4步。
1.完成小图盒子、遮罩、大图盒子布局
2.实现鼠标移动到小图盒子显示遮罩和大图盒子
3.实现鼠标移动遮罩在小图盒子移动
4.实现遮罩的移动范围不能超出小图盒子,且移动时带动大图图片移动
完成小图盒子、遮罩、大图盒子布局
我的布局小图盒子包裹图片、遮罩、大图盒子。
小图盒子为相对定位。遮罩、大图盒子、大图图片都为绝对定位(大图图片没定位不能移动)。mask要设置透明度。只要能实现效果即可。
实现鼠标移动到小图盒子显示遮罩和大图盒子
小图盒子绑定mouseout鼠标移到事件和mouseover鼠标移出事件。每次触发事件的时候切换状态。
实现鼠标移动遮罩在小图盒子移动
小图盒子绑定mousemove鼠标移动事件。鼠标在页面的x坐标减去小图盒子的offersetLeft就是鼠标在盒子的左边这就是遮罩要移动的坐标,想要鼠标在mask的中间要除以2。同理y坐标也是。
实现遮罩的移动范围不能超出小图盒子,且移动时带动大图图片移动
边界值的判断,如果小于等于0,则将mask的left等于0,x的有边界值其实就是小盒子的宽度减去mask的宽度的值。同理y轴就是小盒子的高度减去mask的高度。
带动大图移动有个比例关系。大图片移动距离 = mask的移动距离*大盒子最大移动距离 / mask的x最大移动距离,
完整代码
<template>
<div
class="tb-booth"
@mouseover="onMouseOver"
@mouseout="onMouseOut"
@mousemove="onMouseMove"
ref="boothRef"
>
<img
src="https://img.alicdn.com/imgextra/i3/1917047079/O1CN01lkG2pf22AEUi1owve_!!1917047079.png_430x430q90.jpg"
/>
<div class="mask" ref="mask" v-show="boxShow" />
<div class="big-img_box" ref="bigImgBox" v-show="boxShow">
<img
class="big-img"
ref="bigImg"
src="https://img.alicdn.com/imgextra/i3/1917047079/O1CN01lkG2pf22AEUi1owve_!!1917047079.png"
/>
</div>
</div>
</template>
<script>
import { reactive, toRefs, ref } from "vue";
export default {
setup() {
const boothRef = ref(null);
const mask = ref(null);
const bigImg = ref(null);
const bigImgBox = ref(null);
const state = reactive({
boxShow: false
});
const onMouseOver = () => {
state.boxShow = true;
};
const onMouseOut = () => {
state.boxShow = false;
};
const onMouseMove = (e) => {
let x = e.pageX - boothRef.value.offsetLeft;
let y = e.pageY - boothRef.value.offsetTop;
let maskX = x - mask.value.offsetWidth / 2;
let maskY = y - mask.value.offsetHeight / 2;
// mask的x最大移动距离
let maskXMaxMove = boothRef.value.offsetWidth - mask.value.offsetWidth;
let maskYMaxMove = boothRef.value.offsetHeight - mask.value.offsetHeight;
let bigImgXMaxMove =
bigImgBox.value.offsetWidth - bigImg.value.offsetWidth;
let bigImgYMaxMove =
bigImgBox.value.offsetHeight - bigImg.value.offsetHeight;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskXMaxMove) {
maskX = maskXMaxMove;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskYMaxMove) {
maskY = maskYMaxMove;
}
mask.value.style.left = maskX + "px";
mask.value.style.top = maskY + "px";
// 大图片移动距离 = mask的移动距离*大盒子最大移动距离 / mask的x最大移动距离
let bixImgXMove = (maskX * bigImgXMaxMove) / maskXMaxMove;
let bixImgYMove = (maskY * bigImgYMaxMove) / maskYMaxMove;
bigImg.value.style.left = bixImgXMove + "px";
bigImg.value.style.top = bixImgYMove + "px";
};
return {
...toRefs(state),
boothRef,
mask,
bigImg,
bigImgBox,
onMouseOver,
onMouseOut,
onMouseMove,
};
},
};
</script>
<style scoped>
.tb-booth {
width: 430px;
height: 430px;
position: relative;
border: 1px solid #cccccc;
}
.mask {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
background-color: rgb(61, 110, 206);
opacity: 0.5;
cursor: move;
}
.big-img_box {
position: absolute;
top: 0;
left: 530px;
width: 500px;
height: 500px;
background-color: #fff;
border: 1px solid #cccccc;
overflow: hidden;
}
.big-img {
position: absolute;
left: 0;
top: 0;
}
</style>
总结
- mouseover、mouseout、mousemove事件的运用
- v-show显示隐藏
- vue3获取ref两种方式其中一种通过setup创建ref响应式数据,暴露出去赋予ref元素的值。第二种是getCurrentInstance方法。
- offsetWidth、offsetHeight、offsetLeft、offsetTop、pageX、pageY的概念
到此这篇关于vue3实现淘宝放大镜效果的示例代码的文章就介绍到这了,更多相关vue3 淘宝放大镜内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!