Simple limited drag

by OPTlMUS

HTML

<div id="container">
  <div id="zombie"></div>
</div>

CSS

#container {
  position: relative;
  width: 300px;
  height: 300px;
  border: 1px solid red;
}

#zombie {
  position: absolute;
  width: 40px;
  height: 40px;
  
  background-color: #462;
  border-radius: 50%;
  box-shadow: inset 0 4px 2px #c00;
}

#zombie::before,
#zombie::after  {
  content: "";
  position: absolute;
  top: 35%;
  width: 40%;
  height: 40%;
  border-radius: 50%;
  background-color: #ddd;
}
#zombie::before {
  left: 10%;
}
#zombie::after {
  right: 10%;
}

JavaScript

const MOUSEDOWN = "touchstart" in window ? "touchstart" : "mousedown";
const MOUSEMOVE = "touchmove" in window ? "touchmove" : "mousemove";
const MOUSEUP = "touchend" in window ? "touchend" : "mouseup";

/***/
let cont = document.querySelector("#container");
let zombie = document.querySelector("#zombie");

const X_LIMIT = cont.clientWidth - zombie.offsetWidth;
const Y_LIMIT = cont.clientHeight - zombie.offsetHeight;

/***/
let dragging = false;
let dx = 0, dy = 0;

zombie.addEventListener(MOUSEDOWN, function(e) {
  let rect_zomb = zombie.getBoundingClientRect();
  let rect_cont = cont.getBoundingClientRect();
  
  dx = e.pageX - rect_zomb.left + rect_cont.left;
  dy = e.pageY - rect_zomb.top + rect_cont.top;
  
  dragging = true;
});

document.addEventListener(MOUSEUP, () => dragging = false);

document.addEventListener(MOUSEMOVE, function(e) {
  if (!dragging) return;
  
  zombie.style.left = Math.max(0, Math.min(X_LIMIT, e.pageX - dx)) + "px";
  zombie.style.top = Math.max(0, Math.min(Y_LIMIT, e.pageY - dy)) + "px";
});