JSFiddle - React, Tailwind, and code Playground

HTML

<canvas width="500px" height ="500px"></canvas>

JavaScript

console.log('start');
var ctx = document.querySelector('canvas').getContext('2d');
var lastTime = null;
var timeStep;

var obj1 = {};
var obj2 = {};

obj1.x = 20;
obj1.y = 270;
obj1.radius = 20;
obj1.velocity = {
	x: 50,
  y: 0
};
obj1.mass = 100;
obj1.forceRadius = 150;
obj1.width = 2 * obj1.forceRadius;
obj1.height = 2 * obj1.forceRadius;

obj2.x = 250;
obj2.y = 170;
obj2.radius = 50;
obj2.velocity = {
	x: 0,
  y: 0
};
obj2.forceRadius = 150;
obj2.width = 2 * obj2.forceRadius;
obj2.height = 2 * obj2.forceRadius;
obj2.fRSq = obj2.forceRadius * obj2.forceRadius;
obj2.mass = 100;

function attract(obj1, obj2)
{
  var dx = obj2.x - obj1.x;
  var dy = obj2.y - obj1.y;

  var radii = obj1.forceRadius + obj2.forceRadius;
  if ((dx < 0 ? -dx : dx) > radii)
  {
    return;
  }
  if ((dy < 0 ? -dy : dy) > radii)
  {
    return;
  }
  var distance = dx * dx + dy * dy;
  if (distance < radii * radii)
  {
    var ratio = (obj2.mass / distance)
    obj1.velocity.x += ratio * dx;
    obj1.velocity.y += ratio * dy;
  }
}

function move(obj, dt)
{
	obj.x += obj.velocity.x * dt;
  obj.y += obj.velocity.y * dt;
}

function draw(obj)
{
	ctx.beginPath();
  ctx.arc(obj.x, obj.y, obj.radius, 0, 2 * Math.PI, false);
  ctx.fill();
  if (obj.forceRadius)
  {
  	ctx.beginPath();
    ctx.arc(obj.x, obj.y, obj.forceRadius, 0, 2 * Math.PI, false);
    ctx.lineWidth = 3;
    ctx.strokeStyle = '#ff0000';
    ctx.stroke();
  }
}

function loop(time)
{
	if (lastTime !== null) {
		timeStep = time / 1000 - lastTime;
	}
	lastTime = time / 1000;
 	
  if (timeStep)
  {
  	move(obj1, timeStep);
    move(obj2, timeStep);
    attract(obj1, obj2);
    attract(obj2, obj1);
    ctx.clearRect(0, 0, 500, 500); 
  	ctx.fillStyle = '#B18247';
    draw(obj2);
    ctx.fillStyle = '#503779';
    draw(obj1);
  }
  
  window.requestAnimationFrame(loop);
}

window.requestAnimationFrame(loop);