Preface:
This magnifying glass can directly change the picture (I use zoom.jpg). The premise is that the layout must be the same as mine, or the clientX and offsetLeft in it must be changed accordingly.
First understand the mathematical algorithm:
Find mask width of mask layer
Large, large display area, small, mask layer
1. Small graphs are scaled equally to large graphs
2. The mask layer is zoomed in the large display area
Small / large = mask layer / large display area
Mask layer = large image display area * (small image / large image);
------------------------------------------------
Large active area = large display area
Small map active area = small map mask layer
Mask layer offset / small map active area = large map offset / large map active area
Large map offset = large map active area * (mask layer offset / small map active area)
Large image offset = (large image large image display area) * (mask layer offset / (small image mask layer))
Decomposition action:
1. Layout
2. Calculate the width and height of the mask layer
3. Move in and move out event processing for small binding
4. Bind mouse move in event processing for small
4.1. Calculate the offset of mask
(e.clientX-zoom.offsetLeft-zoom.clientLeft-mask.offsetWidth/2)
4.2. Specify the maximum and minimum offset of mask
4.3. Calculate large drawing offset (refer to formula)
matters needing attention:
1. Mouse move in and mouse move events should be added to small
2. The value of offsetX/offsetY is not accurate, so clientX/clientY should be used instead
Effect:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> /*In the whole div, only the small display area is placed, and the large display area is hidden. In this way, you can directly set the properties of zoom*/ .zoom{ width: 200px; height: 200px; margin-left: 100px; margin-top: 100px; /*margin-top: 1000px; Test response with scroll bar*/ position: relative; border: solid 1px #000; } .big_area{ /*The width and height of large display area can be changed directly*/ width: 200px; height: 200px; position: absolute; left: -10000px; top: -1px; border: solid 1px #000; overflow: hidden; } .big_area img{ position: absolute; left: 0; top: 0; } /*mask*/ .mask{ position: absolute; left: -10000px; top: 0; width: 100px; height: 100px; background: #000; opacity:0.65; filter:alpha(opacity=65); } </style> </head> <body> <div class="zoom"> <div class="small_area"> <img src="images/zoom.jpg" width="200" height="200" /> <span class="mask"></span> </div> <div class="big_area"> <img src="images/zoom.jpg" width="620" height="620"> </div> </div> <script> // Get the corresponding node element var zoom = document.querySelector('.zoom'); var simg = document.querySelector('.small_area img'); var bimg = document.querySelector('.big_area img'); var big = document.querySelector('.big_area'); var small = document.querySelector('.small_area'); var mask = document.querySelector('.mask'); // Set mask layer width height small drawing width divided by large drawing width multiplied by large display area border mask.style.width = (simg.offsetWidth/bimg.offsetWidth)*big.clientWidth+"px"; mask.style.height = (simg.offsetHeight/bimg.offsetHeight)*big.clientHeight+"px"; // Defines the maximum edge distance of the mask layer, that is, the maximum moving distance var maxW = simg.clientWidth - mask.offsetWidth; var maxH = simg.clientHeight - mask.offsetHeight; // Events occur when the mouse moves into the small display area: 1. mask layer display 2. large display area display small.onmouseenter=function(){ mask.style.left = 0; big.style.left = 210+"px"; } // Event occurs when mouse moves into small display area: 1. Mask layer disappears 2. Large display area disappears small.onmouseleave=function(){ mask.style.left = -10000+"px"; big.style.left = -10000+"px"; } // Mouse movement in small display area small.onmousemove=function(e){ // Resolve compatibility issues e = e || window.event; // Define two variables to keep the mouse position in the middle of the mask layer position var nLeft = e.pageX-zoom.offsetLeft-zoom.clientLeft-mask.offsetWidth/2; var nTop = e.pageY-zoom.offsetTop-zoom.clientTop-mask.offsetHeight/2; // Set the mask layer to always display in the small display area, that is, judge the nLeft and nTop values nLeft = Math.min(maxW,Math.max(0,nLeft)); nTop = Math.min(maxH,Math.max(0,nTop)); // Mask layer location mask.style.left = nLeft+"px"; mask.style.top = nTop+"px"; // Set the moving position of the large image to follow the mask layer percentage (brought in by syntax) bimg.style.left = -(bimg.offsetWidth-big.clientWidth)*(nLeft/(simg.clientWidth-mask.offsetWidth))+"px"; bimg.style.top = -(bimg.offsetHeight-big.clientHeight)*(nTop/(simg.clientHeight-mask.offsetHeight))+"px"; } </script> </body> </html>