JSFiddle - React, Tailwind, and code Playground

by raxxla

HTML

<canvas id="canvas" width="800" height="600" style='border:1px solid;'></canvas>

JavaScript

var context = document.getElementById('canvas').getContext('2d');
var ball = [], n=600, v=20, fps=60;
var k, m, dt=1, mfps=fps, ms=1000/fps, sms=ms;

for (var i=0; i<n; i++){
  ball[i] = {};
  ball[i].r = 2;
  ball[i].x = Math.random()*(canvas.width-2*ball[i].r)+ball[i].r;
  ball[i].y = Math.random()*(canvas.height-2*ball[i].r)+ball[i].r;
  ball[i].vx = v*Math.random()*Math.pow(-1, Math.round(Math.random()+1));
  ball[i].vy = Math.sqrt(v*v-ball[i].vx*ball[i].vx)*Math.pow(-1, Math.round(Math.random()+1));
  ball[i].m = ball[i].r*ball[i].r;
  ball[i].a = 1;
}

ball[n] = {};
ball[n].r = 80;
ball[n].x = 320;
ball[n].y = 300;
ball[n].vx = 0
ball[n].vy = 0;
ball[n].m = ball[n].r*ball[n].r;
ball[n].a = 0.6;

ball[n+1] = {};
ball[n+1].r = 60;
ball[n+1].x = 480;
ball[n+1].y = 250;
ball[n+1].vx = 0;
ball[n+1].vy = 0;
ball[n+1].m = ball[n+1].r*ball[n+1].r;
ball[n+1].a = 0.8;

setInterval(draw, sms);

function draw() {
  var date = new Date();
  findCollisions();
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.font = "12px Arial";
  for (var i=0; i<ball.length; i++) {
    motion(i, dt);
    context.beginPath();
    context.arc(ball[i].x, ball[i].y, ball[i].r, 0, 2*Math.PI);
    context.stroke();
  }
  dt=1;
  context.fillText((Math.sqrt(Math.pow(ball[n].x-ball[n+1].x, 2)+Math.pow(ball[n].y-ball[n+1].y, 2))-ball[n].r-ball[n+1].r).toFixed(2), ball[n].x, ball[n].y);
  var mms = new Date() - date;
  sms=ms-mms;
  if (sms<0) sms=0;
  fps=Math.round(1000/(sms + mms));
  if (fps<mfps) mfps=fps;
  context.fillText(fps + " fps", 4, 13);
  context.fillText(mfps + " min", 4, 26);
}

function findCollisions() {
  var t, tc, q, w;
  if (k>m) q=m, w=k;
  else q=k, w=m;
  for (var i=0; i<ball.length-1; i++) {
    for (var j=n; j<ball.length; j++) {
      if (i<j && (i!=q || j!=w)) {
        var vxij=ball[i].vx-ball[j].vx;
        var vyij=ball[i].vy-ball[j].vy;
        var xij=ball[i].x-ball[j].x;
        var yij=ball[i].y-ball[j].y;
        var a=vxij*vxij+vyij*vyij;
   ...