效果展示
思路
- 使用jquery获取dom和css等
- 主要是计算滑块在当前盒子中滑动的比例,到展示出来的图片在大盒子的位置
- 动态计算
JS版本
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><style> *{ margin: 0; padding: 0; } .wrapper{ padding: 30px 10%; } .current-box , .target-box{ float: left; } .current-box{ position: relative; } .current-box .current-image-box{ width: 300px; height: 300px; } .current-box .current-image-box img{ width: 100%; height: 100%; } .current-box .mast{ position: absolute; width: 100px; height:100px; background-color: rgba(255, 0, 0, 0.3); top: 0; left: 0; display:none; } .target-image-box{ position: relative; width: 400px; height: 400px; overflow: hidden; border: 2px dashed #999; } .target-image-box .target-image{ position: absolute; top: 0; left: 0; }</style><body> <div class="wrapper"> <div class="current-box"> <div class="current-image-box"> <img class="current-image" src="./images/1.jpeg"></img> </div> <div class="mast"></div> </div> <div class="target-image-box"> <img class="target-image" src="./images/1.jpeg"></img> </div> </div></body><script> // 思路, // 1、通过计算当前照片和mask的比例计算出要展示的照片的大小来 let wrapper = document.getElementsByClassName('wrapper')[0], currentBox = document.getElementsByClassName('current-box')[0], currentImageBox = document.getElementsByClassName('current-image-box')[0], currentImage = document.getElementsByClassName('current-image')[0], mast = document.getElementsByClassName('mast')[0], targetImageBox = document.getElementsByClassName('target-image-box')[0], targetImage = document.getElementsByClassName('target-image')[0]; // 获取元素的高度和宽地的方法 function getStyle(element,attr){ return Number.parseInt(window.getComputedStyle(element)[attr]) } // 设置css样式的方法 function setCss(element,attr,value){ element.style[attr] = value } // 获取offset到BODY的距离 function offset(element){ let offsetL = element.offsetLeft, offsetT=element.offsetTop, parentEle=element.offsetParent; while(parentEle&&parentEle.targetName !=='BODY'){ offsetL+= parentEle.offsetLeft; offsetT+= parentEle.offsetTop; parentEle = parentEle.offsetParent; } return { left:offsetL, top:offsetT } } // 让mask比上当前盒子的比例乘以目标盒子的宽高为目标图片的宽高 let currentH = getStyle(currentBox,'height'), currentW = getStyle(currentBox,'width'), currentL = currentBox.offsetLeft, currentT = currentBox.offsetTop, mastH = getStyle(mast,'height'), mastW = getStyle(mast,'width'), mastL = offset(mast).left, mastT = offset(mast).top, targetW = getStyle(targetImageBox,'height'), targetH = getStyle(targetImageBox,'width'); setCss(targetImage,'width', currentW/mastW*targetW + 'px') setCss(targetImage,'height', currentH/mastH*targetH + 'px') let scale = currentW/mastW*targetW / currentW; // console.log(scale,'scale') // 4 // 2、按住遮照鼠标状态变为move状态,绑定移动事件 // 3、计算进入的时候的当前点的坐标,计算滑动的距离占 let entryPointX,entryPointY,slideX,slideY; // 计算滑动的值 function computed(ev){ let offsetX = ev.pageX - currentL - mastH/2, offsetY = ev.pageY- currentT - mastW/2; // 边界判断 let minL = 0, minT = 0, maxL = currentW - mastW, maxT = currentH- mastH; offsetX = offsetX < minL ? 0 : offsetX > maxL? maxL : offsetX; offsetY = offsetY < minT ? 0: offsetY > maxT? maxT : offsetY; setCss(mast,'top', offsetY + 'px') setCss(mast,'left', offsetX + 'px') // 判断目标图片滑动的距离,和mask是相反的倍数关系 setCss(targetImage,'top', - offsetY*scale + 'px') setCss(targetImage,'left', - offsetX*scale + 'px') } currentBox.addEventListener('mouseenter',function(ev){ setCss(mast,'cursor', 'move') setCss(mast,'display', 'block') computed(ev) }) currentBox.addEventListener('mousemove',computed) currentBox.addEventListener('mouseleave',function(ev){ setCss(mast,'cursor', 'default') setCss(mast,'display', 'none') })</script></html>
jQuery版本
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>放大镜</title> <style> .magnifier { box-sizing: border-box; margin: 20px auto; width: 600px; } .magnifier .abbre, .magnifier .origin { float: left; } .magnifier .abbre { position: relative; box-sizing: border-box; width: 250px; height: 240px; } .magnifier .abbre img { width: 100%; height: 100%; } .magnifier .abbre .mark { display: none; position: absolute; top: 0; left: 0; width: 20px; height: 10px; background: rgba(255, 0, 0, .3); cursor: move; } .magnifier .origin { display: none; position: relative; box-sizing: border-box; width: 350px; height: 340px; overflow: hidden; } .magnifier .origin img { position: absolute; top: 0; left: 0; } </style> </head> <body> <section class="magnifier clearfix"> <!-- 左侧缩略图 --> <div class="abbre"> <img src="images/1.jpeg" alt=""> <div class="mark"></div> </div> <!-- 右侧原图(大图) --> <div class="origin"> <img src="images/1.jpeg" alt=""> </div> </section> <script src="js/jquery/dist/jquery.min.js"></script> <script> // 1.等待DOM结构加载完 DOMContentLoaded // 2.形成一个闭包,保证私有性 $(function () { let $magnifier = $('.magnifier'), $abbre = $magnifier.find('.abbre'), $mark = $abbre.find('.mark'), $origin = $magnifier.find('.origin'), $originImg = $origin.find('img'); // 首先按照比例计算大图的样式 let abbreW = $abbre.width(), abbreH = $abbre.height(), markW = $mark.width(), markH = $mark.height(), originW = $origin.width(), originH = $origin.height(), originImgW = null, originImgH = null, offset = $abbre.offset(); originImgW = originW / (markW / abbreW); originImgH = originH / (markH / abbreH); $originImg.css({ width: originImgW, height: originImgH }); // 处理鼠标在ABBRE中进入,离开,移动的相关操作 function computed(ev) { // 计算MARK的位置以及根据MARK的移动计算出大图的移动距离 let markT = ev.pageY - offset.top - markH / 2, markL = ev.pageX - offset.left - markW / 2, originImgL = null, originImgT = null; // 边界判断 let minL = 0, minT = 0, maxL = abbreW - markW, maxT = abbreH - markH; markL = markL < minL ? minL : (markL > maxL ? maxL : markL); markT = markT < minT ? minT : (markT > maxT ? maxT : markT); originImgL = markL / abbreW * originImgW; originImgT = markT / abbreH * originImgH; $mark.css({ left: markL, top: markT }); $originImg.css({ left: -originImgL, top: -originImgT }); } $abbre.mouseenter(function (ev) { $mark.css('display', 'block'); $origin.css('display', 'block'); computed(ev); }) .mousemove(computed) .mouseleave(function (ev) { $mark.css('display', 'none'); $origin.css('display', 'none'); }); }); </script> </body></html>