Zoom Effect

Page section: playground

The final project in the Florin Pop series.

random image

How it works

Most of this is done using CSS. An overlarge image is put in a smaller container. The image width is set to 100% so it fits the container exactly. A CSS transform: scale(2) is then applied to the hover state of the image. The container has overflow: hidden so the image never expands beyond it’s edges.

The problem is that the transform-origin coordinates, the center of the enlargement, can only have fixed values with CSS. So JavaScript is used to get the mouse coordinates and use these instead.

The offsetX and offsetY properties give the coordinates of the mouse in pixels from the top left corner of the element to which they’re attached.

There is also clientX and clientY which get the coordinates from the top and left edges of the the client area. This means means the current window.

Florin’s code used let x = e.clientX - e.target.offsetLeft; and I’m not if there’s a good reason for this when the simpler e.offsetX seems to work exactly the same.

I did this a bit differently from Florin. Instead of using mouseenter I used the CSS :hover to enlarge the image rather than attaching it to a JS event and inline style. I also used mousemove instead of a mouseenter event.

const container = document.getElementById('img-container');
const img = document.querySelector('#img-container img');
const coordsBox = document.getElementById('coords');

container.addEventListener('mousemove', (e) => {
    let x = e.offsetX;
    let y = e.offsetY;
    let cx = e.clientX;
    let cy = e.clientY;

    img.style.transformOrigin = `${x}px ${y}px`;
    
    coordsBox.textContent = `x is ${x} and y is ${y} while client x and y are ${cx} and ${cy}`;
});