Home >Web Front-end >Vue.js >How to achieve Taobao magnifying glass effect in vue3

How to achieve Taobao magnifying glass effect in vue3

王林
王林forward
2023-05-19 13:28:312045browse

Achieve effect

How to achieve Taobao magnifying glass effect in vue3

Implementation idea

We need 4 steps to realize the effect of Taobao magnifying glass in animated pictures.

1. Complete the layout of the small picture box, mask, and large picture box
2. Implement the mouse movement to the small picture box to display the mask and the large picture box
3. Implement the mouse movement mask in Moving the small picture box
4. The movement range of the mask cannot exceed the small picture box, and the movement of the large picture box will drive the movement of the large picture box

Complete the layout of the small picture box, mask, and large picture box

My layout small picture box wraps pictures, masks, and large picture boxes.
The small picture box is relatively positioned. Masks, large picture boxes, and large picture pictures are all absolutely positioned (large picture pictures cannot be moved without positioning). Mask needs to set transparency. As long as the effect can be achieved.

Realize moving the mouse to the small picture box to display the mask and the large picture box

The small picture box is bound to the mouse move-in event (mouseover) and the mouse move-out event (mouseout). Switch the state each time the event is triggered.

Realize the movement of the mouse movement mask in the small picture box

The small picture box is bound to the mousemove mouse movement event. The x coordinate of the mouse on the page minus the offerLeft of the small picture box is the mouse on the left side of the box. This is the coordinate where the mask needs to be moved. If you want the mouse to be in the middle of the mask, divide it by 2. The same goes for the y coordinate.
The moving range of the mask cannot exceed the small picture box, and the movement of the large picture will drive the movement of the large picture.
Judgment of the boundary value, if it is less than or equal to 0, set the left of the mask to 0, and the x has a boundary value. It is the width of the small box minus the width of the mask. In the same way, the y-axis is the height of the small box minus the height of the mask.
There is a proportional relationship in driving the movement of the large image. The moving distance of the large picture = the moving distance of the mask * the maximum moving distance of the big box / the x maximum moving distance of the mask,

Complete code

<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>

The above is the detailed content of How to achieve Taobao magnifying glass effect in vue3. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete