JSFiddle - React, Tailwind, and code Playground

HTML

<canvas id="gridCanvas" width="1000" height="1000"></canvas>

CSS

body {
   background-color: #000000;
   margin: 0px;
 }
 
 canvas,
 img {
   image-rendering: optimizeSpeed;
   image-rendering: -moz-crisp-edges;
   image-rendering: -webkit-optimize-contrast;
   image-rendering: optimize-contrast;
   -ms-interpolation-mode: nearest-neighbor;
 }

JavaScript

"use strict"

 var ctx = document.getElementById('gridCanvas').getContext('2d');
 ctx.canvas.width = window.innerWidth;
 ctx.canvas.height = window.innerHeight;
 var centerX = ctx.canvas.width / 2;
 var centerY = ctx.canvas.height / 2;
 var pixels;
 var dotCount = 3000;
 var friction = 1;
 var kick = 0;
 var halfKick = kick / 2;
 var pixel = ctx.createImageData(1, 1);
 pixel.data[0] = 255;
 pixel.data[1] = 255;
 pixel.data[2] = 255;
 pixel.data[3] = 255;

 function bonk(dots, i) {
   var n = i * 4;
   // Bonk
   if (dots[n + 0] > ctx.canvas.width) {
     dots[n + 0] = ctx.canvas.width;
     dots[n + 2] = 0;
     dots[n + 3] = 0;
   }
   if (dots[n + 0] < 0) {
     dots[n + 0] = 0;
     dots[n + 2] = 0;
     dots[n + 3] = 0;
   }
   if (dots[n + 1] > ctx.canvas.height) {
     dots[n + 1] = ctx.canvas.height;
     dots[n + 2] = 0;
     dots[n + 3] = 0;
   }
   if (dots[n + 1] < 0) {
     dots[n + 1] = 0;
     dots[n + 2] = 0;
     dots[n + 3] = 0;
   }
 };

 function doMovement(dots, i) {
   var n = i * 4;
   dots[n + 0] += dots[n + 2];
   dots[n + 1] += dots[n + 3];

   dots[n + 2] /= friction;
   dots[n + 3] /= friction;

   bonk(dots, i);
 }

 function init() {
   var vectors = new Float64Array(dotCount * 4);
   for (var i = 0; i < dotCount; i++) {
     var n = i * 4;
     // dots[i + 0] = dots.x
     // dots[i + 1] = dots.y
     // dots[i + 2] = dots.vector.x
     // dots[i + 3] = dots.vector.y
     vectors[n + 0] = Math.floor(Math.random() * ctx.canvas.width);
     vectors[n + 1] = Math.floor(Math.random() * ctx.canvas.height);
     vectors[n + 2] = Math.random() * kick - halfKick;
     vectors[n + 3] = Math.random() * kick - halfKick
   }
   DrawGrid(vectors);
 }

 function update(dots) {
   for (var i = dotCount; i > 0; i--) {
     for (var j = i - 1; j > 0; j--) {
       var ni = i * 4;
       var nj = j * 4;
       var dx = dots[nj + 0] - dots[ni + 0];
       var dy = dots[nj + 1] - dots[ni + 1];
       var distance = Math.sqrt((dx * dx) + (dy * dy));
    ...