JSFiddle - React, Tailwind, and code Playground

HTML

<div id="canvas"></div>
<div id="pointer"></div>
<div id="intructions">The black dot's movement should be constrained to the gray circle</div>

CSS

html, body {
  height: 100%;
}

#canvas {
  background: #eee;
  position: absolute;
  height: 300px;
  width: 300px;
  top: 50%;
  left: 50%;
  margin-top: -150px;
  margin-left: -150px;
  -webkit-border-radius: 300px;
  -moz-border-radius: 300px;
  border-radius: 300px;
  border: dashed #ccc 1px;
}

#pointer {
  position: absolute;
  background: #000;
  width: 20px;
  height: 20px;
  -webkit-border-radius: 20px;
  -moz-border-radius: 20px;
  border-radius: 20px;
  margin-top: -10px;
  margin-left: -10px;
  top: 50%;
  left: 50%;
}

#intructions {
  position: absolute;
  bottom: 0;
  text-align: center;
  padding-bottom: 10px;
  width: 100%;
}

JavaScript

var pointerEl = document.getElementById("pointer");
var canvasEl = document.getElementById("canvas");
var canvas = {
    width: canvasEl.offsetWidth,
    height: canvasEl.offsetHeight,
    top: canvasEl.offsetTop,
    left: canvasEl.offsetLeft
}

    
window.onmousemove = function(e) {
  pointerEl.style.left = limit(e.x, true);
  pointerEl.style.top = limit(e.y, false);
}
    
function limit(pixels, isX) {
    //this is where the magic should happen
    var value;
    if (!isX) { 
      value = (pixels < canvas.top)
      ? canvas.top
      : Math.min(pixels, canvas.top + canvas.height)
    }
    else {
      value = (pixels < canvas.left)
      ? canvas.left
      : Math.min(pixels, canvas.width + canvas.left)
   }
   return value + "px";
}