<main>
  <div class="body">
    <div id="area" class="area"></div>
    <p id="circle" class="circle"></p>
  </div>
  <form id="form_area" class="area-form">
    <fieldset>
      <legend>edit area</legend>
      <div class="area-form__body">
        <label>
          <strong>width</strong>
          <input type="number" name="width" value="50" max="100">
          <em>vw</em>
        </label>
        <label>
          <strong>height</strong>
          <input type="number" name="height" value="50" max="75">
          <em>vh</em>
        </label>
      </div>
    </fieldset>
    <nav>
      <button type="submit">Set area size</button>
    </nav>
  </form>
</main>
body {
  margin: 0;
  overflow: hidden;
  font-family: 'Helvetica Neue', 'Arial', sans-serif;
}
main {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  width: 100vw;
  min-height: 100vh;
}

.body {
  position: relative;
}

.area {
  display: block;
  width: var(--width, 50vw);
  height: var(--height, 50vh);
  box-sizing: border-box;
  background: blue;
  opacity: .25;
}

.circle {
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  z-index: 2;
  box-sizing: border-box;
  transform: translate(var(--x, 0px), var(--y, 0px));
  pointer-events: none;
}
.circle:before {
  content: '';
  display: block;
  opacity: .5;
  background: var(--color, red);
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: var(--w, 0px);
  height: var(--h, 0px);
  box-sizing: border-box;
  border-radius: 50%;
}

.area-form {
  margin: 24px 0 0;
  user-select: none;
}
.area-form fieldset {
  margin: 0;
  padding: 0;
  border: none;
}
.area-form fieldset legend {
  font-size: 0;
}
.area-form fieldset > div {
  display: flex;
  align-items: center;
}
.area-form label {
  display: flex;
  align-items: center;
}
.area-form label:nth-child(n+2) {
  margin-left: 16px;
}
.area-form label strong {
  display: block;
  margin-right: 8px;
  font-size: 16px;
}
.area-form label input {
  width: 80px;
  height: 32px;
  font-size: 16px;
}
.area-form label em {
  display: block;
  margin-left: 4px;
  font-style: normal;
  font-size: 14px;
}
.area-form nav {
  margin: 16px 0 0;
  text-align: center;
}
.area-form nav button {
  display: block;
  margin: 0 auto;
  font-size: 16px;
  font-weight: 600;
  width: 160px;
  height: 36px;
}
View Compiled
const $area = document.getElementById('area');
const $circle = document.getElementById('circle');
const $form = document.getElementById('form_area');
let downArea = false;
let distanceMax;

// 대각선 길이 구하기
function computeDistance(x1, y1, x2, y2)
{
  const distanceX = x1 - x2;
  const distanceY = y1 - y2;
  return Math.sqrt(Math.abs(distanceX * distanceX) + Math.abs(distanceY * distanceY));
}

// set proxy
let circle = new Proxy({
  x: 0,
  y: 0,
  w: 0,
  h: 0,
}, {
  set: function(obj, prop, value)
  {
    if (typeof obj[prop] === 'undefined') throw new TypeError('error value');
    obj[prop] = value;
    switch (prop)
    {
      case 'x':
        $circle.style.setProperty('--x', value + 'px');
        break;
      case 'y':
        $circle.style.setProperty('--y', value + 'px');
        break;
      case 'w':
        $circle.style.setProperty('--w', value + 'px');
        break;
      case 'h':
        $circle.style.setProperty('--h', value + 'px');
        break;
      case 'color':
        $circle.style.setProperty('--color', value);
        break;
    }
  },
});
let area = new Proxy({
  width: 50,
  height: 50,
}, {
  set: function(obj, prop, value)
  {
    if (obj[prop] === value) return;
    obj[prop] = value;
    circle.x = circle.y = circle.w = circle.h = 0;
    switch(prop)
    {
      case 'width':
        $area.style.setProperty('--width', value + 'vw');
        break;
      case 'height':
        $area.style.setProperty('--height', value + 'vh');
        break;
    }
  },
});

// mouse events from area
function onStartArea(e)
{
  if (!e.target.closest('#area')) return;
  const areaBounding = $area.getBoundingClientRect();
  downArea = true;
  circle.x = e.pageX - Math.round(areaBounding.x);
  circle.y  = e.pageY - Math.round(areaBounding.y);
  circle.w = 0;
  circle.h = 0;
  distanceMax = Math.max.apply(null, [
    Math.round(computeDistance(e.pageX, e.pageY, areaBounding.x, areaBounding.y)),
    Math.round(computeDistance(e.pageX, e.pageY, areaBounding.x + areaBounding.width, areaBounding.y)),
    Math.round(computeDistance(e.pageX, e.pageY, areaBounding.x, areaBounding.y + areaBounding.height)),
    Math.round(computeDistance(e.pageX, e.pageY, areaBounding.x + areaBounding.width, areaBounding.y + areaBounding.height)),
  ]);
}
function onStartMove(e)
{
  if (!downArea) return;
  const areaBounding = $area.getBoundingClientRect();
  let pageX = e.pageX - Math.round(areaBounding.x);
  let pageY = e.pageY - Math.round(areaBounding.y);
  let distance = Math.round(computeDistance(pageX, pageY, circle.x, circle.y));
  circle.w = circle.h = ((distanceMax > distance) ? distance : distanceMax) * 2;
}
function onStartEnd(e)
{
  if (!downArea) return;
  downArea = false;
}

// submit
function onSubmitArea(e)
{
  e.preventDefault();
  const $width = this.querySelector('[name=width]');
  const $height = this.querySelector('[name=height]');
  area.width = Number($width.value);
  area.height = Number($height.value);
}

// set events
window.addEventListener('mousedown', onStartArea);
window.addEventListener('mousemove', onStartMove);
window.addEventListener('mouseup', onStartEnd);
$form.addEventListener('submit', onSubmitArea);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.