var circle = {x: 50, y: 50, radius: 50, contour: []};

var box = {x: 20, y: 20, width: 300, height: 300};

for(var a = 0; a < Math.PI * 2; a += Math.PI / circle.radius){
  circle.contour.push({
    _x: Math.sin(a) * circle.radius, _y: Math.cos(a) * circle.radius
  });
}

var canvas = document.body.appendChild(document.createElement("canvas")).getContext("2d");
canvas.canvas.width = 400;
canvas.canvas.height = 400;

var loop = function(){
  canvas.canvas.width = canvas.canvas.width;
  canvas.save();
  canvas.fillRect(box.x, box.y, box.width, box.height);
  canvas.globalCompositeOperation = "destination-out";
  canvas.fillRect(box.x + 20, box.y + 20, box.width - 40, box.height - 40);
  canvas.restore();

  var circleCanvas = document.createElement("canvas").getContext("2d");
  circleCanvas.canvas.width = canvas.canvas.width;
  circleCanvas.canvas.height = canvas.canvas.height;

  circleCanvas.save();
  circleCanvas.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
  circleCanvas.fillStyle = "#aaa";
  circleCanvas.fill();
  circleCanvas.globalCompositeOperation = "destination-in";
  circleCanvas.fillRect(box.x + 20, box.y + 20, box.width - 40, box.height - 40);
  circleCanvas.restore();
  canvas.drawImage(circleCanvas.canvas, 0, 0);

  if(circle._x < box.x + 20){
    circle._x = box.x + 20;
  }
  if(circle._y < box.y + 20){
    circle._y = box.y + 20;
  }
  if(circle._x > box.x + box.width - 20){
    circle._x = box.x + box.width - 20;
  }
  if(circle._y > box.y + box.height - 20){
    circle._y = box.y + box.height - 20;
  }

  circle.contour.forEach(function(p){
    p.x = p._x;
    p.y = p._y;

    if(circle.x + p.x < box.x + 20){
      p.x = box.x + 20 - circle.x;
    }
    if(circle.y + p.y < box.y + 20){
      p.y = box.y + 20 - circle.y;
    }
    if(circle.x + p.x > box.x + box.width - 20){
      p.x = box.x + box.width - 20 - circle.x;
    }
    if(circle.y + p.y > box.y + box.height - 20){
      p.y = box.y + box.height - 20 - circle.y;
    }
    canvas.strokeStyle = "green";
    canvas.lineWidth = 3;
    canvas.lineTo(p.x + circle.x, p.y + circle.y);
  });
  canvas.stroke();

  circle.x = circle._x;
  circle.y = circle._y;
  requestAnimationFrame(loop);
};
loop();

document.onmousemove = function(event){
  circle._x = event.layerX;
  circle._y = event.layerY;
};
