JSFiddle - React, Tailwind, and code Playground

by panino

HTML

<h1>Noche: escena de la costa mediterránea con pescadores y barcas - Claude-Joseph Vernet</h1>
    <img src="https://upload.wikimedia.org/wikipedia/commons/e/e9/Claude-Joseph_Vernet_-_Nuit-_Sc%C3%A8ne_c%C3%B4te_m%C3%A9diterran%C3%A9enne_avec_les_p%C3%AAcheurs_et_les_bateaux.jpg" alt="Noche: escena de la costa mediterránea con pescadores y barcas - Claude-Joseph Vernet">

CSS

*{
			margin:0;
			padding:0;
			box-sizing:border-box;
	}
  #lupa {
      width: 200px;
      height: 200px;
      position: absolute;
      left: 0;
      top: 0;
      overflow: hidden;
      z-index: 10000;
      border: 3px solid #000;
			background:#fff;
			border-radius:50%;
			box-shadow: 0px 2px 5px 3px rgba(0,0,0,0.67);
			pointer-events: none;
  }
  #clone {
      position: absolute;
      transform-origin: top left;
      transform: scale(var(--zoom-level), var(--zoom-level));
			width:100vw;
  }
  body{
			width:100vw;
			overflow-x:hidden;
			font-family:Verdana, Geneva, sans-serif;
			16px;
  }
  img{
			width:100%;
			height:auto;
	}
	h1{
			font-size:1.5rem;
			padding:15px;
	}

JavaScript

let zoomLevel = 3;
document.documentElement.style.setProperty('--zoom-level', zoomLevel);
let lupaDiv = document.createElement('div');
lupaDiv.id = 'lupa';
let cloneDiv = document.createElement('div');
cloneDiv.id = 'clone';
cloneDiv.innerHTML = document.body.innerHTML;
lupaDiv.appendChild(cloneDiv);
document.body.appendChild(lupaDiv);
function moveLupa(e) {
	let _e=e.changedTouches ? e.changedTouches[0] : e;
  let mouseX = _e.pageX;
  let mouseY = _e.pageY;
  lupaDiv.style.left = (mouseX - lupaDiv.offsetWidth / 2) + 'px';
  lupaDiv.style.top = (mouseY - lupaDiv.offsetHeight / 2) + 'px';
   cloneDiv.style.left = (-mouseX * zoomLevel + lupaDiv.offsetWidth / 2) + 'px';
   cloneDiv.style.top = (-mouseY * zoomLevel + lupaDiv.offsetHeight / 2) + 'px';
}
document.addEventListener('mousemove', moveLupa);
document.addEventListener('touchmove', moveLupa);