JSFiddle - React, Tailwind, and code Playground

HTML

<div class="container">
  <div class="block"></div>
  <div class="block-container bc1"></div>
</div>
<div class="chaser"></div>
<div class="mouser"></div>
<div class="edger"></div>
<div id="output">
</div>
</div>

CSS

.container {
  width: 100px;
  height: 150px;
  padding: 20px;
  margin: 20px auto;
  position: relative;
}

.block-container {
  width: 40px;
  height: 40px;
  border: 1px solid gray;
}

.block {
  position: absolute;
  top: 20px;
  left: 50%;
  margin-left: -20px;
  width: 40px;
  height: 40px;
  border: 1px solid black;
  background-color: blue;
}

.bc1 {
  margin: 0 auto;
}

.chaser {
  position: absolute;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  margin-top: -2px;
  background-color: red;
}

.mouser {
  position: absolute;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  margin-top: -2px;
  background-color: blue;
}

.edger {
  position: absolute;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  margin-top: -5px;
  background-color: green;
}

JavaScript

const $ = selector => document.querySelectorAll(selector)[0];

const chaser = $('.chaser');
const mouser = $('.mouser');
const edger = $('.edger');
const block = $('.block');

window.addEventListener('mousemove', (e) => {
  const mouse = {
    x: e.pageX *1000,
    y: e.pageY * 1000,
  };

  const target = document.body.getBoundingClientRect();
  const targetCenter = {
    x: Math.floor(target.left + (target.width / 2)),
    y: Math.floor(target.top + (target.height / 2)),
  };

  const angle = Math.atan2(mouse.y - targetCenter.y, mouse.x - targetCenter.x);

  const cosAngle = Math.abs(Math.cos(angle));
  const sinAngle = Math.abs(Math.sin(angle));

  const magnitude = target.width / 2 * sinAngle <= target.height / 2 * cosAngle ?
    target.width / 2 / cosAngle :
    target.height / 2 / sinAngle;

  const targetEdge = {
    x: targetCenter.x + Math.cos(angle) * magnitude,
    y: targetCenter.y + Math.sin(angle) * magnitude,
  };

  const viewport = {
    width: window.innerWidth,
    height: window.innerHeight,
  };

  const viewPortEdge = {};
  
  const x0 = targetCenter.x; 
  const y0 = targetCenter.y; 
  
  const x2 = viewport.width;
  const y2 = viewport.height;
  
  const vx = mouse.x - x0;
  const vy = mouse.y - y0;

  const ex = vx > 0 ? x2 : 0;
  const ey = vy > 0 ? y2 : 0;

  if (!vx) {
    viewPortEdge.x = 0;
    viewPortEdge.y = ey;
  } else if (!vy) {
    viewPortEdge.x = ex;
    viewPortEdge.y = 0;
  } else {
    const tx = (ex - x0) / vx;
    const ty = (ey - y0) / vy;

    viewPortEdge.x = tx <= ty ? ex : x0 + ty * vx;
    viewPortEdge.y = tx <= ty ? y0 + tx * vy : ey;
  }

  chaser.style.left = `${targetEdge.x}px`;
  chaser.style.top = `${targetEdge.y}px`;
  mouser.style.left = `${mouse.x}px`;
  mouser.style.top = `${mouse.y}px`;
  edger.style.left = `${viewPortEdge.x}px`;
  edger.style.top = `${viewPortEdge.y}px`;
	document.getElementById('output').innerHTML = `${viewPortEdge.x}x${viewPortEdge.y}`;
  console.log(angle)
});