October 24, 2024
Chicago 12, Melborne City, USA
CSS

Magnifying Glass Effect – part 2


After I got this sample working, thanks to help from a few people, I wondered about doing it in a way that allows it to be responsive and to also include any filters added to the source image. I came up with this:

// The magnification factor; an integer greater than 1
const zoom = 3; 
// The radius of the glass (as a percentage of the image's width)
// a number between 1 and 100, inclusive
const radius = 25;

const container = document.querySelector('.container');
const glass = document.querySelector('.glass');
const { style } = glass;
style.setProperty('--zoom', zoom);

// Add the magnified image as a clone
// This way it'll include any filter applied to the original image
const img = container.querySelector('img').cloneNode();
glass.append(img);

container.addEventListener('mousemove', (e) => {
  // ISSUE: The diameter of the glass is, as the magnification gets bigger, smaller than expected
  const clipPath = `${radius / zoom}% at ${e.offsetX * zoom}px ${e.offsetY * zoom}px`;
  
  style.setProperty('--clip-path', clipPath);
  style.setProperty('--left', `${(zoom - 1 ) * -e.offsetX}px`)
  style.setProperty('--top', `${(zoom - 1 ) * -e.offsetY}px`)
});
.container {
  position: absolute;
  width: 40%;
  height: fit-content;
  left: 8%;
  top: 20%;
  border: 1px dashed grey;
  overflow: hidden;
  cursor: none;

  &> img {
    width: 100%; 
    height: auto; 
    display: block;
  }

  &:hover .glass {
    opacity: 1;
  }

  .glass {
    position: absolute;
    left: var(--left);
    top:  var(--top);
    width: 100%;
    height: auto;
    clip-path: circle(var(--clip-path));
    pointer-events: none;
    transition: opacity 0.2s;
    opacity: 0;

    img {
      width: calc(var(--zoom) * 100%);
      display: block;
    }
  }
}
<div class="container">
  <img src="https://i.sstatic.net/Z4aOFrum.jpg" alt="bg">
  <div class="glass"></div>
</div>

The issue that I can’t work out how it’s happening (and so I can’t fix) is that when the zoom factor is 2 the displayed radius of the glass matches the value I set – for example, if I set the radius to 25 the glass displays at 50% of the source image – but if I increase the zoom the glass displays smaller than expected even though the magnified image is larger (and so the glass size should match.)



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video