JSFiddle - React, Tailwind, and code Playground

by Alexey Ukolov

HTML

<div id="map"></div>

<button type="button" id="zoom-in">+</button>
<button type="button" id="zoom-out">-</button>

CSS

#map {
  position: relative;
  width: 3429px;
  height: 1933px;
  background: url('https://upload.wikimedia.org/wikipedia/commons/f/f6/%D0%9A%D0%BE%D0%BD%D1%82%D1%83%D1%80%D0%BD%D0%B0%D1%8F_%D0%BA%D0%B0%D1%80%D1%82%D0%B0_%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D0%B8_%D1%81_%D1%80%D0%B5%D0%B3%D0%B8%D0%BE%D0%BD%D0%B0%D0%BC%D0%B8_%D0%A1%D0%B1%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_2009.jpg') top left no-repeat;
}

#zoom-in, #zoom-out {
  position: fixed;
  top: 0;
  left: 0;
  width: 30px;
  height: 30px;
}

#zoom-out {
  left: 40px;
}

.b {
  background: green;
  width: 20px;
  height: 20px;
  border-radius: 10px;
  transform: translatex(-50%) translateY(-50%);
}

JavaScript

const $map = document.querySelector('#map');

let zoom = parseFloat($map.style.zoom) || 1.0;

$map.addEventListener('click', (event) => {
	const x = event.offsetX;
  const y = event.offsetY;

	const top = y / zoom; // TODO
  const left = x / zoom; // TODO

	console.log({zoom, x, y});

  const $b = document.createElement('div');
  $b.classList.add('b');
  $b.style.position = 'absolute';
  $b.style.top = top + 'px';
  $b.style.left = left + 'px';
  $map.appendChild($b);
});

document.querySelector('#zoom-in').addEventListener('click', (event) => {
	event.stopPropagation();
  
  zoom += 0.1;
  
  $map.style.zoom = zoom;
});

document.querySelector('#zoom-out').addEventListener('click', (event) => {
	event.stopPropagation();
  
  zoom -= 0.1;
  
  $map.style.zoom = zoom;
});