<div class="description">
  <h1>Draggable Image Hotspots</h1>
  <p>Click on the image to create hotspots. Drag to change positions.</p>
</div>
<div class="outfit"><img src="https://unsplash.it/1280/800" /></div>
<div class="output">Dot Positions goes here.</div>
body {
  background: black;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
  min-height: 100vh;
  padding: 10px 0 30px;
}

.description {
  margin-bottom: 20px;
  color: #fff;
}

.output {
  padding: 10px 0;
  color: #fff;
  background: #525252;
  width: 100%;
  max-width: 420px;
}

.outfit {
  line-height: 0;
  position: relative;
  width: auto;
  height: auto;
  background: gray;
  display: inline-block;
  max-width: 420px;
  
  img {
    width: 100%;
    height: auto;
    cursor: pointer;
  }
}

.dot {
  position: absolute;
  width: 24px;
  height: 24px;
  background: rgba(white, 1);
  border-radius: 50%;
  overflow: hidden;
  cursor: pointer;
  box-shadow: 0 0 3px 0 rgba(0, 0, 0, .2);
  line-height: 24px;
  font-size: 12px;
  font-weight: bold;
  transition: box-shadow .214s ease-in-out, transform .214s ease-in-out, background .214s ease-in-out;
  
  &.ui-draggable-dragging {
    box-shadow: 0 0 25px 0 rgba(0, 0, 0, .5);
    transform: scale3d(1.2, 1.2, 1.2);
    background: rgba(white, .7);
  }
}
View Compiled
$( ".outfit img" ).click(function(e) {
  var dot_count = $( ".dot" ).length;
  
  var top_offset = $(this).offset().top - $(window).scrollTop();
  var left_offset = $(this).offset().left - $(window).scrollLeft();

  var top_px = Math.round( (e.clientY - top_offset - 12) );
  var left_px = Math.round( (e.clientX - left_offset - 12) );
  
  var top_perc = top_px / $(this).height() * 100;
  var left_perc = left_px / $(this).width() * 100;
  
  // alert('Top: ' + top_px + 'px = ' + top_perc + '%');
  // alert('Left: ' + left_px + 'px = ' + left_perc + '%');
  
  var dot = '<div class="dot" style="top: ' + top_perc + '%; left: ' + left_perc + '%;">' + (dot_count + 1) + '</div>';
  
  $(dot).hide().appendTo($(this).parent()).fadeIn(350);;
  
  $( ".dot" ).draggable({
    containment: ".outfit",
    stop: function( event, ui ) {
      var new_left_perc = parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%";
      var new_top_perc = parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%";
      var output = 'Top: ' + parseInt(new_top_perc) + '%, Left: ' + parseInt(new_left_perc) + '%';
      
      $(this).css("left", parseInt($(this).css("left")) / ($(".outfit").width() / 100) + "%");
      $(this).css("top", parseInt($(this).css("top")) / ($(".outfit").height() / 100) + "%");
      
      $('.output').html('CSS Position: ' + output);
    }
  });
  
  console.log("Left: " + left_perc + "%; Top: " + top_perc + '%;');
  $('.output').html("CSS Position: Left: " + parseInt(left_perc) + "%; Top: " + parseInt(top_perc) + '%;');
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js