宝哥软件园

基于Vue的商品主图放大镜方案详解

编辑:宝哥软件园 来源:互联网 时间:2021-08-20

前言

做电商应用时,难免会遇到商品主图达到放大镜效果的场景。现有的基于Vue的第三方包很少,不能直接重用。今天分享一个基于Vue的高稳定性图像放大镜的方法。

实施原则

放大镜的原理可以用一句话概括,就是根据鼠标在小图片上的位置来定位大图片。

图1示意图(以2倍放大为例)

我相信示意图已经画清楚了。图中左框为小框,其蓝色区域为画面蒙版层(需放大的区域);右框是整个大图当前所在的区域,其蓝色区域是放大区域。如果设置无法隐藏,可以实现放大蒙版面积的效果。

显然,两个蓝色区域之间存在一定的对应关系,即蒙版左上角位置(相对于小图像,以下简称X坐标)与放大区域左上角位置(相对于大图像)成正比,即放大倍数。计算出x坐标后,适当调整背景图像的位置,使大图像反方向移动缩放次数的x坐标。

x坐标为(maskX,maskY),以maskX的计算为例:

当鼠标移动时会生成E.clientX,它标记了鼠标与浏览器左侧的距离。缩略图和浏览器左侧之间的距离是左侧。因为遮罩总是以鼠标为中心的正方形,所以:

maskX=e.clientX - left - mask/2

同样地,

maskY=e.clientY - top - mask/2

大图像的对应样式设置如下:

{ left: - maskX *比例尺' px ';top: - maskY *刻度' px ';}效果演示

图2显示了长图

图3的宽视图显示

图4双放大渲染

图5四倍放大渲染

核心代码

超文本标记语言

一般放大镜实现等宽等高1:1的方形图片,兼容其他比例的图片,设置图片垂直居中对齐,包括小图片和大图片。如果小图不足以填满整个小画框,也可以将左边空白部分放大,但放大后的结果仍然是空白。这样,我们只需要计算背景图像的移动距离,而不需要过多关注图像定位的问题。

模板div class='放大镜'!-Small pick-div class=' Small-box ' @ mouse over='交接' @ mouse move=' hand move ' @ mouse out='交接' img class=' Small pic ' : src=' http 3360 ` $ { src }?x-oss-process=image/resize,l _ 836 ` '/div class=' magnifier-zoom ' v-show=' show mask ' : style=' { background : configs . maskcolor,height : configs . maskwidth ' px ',width : configs . mask hx8 ' px ',opa city 3360 configs . maskopacity,transform 3360 transform mask } '/div/div!-大图,注意错误-div class='放大镜-图层' v-show='显示放大镜' : style=' {width : configs。宽度' px ',高度:配置。高度' px ',左侧: configs . width 20 ' px ' } ' div class=' big-box ' : style=' { width : bigWidth 'px ',高度: big width ' px ',左侧: moveLeft,top : move top } ' div class=' big-box-img ' : style=' { width : big width-2 ' px ',高度3: big

主要有三个事件函数。

切换:鼠标在小框上进入事件时,会显示蒙版和放大区域,并计算小框的位置信息。

HandOver() {//计算小框架在浏览器中的位置这。imgobj=这个。$ el。getElementByclassName('小方框')[0];this . imgrectnow=this . imgobj . getboundingclientrect();this.showMagnifier=truethis.showMask=true}handMove:鼠标在小图片上的移动事件,发生在after、计算数据、移动蒙版和背景图片之后;

handMove(e) { //计算初始的遮罩左上角的坐标让objX=e . client x-这个。imgrectnow。向左;让objY=e . clienty-这个。imgrectnow。顶部;//计算初始的遮罩左上角的坐标让maskX=Objx-这个。配置。maskwidth/2;让MaSky=Objy-这个。配置。mask h AiR/2;//判断是否超出界限,并纠正maskY=maskY 0?0 : maskYmaskX=maskX 0?0 : maskXif(MaSky这个。配置。MaSKhA8=这个。IMGRECtNow。高度){ MaSky=这个。IMGRECtNow。身高-这个。配置。MaSKhA8} if(maskX这个。配置。maskwidth=这个。imgrectnow。宽度){ maskX=这个。imgrectnow。宽度-这个。配置。maskwidth} //遮罩移动这个。transform mask=` translate($ { MaSkx } px,$ { MaSky } px)`;//背景图移动这个。moveleft=-maskX *这个。配置。刻度“px”;这个。移动top=-MaSky *这个。配置。刻度“px”;}讲义:鼠标离开小图事件,此时无放大镜效果,隐藏遮罩和放大区域。

讲义(){ this . show magnifier=false this . show mask=false }以上三个事件基本上就实现了图片的放大镜功能。

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

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

切换(){ if(!这个。init){这个。init=true//原移交事件.} this . show magnifier=true this . show mask=true },在测试的过程中,发现页面滚动后,会出现遮罩定位错误的情况,原来是因为初始化时,我们固定死了小图框的位置信息(存放在this.imgRectNow),导致手动移动事件中的移动数据计算错误。

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

监听卷起事件,更新this.imgRectNow在手动移动事件中更新this.imgRectNow。这里选择了第二种。

handMove(e) { //动态获取小图的位置(或者监听滚动)让imgRectNow=这个。imgobj。getboundingclientrect();让objX=e . clientx-imgrectnow。向左;让objY=e . clienty-imgrectnow。顶部;//原手动移动事件剩余内容.},综合以上,我们已经实现了一个完美的图片放大镜功能。最终的射流研究…如下所示:

data(){ return { imgobj : },moveLeft: 0,moveTop: 0,transform mask : ` translate(0px,0px)`,show放大镜:false,showMask:false,init: false,};},计算出: { BigWidth(){返回这个。配置。缩放*这个。配置。宽度;},BigHout(){ 0返回这个。配置。缩放*这个。配置。身高;}},methods: { handMove(e) { //动态获取小图的位置(或者监听滚动)让imgRectNow=这个。imgobj。getboundingclientrect();让objX=e . clientx-imgrectnow。向左;让objY=e . clienty-imgrectnow。顶部;//计算初始的遮罩左上角的坐标让maskX=Objx-这个。配置。maskwidth/2;让MaSky=Objy-这个。配置。mask h AiR/2;//判断是否超出界限,并纠正maskY=maskY 0?0 : maskYmaskX=maskX 0?0 : maskXif(MaSky这个。配置。mask h8=imgrectnow。高度){ MaSky=imgrectnow。身高-这个。配置。口罩h8;} if(maskX这个。配置。maskwidth=imgrectnow。width){ maskX=imgrectnow。宽度-这个。配置。maskwidth} //遮罩移动这个。transform mask=` translate($ { MaSkx } px,$ { MaSky } px)`;//背景图移动这个。moveleft=-maskX *这个。配置。刻度“px”;这个。移动top=-MaSky *这个。配置。刻度“px”;},讲义(){ this . show magnifier=false this . show mask=false },RoBErt(){ if(!这个。init){这个。init=truethis.imgObj=this .$el.getElementsByClassName('小方框')[0];} this . show放大镜=truethis.showMask=true}}使用方法

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

程序可接受参数:

//小图片地址src: {type: String,},//大图片地址BigSRC: {Type: String,},//配置项配置: {type: Object,Default () {return {width:420,//放大区域height:420,//放大区域maskWidth:210,///屏蔽maskh x8 3360210,//屏蔽maskColor}}图2为长图,小图最大边缘不超过836px(双图),大图分辨率尽可能高以达到视觉效果,程序会根据配置项自动设置相应的高度和宽度。长图和宽图效果对比见图3。

配置项可以根据应用场景进行设置。本例中的配置项为2倍放大,效果如图4所示,4倍放大的效果如图5所示。

摘要

其实图片放大镜的实现并没有那么复杂,有两个核心点:

大小图像的定位,蒙版和放大区域的创建了解放大镜的原理,用代码实现DOM的移动。按照这个思路,本文做了一个简单的实现,还有一定的优化空间。欢迎大家在评论区讨论。虽然代码看起来不太优雅,但足够清晰,感兴趣的学生可以自己尝试。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

更多资讯
游戏推荐
更多+