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> <br></td>
<td> <br></td>
<td> <br></td>
<td> <br></td>
<td> <br></td>
<td> <br></td>
<td> <br></td>
<td> <br></td>
<td> <br></td>
<td> <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)...