Vue based magnifying glass scheme for the main picture of goods

Time:2020-2-13

This article first appeared on the blog of the front-end team of Zhengcai cloud: the magnifier scheme of the main picture of commodities based on Vue

Preface

When doing e-commerce applications, it is inevitable to encounter the scene where the product master map realizes the magnifying glass effect. The existingVueToday, I want to share a high stability based onVueImage magnifier method.

Realization principle

The principle of magnifying glass is summed up in one sentence, which is to locate the large picture according to the mouse position on the small picture.

Figure 1 Schematic diagram (take 2-fold magnification as an example)

Vue based magnifying glass scheme for the main picture of goods

I believe that the schematic diagram has been drawn very clearly. In the diagram, the left frame is a small frame, its blue area is the image mask layer (the area to be enlarged), the right frame is the current area of the whole large picture, and its blue area is the enlarged area. If you set it beyond hiding, you can achieve the effect of enlarging the mask area.

Obviously, there is a corresponding relationship between the two blue areas, that is, the upper left corner position of the mask (relative to the small image, hereinafter referred to as X coordinate) and the upper left corner position of the enlarged area (relative to the large image) are proportional, that is, the magnification. After calculating the X coordinate, adjust the position of the background image properly so that the large image moves the X coordinate of scale times in the opposite direction.

The X coordinate is (maskx, masky). Take the calculation of maskx as an example:

During mouse movement, e.clientx will be generated to identify the distance between the mouse and the left side of the browser. The distance between the small figure and the left side of the browser is left. Because the mask is always a square centered on the mouse, so:

maskX = e.clientX – left – mask/2

Similarly,

maskY = e.clientY – top – mask/2

The corresponding style of the large drawing is set as follows:

{
  left: - maskX * scale + 'px';
  top: - maskY * scale + 'px';
}

Effect demonstration

Figure 2 long picture display

Vue based magnifying glass scheme for the main picture of goods

Fig. 3 wide view

Vue based magnifying glass scheme for the main picture of goods

Fig. 4 double magnification effect

Vue based magnifying glass scheme for the main picture of goods

Figure 5 quadruple magnification effect

Vue based magnifying glass scheme for the main picture of goods

Core code

HTML

Generally, the magnifying glass implements a square image with the same width and height of 1:1, which is compatible with other scale images. Set the image to be vertically centered and aligned, including small image and large image. If the small image is not enough to fill the whole small frame, the remaining blank part can also be enlarged, but the enlarged result is still blank. In this way, we only need to calculate the moving distance of the background image and not pay too much attention to the image location.

<template>
 <div class="magnifier">
    <! -- small picture -- >
    <div class="small-box" @mouseover="handOver"  @mousemove="handMove" @mouseout="handOut">
      <img class="smallPic" :src="`${src}?x-oss-process=image/resize,l_836`" />
      <div class="magnifier-zoom" 
        v-show="showMask"
        :style="{
          background: configs.maskColor,
          height: configs.maskWidth + 'px',
          width: configs.maskHeight + 'px', 
          opacity: configs.maskOpacity, 
          transform: transformMask
        }"
      ></div>
    </div>
    <! -- large picture, pay attention to error -- >
    <div class="magnifier-layer" 
      v-show="showMagnifier"
      :style="{ 
        width: configs.width + 'px', 
        height: configs.height + 'px', 
        left: configs.width + 20 + 'px' 
      }"
    >
      <div class="big-box"
        :style="{ 
          width: bigWidth + 'px',
          height: bigHeight + 'px',
          left: moveLeft,
          top: moveTop
        }"
      >
        <div class="big-box-img"
          :style="{ 
            width: bigWidth - 2  + 'px', 
            height: bigHeight - 2 + 'px' 
          }"
        >
          <img
            :src="bigSrc"
            :style="{ 
              maxWidth: bigWidth - 2 + 'px', 
              maxHeight: bigHeight -2 + 'px' 
            }"
          />
        </div>
      </div>
    </div>
  </div>
</template>
JS

There are three main event functions.

  • Handover: the mouse enters the event on the small frame, the mask and zoom area are displayed, and the location information of the small frame is calculated.
handOver() {
  //Calculate the position of the small border in the browser
  this.imgObj = this.$el.getElementsByClassName('small-box')[0];
  this.imgRectNow = this.imgObj.getBoundingClientRect();
  this.showMagnifier = true;
  this.showMask = true;
}
  • Handmove: the move event of the mouse on the small graph. This event occurs after handover, calculating data, moving mask and background graph;
handMove(e) {
  //Calculate the coordinates of the upper left corner of the initial mask
  let objX = e.clientX - this.imgRectNow.left;
  let objY = e.clientY - this.imgRectNow.top;

  //Calculate the coordinates of the upper left corner of the initial mask
  let maskX = objX - this.configs.maskWidth / 2;
  let maskY = objY - this.configs.maskHeight / 2;

  //Judge whether the limit is exceeded and correct
  maskY = maskY < 0 ? 0 : maskY; 
  maskX = maskX < 0 ? 0 : maskX; 
  if(maskY + this.configs.maskHeight >= this.imgRectNow.height) {
    maskY = this.imgRectNow.height - this.configs.maskHeight;
  }
  if(maskX + this.configs.maskWidth >= this.imgRectNow.width) {
    maskX = this.imgRectNow.width - this.configs.maskWidth;
  }

  //Mask move
  this.transformMask = `translate(${maskX}px, ${maskY}px)`;

  //Background image move
  this.moveLeft = - maskX * this.configs.scale + "px";
  this.moveTop = - maskY * this.configs.scale + "px";
}
  • Handout: when the mouse leaves the small image event, there is no magnifier effect, and the mask and magnified area are hidden.
handOut() {
  this.showMagnifier = false;
  this.showMask = false;
}

The above three events basically realize the magnifying glass function of the picture.

But if you look carefully, you will find that every time you move in a small frame, a handover event will be triggered and the small frame DOM (imgobj) will be calculated.

In order to optimize this problem, init can be used to identify whether the handover event is triggered for the first time after the page is loaded. If it is initialized, imgobj information will be calculated, otherwise, it will not be calculated.

handOver() {
  if (!this.init) {
    this.init = true;
    //Original handover event
    ...
  } 
  this.showMagnifier = true;
  this.showMask = true;
},

During the test, it is found that the mask positioning error will occur after the page scrolls. The reason is that during initialization, we fixed the location information of the small frame (stored in this. Imgrectnow), resulting in the mobile data calculation error in the handmove event.

There are two solutions to this problem:

  • Listen to the scroll event and update this.imgrectnow;
  • Update this.imgrectnow in the handmove event.

Here’s the second option.

handMove(e) {
  //Dynamically obtain the location of small graph (or monitor scroll)
  let imgRectNow = this.imgObj.getBoundingClientRect();
  let objX = e.clientX - imgRectNow.left;
  let objY = e.clientY - imgRectNow.top;
  //Remaining contents of the original handmove event
  ...
},

In summary, we have achieved a perfect image magnifier function. The final JS is as follows:

data() {
  return {
    imgObj: {},
    moveLeft: 0,
    moveTop: 0,
    transformMask:`translate(0px, 0px)`,
    showMagnifier:false,
    showMask:false,
    init: false,
  };
},
computed: {
  bigWidth(){
    return this.configs.scale * this.configs.width;
  },
  bigHeight(){
    return this.configs.scale * this.configs.height;
  }
},
methods: {
  handMove(e) {
    //Dynamically obtain the location of small graph (or monitor scroll)
    let imgRectNow = this.imgObj.getBoundingClientRect();
    let objX = e.clientX - imgRectNow.left;
    let objY = e.clientY - imgRectNow.top;

    //Calculate the coordinates of the upper left corner of the initial mask
    let maskX = objX - this.configs.maskWidth / 2;
    let maskY = objY - this.configs.maskHeight / 2;

    //Judge whether the limit is exceeded and correct
    maskY = maskY < 0 ? 0 : maskY; 
    maskX = maskX < 0 ? 0 : maskX; 
    if(maskY + this.configs.maskHeight >= imgRectNow.height) {
      maskY = imgRectNow.height - this.configs.maskHeight;
    }
    if(maskX + this.configs.maskWidth >= imgRectNow.width) {
      maskX = imgRectNow.width - this.configs.maskWidth;
    }

    //Mask move
    this.transformMask = `translate(${maskX}px, ${maskY}px)`;

    //Background image move
    this.moveLeft = - maskX * this.configs.scale + "px";
    this.moveTop = - maskY * this.configs.scale + "px";
  },
  handOut() {
    this.showMagnifier = false;
    this.showMask = false;
  },
  handOver() {
    if (!this.init) {
      this.init = true;
      this.imgObj = this.$el.getElementsByClassName('small-box')[0];
    }
    this.showMagnifier = true;
    this.showMask = true;
  }
}

Usage method

Fixed parameter in this example: small frame: 420 * 420.

Program acceptable parameters:

//Small map address
src: {
  type: String,
},
//Large map address
bigSrc: {
  type: String,
},
// configuration item
configs: {
  type: Object,
    default() {
    return {
      Width: 420, // enlarge the area
      Height: 420, // enlarge the area
      Maskwidth: 210, // mask
      Maskheight: 210, // mask
      Maskcolor: 'RGBA (25122255,0.5)', // mask style
      maskOpacity:0.6,
      Scale: 2, // scale up
    };
  }
}

In this paper, figure 2 is a long picture, and the maximum edge of the small picture is not more than 836px (double picture). For the visual effect of the large picture, the resolution should be as high as possible. The program will automatically set the corresponding height, width according to the configuration item. For the effect comparison between the long picture and the wide picture, please refer to figure 3.

The configuration item can be set according to the application scenario. The example configuration item in this paper is 2-fold magnification, the effect can refer to figure 4, and the 4-fold magnification effect can refer to figure 5.

summary

In fact, the realization of image magnifier is not so complicated. There are two core points:

  • Positioning of small and large drawings, creating methods of masking and enlarging areas
  • Understand the principle of magnifying glass, and use code to realize DOM movement.

Following this idea, this paper makes a simple implementation and some optimization space. Welcome to discuss in the comment area. Although the code is not very elegant, it is clear enough that interested students can try it on their own.

Invite to one’s side men of wisdom and Valor

Recruitment, front-end, subordinate to zoomteam, more than 50 small partners are waiting for you to join the wave ~ If you want to change things that are always being tossed, you want to start tossing things; if you want to change things that are always being told, you need more ideas, but you can’t break the situation; if you want to change things that you have the ability to achieve that result, but you don’t need you; if you want to change things that you want to achieve, you need a team to support, but you don’t take people with you; if you want to change the established rhythm, it will be “5 years working time and 3 years working experience”; if you want to change the original understanding is good, but there is always a layer of window paper blur If you believe in the power of faith, believe that ordinary people can achieve extraordinary things, believe that you can meet a better self. If you want to participate in the process of business take-off and personally participate in the growth process of a front-end team with in-depth business understanding, perfect technical system, technology creating value and influence spillover, I think we should talk about it. Any time, wait for you to write something, send it[email protected]

Vue based magnifying glass scheme for the main picture of goods

Recommended Today

[reading notes] calculation advertising (Part 3)

By logm This article was originally published at https://segmentfault.com/u/logm/articles and is not allowed to be reproduced~ If the mathematical formula in the article cannot be displayed correctly, please refer to: Tips for displaying the mathematical formula correctly This article isComputing advertising (Second Edition)Reading notes. This part introduces the key technology of online advertising, which is […]