JSFiddle - React, Tailwind, and code Playground

HTML

<table>
    <tr>
      <td style="min-width: 120px;">
        <div style="display: none">
        <label for="atomSize">Atom size</label>
        <input type="text" id="atomSize" />

        <label for="numberOfAtoms">Number of atoms</label>
        <input type="text" id="numberOfAtoms" />

        <label for="startVelocity" title="module, direction">Start velocity</label>
        <input type="text" id="startVelocity" />

        <label for="gravity">Gravity</label>
        <input type="text" id="gravity" />

        <label for="picoSecondsPerSecond" title="Big time factor can cause incorrect collision processing">Time factor</label>
        <input type="text" id="picoSecondsPerSecond" />

        <label for="atomMassFrom" title="from, to">Atom mass</label>
        <input type="text" id="atomMassFrom" />
        </div>

        <button id="startButton" data-switch-title="Stop" style="min-width: 60px;">Start</button>
      </td>
      <td>
        <canvas id="canvas" width="800" height="400"></canvas>
      </td>
    </tr>
    <tr>
      <td style="padding: 0.67em">Ср. кв. скорость<br>Количество</td>
      <td>
        <table id="avgTemp">
          <tr>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
            <td>&nbsp;<br></td>
          </tr>
        </table>
      </td>
    </tr>
  </table>

CSS

body { font-size: 12px; }
    table { width: min-content; }
    table td { vertical-align: top; padding: 0.33em; }

    input { margin-bottom: 0.8em; }
    #canvas { border: 1px solid #000; }
    
    #avgTemp {
      width: 100%;
      border: 1px solid #000;
      border-collapse: collapse;
      table-layout: fixed;
    }

    #avgTemp td { border: 1px solid #000; }

JavaScript

(function () {
      const $ = (selector, parent) => (parent ?? document).querySelector(selector)

      // units, just for clarity
      const PM = 1
      const PM_PER_PSEC = 1
      const KG = 1
      const RADIAN = 1

      const ONE_ATOM_MASS = 1.66e-27*KG

      // for simplicity and performance we assume that all atoms have the same radius
      const ATOM_DIAMETER = 300*PM


      const settings = {
        atomSize: 6,
        numberOfAtoms: 600,
        startVelocity: 493*PM_PER_PSEC,
        startDirection: 0,
        gravity: 0,
        atomMassFrom: 1,
        atomMassTo: 1,
        picoSecondsPerSecond: 20,
      }
      window.settings = settings


      class App {
        canvas
        ctx
        canvasWidth
        canvasHeight

        /** @var boolean */
        running

        startTime

        /** @var {World} */
        world
        renderScale

        mouseMoveEvent

        run() {
          this.canvas = $('#canvas')
          this.ctx = this.canvas.getContext('2d')
          this.canvasWidth = this.canvas.width
          this.canvasHeight = this.canvas.height

          this.ctx.lineWidth = 1
          this.ctx.fillStyle = '#fff'

          this.running = false

          const search = new URLSearchParams(location.search)
          const dataStr = search.get('d') ?? undefined
          this.initWorld(dataStr)

          this.initHandlers()

          requestAnimationFrame((time) => {
            this.startTime = time
            requestAnimationFrame(this.step.bind(this))
          })

          this.calcTable();
        }

        calcTable() {
          const avgTempEl = $('#avgTemp')
          const tdCnt = [...document.querySelectorAll('#avgTemp td')].length
          const avgTempArr = [];
          for (let i = 0; i < tdCnt; i++) avgTempArr.push({sum: 0, cnt: 0})

          for (let atom of this.world.atomList) {
            if (atom.type === 2)...