京东商品首页随便选择一个商品进入到商品详情页,商品放大镜就是如下图所示的效果:
从图中分析可得:
(1)首先在鼠标放置在商品上的时候会出现一个黄色的透明遮罩层
(2)遮罩层会随着鼠标的移动一起移动,这里要注意遮罩层的移动范围在图片盒子内部
(3)当出现遮罩层的时候右边同时也会出现一个盒子,盒子里面是放大后的商品图
PS:看起来好像右边盒子里的图片是左边遮罩层所覆盖部分的放大—专业称为“放大镜”效果,但实际上这里是两张图片,一张小图片放在左边的盒子里,一张大图片放在右边的盒子里,遮罩层在左边盒子里面移动时,大图片在右边盒子里面移动,从而实现视觉上的放大效果。
———————
实现:
(1)准备素材:首先去京东的首页把某个商品的大小图片全部扒下来
(2)html部分:准备两个大小一样的div盒子,一个放在左边(商品小图片+遮罩层),一个放在右边(商品大图片)
<div class="preview_img">
<img src="image/4.jpg" alt="">
<div class="mask"></div>
</div>
<div class="big">
<img src="image/5.jpg" alt="" class="big_img">
</div>
(3)CSS部分:这部分的设置可以按照自己的想法设置,毕竟我很菜,存在一些不规范或不好的地方,只提供参考。
这里要注意遮罩层和右边的div一开始要设置 display:none 隐藏起来,只有当鼠标在左边div里面时才显示出来(这块属于js实现)。
这里还要设置position属性,遮罩层和大图片都是以父盒子作为参考进行定位的,所以它们必须是绝对定位,另外右边的 div 也是通过定位固定在右边位置的。
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.preview_img {
position: relative;
width: 352px;
height: 451px;
border: 1px solid #ccc;
margin:20px 50px ;
}
.mask {
display: none;
position: absolute;
top: 0;
left:0;
width: 200px;
height: 200px;
background-color: #FEDE4F;
opacity: 0.3;
}
.big {
display: none;
position: absolute;
top:20px;
left:412px ;
width: 352px;
height: 451px;
border: 1px solid #ccc;
overflow: hidden;
}
.big .big_img {
position: absolute;
top:0;
left: 0;
}
(4)JS部分:js这块遮罩层随鼠标移动比较简单,难点在于放大镜效果的实现,这里涉及到一个公式,遮罩层在左边盒子里面移动,右边盒子在大图片上面移动(先这样看比较容易理解,有个比例关系在里面),那么比例关系为:
mask移动的距离/mask最大的移动距离 = 右边div移动的距离/右边div最大的移动距离
=> 右边div移动距离 = (mask移动距离*右边div最大的移动距离)/mask最大的移动距离
【 mask移动距离灵活转换为鼠标在左边div里面的坐标moveX和moveY 】
此时根据相对运动,参考点换成右边div,那么此时右边div不动,大图片像相反的方向运动,所以最后大盒子的top和left设置的时候要加“-”。
【PS:我觉得这块的比例关系也不算太好理解,需要多思考思考,应该是我比较笨吧。。。】
var preview_img = document.querySelector('.preview_img');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
var big_img = document.querySelector('.big_img');
preview_img.addEventListener('mouseover',function(){
mask.style.display = 'block';
big.style.display = 'block';
})
preview_img.addEventListener('mouseout',function(){
mask.style.display = 'none';
big.style.display = 'none';
})
preview_img.addEventListener('mousemove',function(e){
// 获得鼠标在页面中的坐标
var mouseX = e.pageX ;
var mouseY = e.pageY ;
// 获得preview_img盒子在页面中的位置
var boxLeft = preview_img.offsetLeft ;
var boxTop = preview_img.offsetTop ;
// 获得鼠标在preview_img盒子里面的坐标
var x = mouseX - boxLeft ;
var y = mouseY - boxTop ;
// 让遮罩层跟着鼠标移动,最好让鼠标位于遮罩层盒子的中间
var moveX = x - mask.offsetLeft/2 ;
var moveY = y - mask.offsetHeight/2;
//这里实现了遮罩层跟着鼠标移动,但是要注意限制遮罩层的移动范围在preview_img盒子里面
if( moveX <= 0){
moveX = 0 ;
}else if( moveX >= preview_img.offsetWidth-mask.offsetWidth){
moveX = preview_img.offsetWidth-mask.offsetWidth;
}
// 纵轴上同理
if( moveY <= 0){
moveY = 0 ;
}else if ( moveY >= preview_img.offsetHeight-mask.offsetHeight){
moveY = preview_img.offsetHeight-mask.offsetHeight;
}
mask.style.top = moveY + 'px' ;
mask.style.left = moveX + 'px' ;
//接下来实现放大镜的功能:大图片的移动距离=遮挡层移动距离*大图片最大移动距离/遮挡层的最大移动距离
// 遮挡层移动的最大距离
var maskMaxX = preview_img.offsetWidth - mask.offsetWidth;
var maskMaxY = preview_img.offsetHeight - mask.offsetHeight ;
// 大图片的最大移动距离
var bigImgMaxX = big_img.offsetWidth - big.offsetWidth ;
var bigImgMaxY = big_img.offsetHeight - big.offsetHeight ;
// 遮挡层移动的距离 moveX 和 moveY
// 大图片的移动距离
var bigX = moveX * bigImgMaxX / maskMaxX ;
var bigY = moveY * bigImgMaxY / maskMaxY ;
big_img.style.left = -bigX+'px';
big_img.style.top = -bigY +'px';
})