Detailed explanation of JS magnifier demo

Posted by pstevereynolds on Tue, 31 Dec 2019 21:47:38 +0100


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
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


<!DOCTYPE html>
<html lang="en">
	<meta charset="UTF-8">
		/*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*/
			width: 200px;
			height: 200px;
			margin-left: 100px;
			margin-top: 100px;
			/*margin-top: 1000px;  Test response with scroll bar*/
			position: relative;
			border: solid 1px #000;
			/*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;
			position: absolute;
			left: -10000px;
			top: 0;
			width: 100px;
			height: 100px;
			background: #000;
	<div class="zoom">
		<div class="small_area">
			<img src="images/zoom.jpg" width="200" height="200" />
			<span class="mask"></span>
		<div class="big_area">
			<img src="images/zoom.jpg" width="620" height="620">

		// 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 = (simg.offsetWidth/bimg.offsetWidth)*big.clientWidth+"px"; = (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(){ = 0; = 210+"px";
		// Event occurs when mouse moves into small display area: 1. Mask layer disappears 2. Large display area disappears
		small.onmouseleave=function(){ = -10000+"px"; = -10000+"px";
		// Mouse movement in small display area
			// 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 = nLeft+"px"; = nTop+"px";

			// Set the moving position of the large image to follow the mask layer percentage (brought in by syntax) = -(bimg.offsetWidth-big.clientWidth)*(nLeft/(simg.clientWidth-mask.offsetWidth))+"px"; = -(bimg.offsetHeight-big.clientHeight)*(nTop/(simg.clientHeight-mask.offsetHeight))+"px";