亲宝软件园·资讯

展开

vue3 淘宝放大镜

Ayanokouji 人气:2

实现效果

实现思路

我们实现动图的淘宝放大镜的效果需要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>

总结

加载全部内容

相关教程
猜你喜欢
用户评论