JavaScript Image Magnifying Glass

JavaScript Image Magnifying Glass
Code Snippet:Photo Zoom Magnifying Glass - Codepen challenge
Author: Jos Faber
Published: January 19, 2024
Last Updated: January 22, 2024
Downloads: 886
License: MIT
Edit Code online: View on CodePen
Read More

This JavaScript code creates a magnifying glass effect for images on a web page. It allows you to zoom in and view a portion of an image in greater detail when you hover or click on it. The code works by tracking your mouse or touch movements and adjusting the position of the magnifying glass and the underlying image accordingly.

This magnifying glass feature is helpful for users who want to examine fine details in images without having to open a separate viewer or zoom in on the entire image.

How to Create Javascript Image Magnifying Glass

1. First, load the Normalize CSS by adding the following CDN link into the head tag of your HTML document. (Optional)

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

2. Create the HTML structure for your magnifying glass effect as below. This structure includes a container div (viewer) for your image and magnifying glass, a paper div (paper) for the image you want to magnify, and a glass div (glass) for the magnifying glass itself.

<div id="viewer" class="viewer">
	<div id="paper" class="paper"></div>
	<div id="glass" class="glass"></div>
</div>

2. Apply some basic CSS styles to create the visual elements of the magnifying glass and the viewer container. You can customize these styles to fit your design:

html,
body {
  height: 100%;
}

body {
  background-image: linear-gradient(45deg, #bbb 0%, #eee 100%);
  display: flex;
  justify-content: center;
  align-items: center;
}

.viewer {
  width: 800px;
  height: 520px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  position: relative;
  overflow: hidden;
  box-shadow: 0 0 24px rgba(0, 0, 0, 0.13);
}
.viewer .paper {
  width: 100%;
  height: 205%;
  background: url(https://assets.codepen.io/439000/newspaper_texture2832.webp);
  background-size: 800px auto;
}
.viewer .glass {
  position: absolute;
  top: 0;
  left: 0;
  width: 360px;
  height: 190px;
  border-radius: 32px;
  background: url(https://assets.codepen.io/439000/newspaper_texture2832.webp);
  background-size: 1600px 2132px;
  pointer-events: none;
  box-shadow: inset -20px 20px 40px rgba(255, 255, 255, 0.4), inset 20px -20px 40px rgba(0, 0, 0, 0.2);
  opacity: 0.95;
}
.viewer .glass::before, .viewer .glass::after {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  content: "";
  border-radius: 32px;
}
.viewer .glass::before {
  box-shadow: -6px 4px 4px rgba(0, 0, 0, 0.23);
}
.viewer .glass::after {
  background-image: url(https://assets.codepen.io/439000/dirty-window-texture-11.webp);
  background-size: cover;
  mix-blend-mode: soft-light;
  opacity: 0.9;
}

3. Finally, add the following JavaScript code to functionalize the magnifying glass. You can adjust variables like offset and smoothFactor to customize the behavior of your magnifying glass.

const normalize = (va, mi, ma) => (va - mi) / (ma - mi),
			interpolate = (no, mi, ma) => mi + (ma - mi) * no,
			map = (va, mi1, ma1, mi2, ma2) => interpolate(normalize(va, mi1, ma1), mi2, ma2),
			viewer = document.getElementById("viewer"),
			paper = document.getElementById("paper"),
			glass = document.getElementById("glass"),
			offset = 50, // dragging calculated with an edge to make it feel more comfortable
			smoothFactor = .28, // x and y are not directly set, but with a tendency towards that target (tx, ty)
			STATUS_IDLE = 1, // idle
			STATUS_DRAG = 2, // dragging
			STATUS_FADE = 3; // post dragging

let glassPos = { x: 0, y: 0, tx: 0, ty: 0 },
		glassBackPos = { x: 0, y: 0, tx: 0, ty: 0 },
		paperPos = { x: 0, y: 0, tx: 0, ty: 0 },
		status = STATUS_IDLE;

const touchstart = (e) => {
	if (status === STATUS_DRAG) return;
	status = STATUS_DRAG;
	if (!glass.classList.contains("active")) glass.classList.add("active");
};

const touchmove = (e) => {
	if (status !== STATUS_DRAG) return;
	
	e.preventDefault();
	
	const cx = e.type == 'touchmove' ? e.touches[0].clientX : e.clientX,
				cy = e.type == 'touchmove' ? e.touches[0].clientY : e.clientY,
				rect = viewer.getBoundingClientRect(),
				x = Math.min(viewer.clientWidth - offset, Math.max(offset, Math.min(viewer.clientWidth, cx - rect.left))),
				y = Math.min(viewer.clientHeight - offset, Math.max(offset, Math.min(viewer.clientHeight, cy - rect.top))),
				normX = normalize(x, offset, viewer.clientWidth - offset),
				normY = normalize(y, offset, viewer.clientHeight - offset),
				diffX = paper.clientWidth - viewer.clientWidth,
				diffY = paper.clientHeight - viewer.clientHeight;

	glassPos.tx = interpolate(normX, 0, viewer.clientWidth - glass.clientWidth); 
	glassPos.ty =interpolate(normY, 0, viewer.clientHeight - glass.clientHeight);
	
	paperPos.tx = interpolate(normX, 0, diffX);
	paperPos.ty =interpolate(normY, 0, diffY);
	
	glassBackPos.tx = interpolate(normX, 0, 100);
	glassBackPos.ty = interpolate(normY, 0, 100);
};

const touchend = () => {
	if (status !== STATUS_DRAG) return;
	status = STATUS_FADE;
	if (glass.classList.contains("active")) glass.classList.remove("active");
	// console.log("touchend");
};

const magnify = (() => {})();

viewer.addEventListener("touchstart", touchstart);
viewer.addEventListener("touchmove", touchmove);
viewer.addEventListener("touchend", touchend);
viewer.addEventListener("touchcancel", touchend);

viewer.addEventListener("mousedown", touchstart);
viewer.addEventListener("mousemove", touchmove);
viewer.addEventListener("mouseup", touchend);

(function tick() {
	// repeat
	requestAnimationFrame(tick);
	
	// nothing on idle
	if (status === STATUS_IDLE) return;
	
	// return to idle when smoothing out is at its end
	if (status === STATUS_FADE && Math.abs(glassPos.tx - glassPos.x) < 0.2) status = STATUS_IDLE;
	
	// smooth motion towards targets
	paperPos.x += smoothFactor * (paperPos.tx - paperPos.x);
	paperPos.y += smoothFactor * (paperPos.ty - paperPos.y);
	glassPos.x += smoothFactor * (glassPos.tx - glassPos.x);
	glassPos.y += smoothFactor * (glassPos.ty - glassPos.y);
	glassBackPos.x += smoothFactor * (glassBackPos.tx - glassBackPos.x);
	glassBackPos.y += smoothFactor * (glassBackPos.ty - glassBackPos.y);

	// transformations
	paper.style.transform = `translate(${-paperPos.x}px, ${-paperPos.y}px)`;
	glass.style.transform = `translate(${glassPos.x}px, ${glassPos.y}px)`;
	glass.style.backgroundPosition = `${glassBackPos.x}% ${glassBackPos.y}%`;
	
})();

That’s it! You’ve successfully implemented a JavaScript Image Magnifying Glass effect on your website. Users can now hover or click on images to explore them in detail. . If you have any questions or suggestions, feel free to comment below.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About CodeHim

Free Web Design Code & Scripts - CodeHim is one of the BEST developer websites that provide web designers and developers with a simple way to preview and download a variety of free code & scripts. All codes published on CodeHim are open source, distributed under OSD-compliant license which grants all the rights to use, study, change and share the software in modified and unmodified form. Before publishing, we test and review each code snippet to avoid errors, but we cannot warrant the full correctness of all content. All trademarks, trade names, logos, and icons are the property of their respective owners... find out more...

Please Rel0ad/PressF5 this page if you can't click the download/preview link

X