JSFiddle - React, Tailwind, and code Playground
HTML
<canvas id="canvas" style="border: 1px solid" width="1000" height="600"></canvas>
JavaScript
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let raf;
var G = 1; //гравитационная постоянная
var balls = [];
for (var i = 0; i < 4; i ++) {
for (var j = 0; j < 4; j ++) {
balls.push({
x: i * 100 + 350,
y: j * 100 + 100,
f: 0,
a: 0,
radius: 5,
color: "rgb("+Math.pow(2, i*2)+","+Math.pow(2, j*2)+","+0+")",
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
},
recalc(fn, an) {
xn = this.f * Math.cos(this.a) + fn * Math.cos(an);
yn = this.f * Math.sin(this.a) + fn * Math.sin(an);
this.f = Math.sqrt(xn * xn + yn * yn);
this.a = Math.atan2(yn, xn);
},
});
}
}
function dist(el1, el2) {
return Math.sqrt(Math.pow(el1.x - el2.x, 2) + Math.pow(el1.y - el2.y, 2));
}
function angle(el1, el2) {
return Math.PI + Math.atan2(el1.y - el2.y, el1.x - el2.x);
}
function draw() {
ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (const ball of balls) {
for (const ball2 of balls) {
if (ball != ball2) {
var d = dist(ball, ball2);
if (d > 100) {
var f = G / d;
var a = angle(ball, ball2);
ball.recalc(f, a);
}
}
}
}
for (const ball of balls) {
ball.x += ball.f * Math.cos(ball.a);
ball.y += ball.f * Math.sin(ball.a);
ball.draw();
}
setTimeout(function() {
raf = window.requestAnimationFrame(draw);
}, 10);
}
raf = window.requestAnimationFrame(draw);
ball.draw();