<div class="wrap">
  <img class="image" src="https://picsum.photos/400/400">
</div>
.wrap {
    
  width: 400px;
  height: 400px;
  overflow: hidden;
  position: relative;
  border: 1px solid black;
}

.wrap img {
  transform: translate(2px, 2px) scale(2);
}
const container = document.querySelector('.wrap');
const image = document.querySelector('.image');
const speed = 0.25;
let size = { 
  w: image.offsetWidth, 
  h: image.offsetHeight 
};
let pos = { x: 0, y: 0 };
let halfSize = { x: 0, y: 0 };
let offset = { x: 0, y: 0 };
let scale = 1;

window.addEventListener('wheel', event => {
  event.preventDefault();
  
  offset.x = event.pageX * scale - container.offsetLeft;
  offset.y = event.pageY * scale - container.offsetTop;
  
  halfSize.x = image.getBoundingClientRect().width / 2
  halfSize.y = image.getBoundingClientRect().height / 2
 
  scale += -1 * Math.max(-1, Math.min(1, event.deltaY)) * speed * scale;
  const max_scale = 4;
  const min_scale = 1;
  scale = Math.max(min_scale, Math.min(max_scale, scale));

  pos.x = halfSize.x - (offset.x + ((halfSize.x - offset.x) / scale))
  pos.y = halfSize.y - (offset.y + ((halfSize.y - offset.y) / scale))

  image.style.transform = `translate(${pos.x}px,${pos.y}px) scale(${scale},${scale})`;
}, { passive: false });

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.