JSFiddle - React, Tailwind, and code Playground

by Danilo Metzker

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js"></script>

<div class="map-container">
  <div id="terminal" style="width: 720px; height: 380px;">
    <div id="floor" style="top: 0px; left: 0px; position: relative;" class="ui-draggable ui-draggable-handle">
    <div class="svg" id="svg-container">
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:amcharts="http://amcharts.com/ammap" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="720" height="380" viewBox="0 0 720 380" xml:space="preserve" class="editor">
	<defs>

		<amcharts:ammap projection="mercator" leftlongitude="-74.008595" toplatitude="5.275696" rightlongitude="-34.789914" bottomlatitude="-33.743888"></amcharts:ammap>

		<!-- All areas are listed in the line below. You can use this list in your script. -->
		<!--{id:"BR-AC"},{id:"BR-AL"},{id:"BR-AM"},{id:"BR-AP"},{id:"BR-BA"},{id:"BR-CE"},{id:"BR-DF"},{id:"BR-ES"},{id:"BR-GO"},{id:"BR-MA"},{id:"BR-MG"},{id:"BR-MS"},{id:"BR-MT"},{id:"BR-PA"},{id:"BR-PB"},{id:"BR-PE"},{id:"BR-PI"},{id:"BR-PR"},{id:"BR-RJ"},{id:"BR-RN"},{id:"BR-RO"},{id:"BR-RR"},{id:"BR-RS"},{id:"BR-SC"},{id:"BR-SE"},{id:"BR-SP"},{id:"BR-TO"}-->

	</defs>
	<g>
		<path id="BR-AC" title="Acre" class="land"...

CSS

.map-container {
    position: relative;
    background-color: white;
    min-height: 200px;
    margin: 0 auto;
    padding: 30px;
    cursor: move;
    overflow: hidden;
}

#terminal{
  overflow: hidden;
  border: 1px solid #000;
}

.controls {
    position: absolute;
    bottom: 40px;
    left: 40px;
    z-index: 1;
}

.controls a {
    display: table;
    width: 28px;
    height: 28px;
    background-color: #fff;
    text-align: center;
    font-size: 20px;
    font-weight: 900;
    line-height: 1.2;
    margin: 5px;
    vertical-align: middle;
    color: #000;
    text-decoration: none;
    border-radius: 50%;
    border: 1px solid #000;
}

.map{
    width: 100%;
    height: 100%;
    top: 0;
    left: 0
}

.svg {
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
}

.svg svg {
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    -webkit-transition: 0.2s all linear;
}
#floor {
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
}

.svg svg path[data-text]{
  cursor: pointer;
}

.pin{
  width: 220px;
  height: 100px;
  background: #fff;
  border: 2px solid #000;
  display: none;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  position: fixed;
}

.pin.active{
  display: flex;
}

svg path:hover{
  fill: rgba(0,0,0,0.3);
  cursor: pointer;
}

#terminal .area{
  display: flex;
  align-items: center;
  justify-content: center;
  color: #000;
  font-weight: bold;
  position: absolute;
  background: red;
}

.edit-layer{
  position: fixed;
  background-color: rgba(0,0,0,0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 16px;
  display: none;
}

.edit-layer input{
  background: transparent;
  border: 0;
  color: #fff;
  text-align: center;
  background: #000;
  outline: none;
}

.edit-layer input::placeholder{
  color: rgba(255,255,255,0.7);
}

.edit-layer a.save{
  display: block;
  padding: 8px 16px;
  background-color: #18864B;
  color: #fff;
 ...

JavaScript

var zoom = 1;

$('#floor').draggable({
	cursor: "move",
	drag: function(event, ui) {
  $(".pin").removeClass("active");
		var topPosition = ui.position.top,
			leftPosition = ui.position.left,
			maxWidth = $('#terminal').width() - $('.svg').width(),
			maxHeight = $('#terminal').height() - $('.svg').height();

		if (leftPosition <= maxWidth) {
			ui.position.left = maxWidth;
		} else if (leftPosition >= 0) {
			ui.position.left = 0;
		}

		if (topPosition <= maxHeight) {
			ui.position.top = maxHeight;
		} else if (topPosition >= 0) {
			ui.position.top = 0;
		}

		$('.office').removeClass('show');
	}
});

$('.controls a').on('click', function(evt) {
	evt.stopImmediatePropagation();
  $(".pin").removeClass("active");

	var containerWidth = $('#terminal').width(),
		containerHeight = $('#terminal').height(),
		mapWidth = $('#floor').width(),
		mapHeight = $('#floor').height(),
		mapTop = $('#floor').position().top,
		mapLeft = $('#floor').position().left,
		mapRight = mapLeft + mapWidth,
		mapBottom = mapTop + mapHeight,
		topCenter = mapTop - (containerHeight / 2),
		rightCenter = (containerWidth / 2) - mapRight,
		bottomCenter = (containerHeight / 2) - mapBottom,
		leftCenter = mapLeft - (containerWidth / 2),
		zoomWidth,
		zoomHeight,
		zoomTop,
		zoomLeft;

	if ($(this).hasClass('zoom-in') && zoom < 6) {
		topPos = containerHeight / 2 + topCenter * 1.4;
		leftPos = containerWidth / 2 + leftCenter * 1.4;

		$('#floor').css({
			'width': mapWidth * 1.4,
			'height': mapHeight * 1.4,
			'top': topPos,
			'left': leftPos
		});
		zoom++;
	} else if ($(this).hasClass('zoom-out') && zoom > 1) {
		topPos = containerHeight / 2 + topCenter / 1.4;

		if (topPos > 0) {
			topPos = 0;
		}


		bottomPos = topPos + mapHeight / 1.4;

		if (bottomPos < containerHeight) {
			topPos = topPos + containerHeight - bottomPos;
		}


		leftPos = containerWidth / 2 + leftCenter / 1.4;

		if (leftPos > 0) {
			leftPos = 0;
		}


		rightPos = leftPos + mapWidth / 1.4;

		if (rightPos <...