京东放大镜效果实现 + 原理分析
效果展示:
在左侧效果图区域按下鼠标会显示黄色覆盖层与右边的放大图,移动光标黄色覆盖层跟随移动并且可以改变右侧放大的范围 ,松开鼠标后黄色覆盖层与右侧放大区域隐藏
实现原理:
(文字描述过于生硬,下方有JS 部分单独的代码分析,更加易懂!)
(文字描述过于生硬,下方有JS 部分单独的代码分析,更加易懂!)
首先我们要获取到鼠标在左侧盒子内的坐标,以横坐标为例,x=光标到页面左侧距离-盒子到左侧距离,说白了就是 e.clientX - leftbox.offsetLeft,纵坐标同理。获取过后 x 与 y 得到的值减去黄色遮盖层一半的宽度 得到的分别为黄色遮盖层到左侧盒子的距离,maskX=mask.offsetWidth/2,到盒子上方竖直距离同理,然后赋值给盒子的绝对位移左上边距,这里用到了子绝父相来保证遮盖层的参照系是左侧盒子。为了防止遮盖层移动超出左侧盒子,用到了if语句判断X方向与Y方向,最难的部分在于小盒子与大盒子移动的比例,我们应该得到以下公式,右侧放大区域大图片:大图片移动的距离 = 遮盖层移动的距离 * 大图片最大移动距离 / 遮盖层最大移动距离,这样就可以得到大图片移动的距离了,但要注意此处要设置和小图片相反的移动方向,故在前面加符号即可。
JS区域代码:
document.addEventListener('DOMContentLoaded',function(){ var smallbox=document.querySelector('.smallbox'); var mask=document.querySelector('.mask'); var bigbox=document.querySelector('.bigbox'); smallbox.addEventListener('mousedown',function(e){ bigbox.style.display='block'; mask.style.display='block'; smallbox.addEventListener('mousemove',fn) function fn(e){ var X=e.clientX-smallbox.offsetLeft; //光标在盒子内的坐标 var Y=e.clientY-smallbox.offsetTop; maskX=X-mask.offsetWidth/2; //遮盖层到盒子左和上的距离 maskY=Y-mask.offsetHeight/2; if(maskX=smallbox.offsetWidth-mask.offsetWidth){ maskX=smallbox.offsetWidth-mask.offsetWidth; } if(maskY=smallbox.offsetHeight-mask.offsetHeight){ maskY=smallbox.offsetHeight-mask.offsetHeight; } mask.style.left=maskX + 'px'; //判断完是否出界后将距离赋值给遮盖层 mask.style.top=maskY + 'px'; var bigphoto=document.querySelector('.bigphoto'); //获取到右侧的大图片 var bigMapMaxX=bigphoto.offsetWidth-bigbox.offsetWidth; //大图片最大的移动距离 var bigMapMaxY=bigphoto.offsetHeight-bigbox.offsetHeight; var maskMaxX=smallbox.offsetWidth-mask.offsetWidth; //遮盖层最大的移动距离 var maskMaxY=smallbox.offsetHeight-mask.offsetHeight; var maxMapX=maskX*bigMapMaxX/maskMaxX; //大盒子移动的距离 var maxMapY=maskY*bigMapMaxY/maskMaxY; bigphoto.style.left=-maxMapX + 'px'; bigphoto.style.top=-maxMapY + 'px'; } smallbox.addEventListener('mouseup',function(e){ //鼠标松开后删除mousemove事件 smallbox.removeEventListener('mousemove',fn); mask.style.display='none'; bigbox.style.display='none'; }) }) })
完整代码:
Document .smallbox{ position: relative; margin-top: 20px; width: 400px; height: 400px; box-sizing: border-box; cursor: move; } .mask{ display: none; position: absolute; top: 0px; left: 0px; width: 300px; height: 300px; background-color: rgba(255, 224, 88, 0.363); } .smallphoto{ width: 400px; height: 400px; box-sizing: border-box; border: 1px solid; } .bigbox{ position: absolute; top: 28px; left: 503px; width: 500px; height: 500px; box-sizing: border-box; border: 1px solid; overflow: hidden; display: none; } .bigphoto{ position: absolute; top: 0px; left: 0px; } .left{ float: left; width: 80px; height: 900px; background-color: rgb(255, 255, 255); } .right{ margin-left: 10px; float:left; width: 1180px; height: 900px; background-color: rgb(255, 255, 255); } document.addEventListener('DOMContentLoaded',function(){ var smallbox=document.querySelector('.smallbox'); var mask=document.querySelector('.mask'); var bigbox=document.querySelector('.bigbox'); smallbox.addEventListener('mousedown',function(e){ bigbox.style.display='block'; mask.style.display='block'; smallbox.addEventListener('mousemove',fn) function fn(e){ var X=e.clientX-smallbox.offsetLeft; var Y=e.clientY-smallbox.offsetTop; maskX=X-mask.offsetWidth/2; maskY=Y-mask.offsetHeight/2; if(maskX=smallbox.offsetWidth-mask.offsetWidth){ maskX=smallbox.offsetWidth-mask.offsetWidth; } if(maskY=smallbox.offsetHeight-mask.offsetHeight){ maskY=smallbox.offsetHeight-mask.offsetHeight; } mask.style.left=maskX + 'px'; mask.style.top=maskY + 'px'; var bigphoto=document.querySelector('.bigphoto'); var bigMapMaxX=bigphoto.offsetWidth-bigbox.offsetWidth; var bigMapMaxY=bigphoto.offsetHeight-bigbox.offsetHeight; var maskMaxX=smallbox.offsetWidth-mask.offsetWidth; var maskMaxY=smallbox.offsetHeight-mask.offsetHeight; var maxMapX=maskX*bigMapMaxX/maskMaxX; var maxMapY=maskY*bigMapMaxY/maskMaxY; bigphoto.style.left=-maxMapX + 'px'; bigphoto.style.top=-maxMapY + 'px'; } smallbox.addEventListener('mouseup',function(e){ smallbox.removeEventListener('mousemove',fn); mask.style.display='none'; bigbox.style.display='none'; }) }) })