昨天在做商品详情页面时,遇到一个需求,就是图片放大镜效果。在图片上鼠标划过时,右侧出现一个大图,用于展示鼠标移过的区域,也就是图片放大镜效果。 效果图基本类似如下: 我之前有篇文章js实现图片放大镜效果:https://blog.csdn.net/yehaocheng520/article/details/115278622?spm=1001.2014.3001.5501
当时是用js 实现的效果,因此现在要把代码嫁接到vue 创建的项目中。
html 部分代码:
<div class="big-img-box" ref="big-img-box" @mouseleave="moveend">
<div class="imgWrap" @mouseenter="movestart" @mousemove.stop>
<img :src="HOST + commonUploadFileUrl + bigImgsrc" alt="" />
</div>
<div
v-if="bigImgUrl"
@mousemove.stop
@mousemove="move"
class="move"
ref="move"
:style="{ left: -left / 3 + 'px ', top: -top / 3 + 'px' }"
></div>
<div
class="bigPic"
ref="bigPic"
v-if="bigImgUrl"
:style="{ backgroundPosition: left + 'px ' + top + 'px' }"
></div>
</div>
<div class="small-img-box">
<div class="img-content-box">
<ul>
<li
v-for="(item, index) in detailInfo.images"
:key="index"
@mouseover="handleBigImg(item, index)"
:class="{ smallImgBorder: currentSmallImgIndex == index }"
>
<img :src="HOST + commonUploadFileUrl + item.src" alt="" />
</li>
</ul>
</div>
</div>
图片放大镜效果的重点——css 和js 部分
css 部分的关键
这个效果有个特别的css 样式,分析一下有几个元素; 左侧图片原图:这个就是个普通的图片,可以通过background 设置图片路径,也可以是一个img 标签来展示。 图片上的鼠标移动区域:这个比较需要注意的是:这个是个绝对布局,为了js 部分计算简单,我使用了200x200 的大小,颜色为一个偏透明的色号 右侧大图:这个也是个绝对布局,采用background 的方式来设置图片路径和背景参数,background-size 设置成大于1的参数。
css 部分代码如下:
.big-img-box {
width: 480px;
height: 360px;
margin: 0 0 20px;
border: 1px solid #eee;
position: relative;
.imgWrap {
width: 100%;
height: 100%;
overflow: hidden;
}
.move {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
background: rgba(0, 0, 255, 0.15);
cursor: move;
}
.bigPic {
width: 480px;
height: 480px;
position: absolute;
left: 480px;
top: 0;
border: 2px solid #f90;
background-position: 0 0;
background-size: 300% 300%;
background-repeat: no-repeat;
z-index: 2;
}
}
原图下方的小图部分:就是一排普通的图片,css 样式部分并无不同
.small-img-box {
width: 480px;
height: 70px;
position: relative;
.img-content-box {
width: 100%;
margin: 0 auto;
height: 100%;
display: block;
ul {
width: 105%;
height: 100%;
li {
display: inline-block;
width: 88px;
height: 100%;
margin-right: 10px;
overflow: hidden;
img {
display: block;
width: 100%;
}
}
}
}
}
js 部分的关键——鼠标的移入移出事件+dom 元素的位置及大小
在用js 实现此效果时,需要用到几个重要的参数
- 左侧原图距离左侧的大小——
oAppLeft - 左侧原图距离上方的大小——
oAppTop - 鼠标移入后的位置
e.pageX e.pageY ,之前的js 版本的效果用的是e.clientX e.clientY ,这个e.clientX 有问题,这个参数会跟着屏幕的滚动而发生变化,我们需要的是一个不会变化的值,鼠标的位置对于整个页面来说是固定的,而不是随着页面的滚动发生变化。 - 移动区域的大小——可以通过
style.width style.height 来获取,但是我在css 部分为了方便,直接固定为200X200 ,因此我这边是直接使用的200 的数值
左侧原图距离左边和上边的大小——oAppLeft 与oAppTop 的计算
mounted() {
this.$nextTick(() => {
this.oAppLeft = this.$refs["big-img-box"].offsetLeft;
this.oAppTop = this.$refs["big-img-box"].offsetTop;
});
},
针对普通的dom 元素可以通过this.$refs[xxx].xxx 的方式来获取
针对v-for 等渲染的dom 元素可以通过this.$refs[xxx][0].xxx 的方式来获取
鼠标移入移出需要注意的部分:
- 左侧原图具体展示哪张图片可以根据一个字段
bigImgUrl 来处理。下方下图鼠标移入时,更改bigImgUrl 的值,就可以了 - 鼠标移入到左侧原图时,开始出现选择框,右侧展示选择框中的图片放大效果,也就是说:左侧原图需要加一个鼠标移入的监听事件
<div class="big-img-box" ref="big-img-box" @mouseleave="moveend">
<div class="imgWrap" @mouseenter="movestart" @mousemove.stop>
<img :src="HOST + commonUploadFileUrl + bigImgsrc" alt="" />
</div>
<div v-if="bigImgUrl" @mousemove.stop @mousemove="move" class="move" ref="move"
:style="{ left: -left / 3 + 'px ', top: -top / 3 + 'px' }"></div>
<div class="bigPic" ref="bigPic" v-if="bigImgUrl" :style="{ backgroundPosition: left + 'px ' + top + 'px' }"> </div>
</div>
上面html 结构中的class='imgWrap'就是左侧原图部分 ;
鼠标移入的函数——鼠标移入的位置就是选择框的初始位置
movestart(e) {
this.move(e);
this.bigImgUrl = this.bigImgsrc;
var imgUrl = this.HOST + this.commonUploadFileUrl + this.bigImgUrl;
this.$nextTick(() => {
this.$refs.bigPic.style.backgroundImage = `url(${imgUrl})`;
});
},
选择框鼠标移动的位置——改变选择框的位置
move(e) {
var left = e.pageX - this.oAppLeft - 100;
var top = e.pageY - this.oAppTop - 100;
if (left < 0) {
left = 0;
} else if (left > 280) {
left = 280;
}
if (top < 0) {
top = 0;
} else if (top > 160) {
top = 160;
}
this.left = -left * 3;
this.top = -top * 3;
},
左侧原图鼠标移出——隐藏选择框和大图(将bigImgUrl 置为空即可)
moveend() {
this.bigImgUrl = "";
this.left = 0;
this.top = 0;
},
最终功能实现!!!!
|