FIG Vue merchandise master based scheme magnifier


Foreword

In doing electrical business class applications, you will inevitably encounter a magnifying glass effect to achieve Commodity master map of the scene, based on existing third-party packages Vue much and can not be directly reused, today, I share a high-stability based Vue picture magnifying glass method.

The principle

The principle magnifying glass summarized in one sentence, that is, according to the mouse position on the small map to locate the big picture.

FIG 1 Schematic (magnification Example 2)

4fdfbe98091a4dde9b87a583a7ed5ac1


I believe the schematic is already drawn very clear, the figure, the left box is a small frame, a picture of the blue area mask layer (the need to enlarge the area), the right side of the box is the area where the whole big picture, which is blue region is an enlarged area disposed outside the hide, to achieve the effect of an enlarged mask region.

Clearly, there is a certain two blue region corresponding relation, i.e., the upper left position of the mask (with respect to the panel, hereinafter referred to as X-coordinate) and the enlarged region (large with respect to FIG.) Of the upper left corner is proportional to the position, i.e. magnification. After calculating the X-coordinate, adjust the position of the background, the large-scale view of a mobile X-coordinate to fold in the opposite direction.

X coordinate (maskX, maskY), to calculate maskX Example:

Mouse movement may be generated e.clientX, the distance from the left side of the left mouse identification browser, and the browser panel is left, since the mask is always the center of a mouse-square, so that:

maskX = e.clientX - left - mask/2

Similarly,

MASK = e.clientY - top - mask / 2

Larger patterns corresponding to:

Left {: - maskX Scale * + 'PX'; Top: - maskY Scale * + 'PX'; 
} 
copy the code

Demonstration effect

FIG. FIG. 2 shows the long

76cadcf6da074744912314ea68b8dc70


FIG 3 shows wide

67928690268640ea9f40cec128fdad5a


FIG 4 FIG twice Magnifying

50ec674ff4fa4177a615db2237aab339


FIG 5 FIG quadruple Magnifying

26a4323ae28b4ec4ba43041295ee6c36


Core code

HTML

1 is generally achieved magnifier: 1 width a square contour image, where compatible with other ratios of the image, to set the picture vertically centered, FIG comprising small and large FIG. If the thumbnail is not enough to fill the entire small frame, leaving a blank portion of the remainder may have magnified the effect, but the result is still enlarged blank. Simply calculate the distance to move this background, the picture positioning without too much attention to the issue.

<template>
 <div class="magnifier">
 <!-- 小图 -->
 <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>
 <!-- 大图, 注意误差 -->
 <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

这里主要有三个事件函数。

  • handOver:鼠标进入到小图框上的事件,此时显示遮罩和放大区域,并计算小图框的位置信息。

handOver() { // 计算小图框在浏览器中的位置
 this.imgObj = this.$el.getElementsByClassName('small-box')[0]; this.imgRectNow = this.imgObj.getBoundingClientRect(); this.showMagnifier = true; this.showMask = true;
}
 
复制代码
  • handMove:鼠标在小图上的移动事件,此事件发生在 handOver 之后,计算数据,移动遮罩以及背景图;

handMove(e) { // 计算初始的遮罩左上角的坐标
 let objX = e.clientX - this.imgRectNow.left;
 let objY = e.clientY - this.imgRectNow.top; // 计算初始的遮罩左上角的坐标
 let maskX = objX - this.configs.maskWidth / 2;
 let maskY = objY - this.configs.maskHeight / 2; // 判断是否超出界限,并纠正
 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;
 } // 遮罩移动
 this.transformMask = `translate(${maskX}px, ${maskY}px)`; // 背景图移动
 this.moveLeft = - maskX * this.configs.scale + "px"; this.moveTop = - maskY * this.configs.scale + "px";
}
复制代码
  • handOut:鼠标离开小图事件,此时无放大镜效果,隐藏遮罩和放大区域。

handOut() { this.showMagnifier = false; this.showMask = false;
}
复制代码

以上三个事件基本上就实现了图片的放大镜功能。

但仔细看,你会发现每次移入小图框都会触发一次 handOver 事件,并且计算一次小图框 DOM (imgObj) 。

为了优化此问题,可以用 init 标识是否是页面加载后首次触发 handOver 事件,如果是初始化就计算imgObj 信息,否则不计算。

handOver() { if (!this.init) { this.init = true; // 原 handOver 事件
 ...
 } 
 this.showMagnifier = true; this.showMask = true;
},
 
复制代码

在测试的过程中,发现页面滚动后,会出现遮罩定位错误的情况,原来是因为初始化时,我们固定死了小图框的位置信息(存放在 this.imgRectNow ),导致 handMove 事件中的移动数据计算错误。

解决这个问题有两种方案:

  • 监听 scroll 事件,更新 this.imgRectNow;

  • 在 handMove 事件中更新 this.imgRectNow。

这里选择了第二种。

handMove(e) { // 动态获取小图的位置(或者监听 scroll )
 let imgRectNow = this.imgObj.getBoundingClientRect(); let objX = e.clientX - imgRectNow.left; let objY = e.clientY - imgRectNow.top; // 原 handMove 事件剩余内容
 ...
},
复制代码

综合以上,我们已经实现了一个完美的图片放大镜功能。最终的 js 如下所示:

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) { // 动态获取小图的位置(或者监听 scroll )
 let imgRectNow = this.imgObj.getBoundingClientRect();
 let objX = e.clientX - imgRectNow.left;
 let objY = e.clientY - imgRectNow.top; // 计算初始的遮罩左上角的坐标
 let maskX = objX - this.configs.maskWidth / 2;
 let maskY = objY - this.configs.maskHeight / 2; // 判断是否超出界限,并纠正
 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;
 } // 遮罩移动
 this.transformMask = `translate(${maskX}px, ${maskY}px)`; // 背景图移动
 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;
 }
}
复制代码

使用方法

本示例中的固定参数:小图框:420 * 420 。

程序可接受参数:

// 小图地址src: { type: String,
},// 大图地址bigSrc: { type: String,
},// 配置项configs: { type: Object,
 default() {
 return { width:420,//放大区域
 height:420,//放大区域
 maskWidth:210,//遮罩
 maskHeight:210,//遮罩
 maskColor:'rgba(25,122,255,0.5)',//遮罩样式
 maskOpacity:0.6, scale:2,//放大比例
 };
 }
}
复制代码

文中图 2 是一张长图,小图的最大边不超过 836px(二倍图) ,大图为了视觉效果,分辨率尽量高点,程序会根据配置项自动设置对应的 height , width ,长图与宽图的效果对比可参考图3。

The configuration item may set their own application scenario, is exemplified herein CI 2 times magnification, the effect can refer to FIG. 4, the effect can be enlarged four times with reference to FIG.

to sum up

In fact, the picture magnifying glass to realize the idea is not so complicated, there are two core points:

  • FIG small creation method, the positioning of the large map, magnified area and the mask

  • Understanding the principles of the magnifying glass, and the like to achieve by moving the DOM code.

This article Along the way, made a simple implementation, as well as some optimization of space, welcome chiefs discuss in the comments area. Although the code does not look very elegant, but clear enough, interested students can try it yourself.

5a7a0fd1-5bf2-4157-a494-184347e96819



Guess you like

Origin blog.51cto.com/14516511/2439690