{
const w = width;
const h = 240;
const ctx = DOM.context2d(w, h);
const state = {
minGravR: 20,
a: { x: w * 0.5, vx: 0, m: 100, r: 30, color: "yellow" },
b: { x: w * 0.75, vx: 0, m: 1, r: 10, color: "cornflowerblue" }
};
function draw() {
const y = h / 2;
const { a, b } = state;
const r = 10;
ctx.save();
ctx.fillStyle = "#333";
ctx.fillRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(a.x, y, a.r, 0, 2 * Math.PI);
ctx.fillStyle = a.color;
ctx.fill();
ctx.beginPath();
ctx.arc(b.x, y, b.r, 0, 2 * Math.PI);
ctx.fillStyle = b.color;
ctx.fill();
ctx.restore();
}
function getGravityAcc(me, other) {
const G = 0.01;
const r = other.x - me.x;
if (Math.abs(r) < state.minGravR) return 0;
const a = (G * other.m) / r ** 2;
return a * Math.sign(r);
}
const dt = 1000 / 60;
function update() {
const steps = 40;
const _dt = dt / steps;
for (let i = 0; i < steps; i++) {
state.a.vx += getGravityAcc(state.a, state.b) * _dt;
state.b.vx += getGravityAcc(state.b, state.a) * _dt;
state.a.x += state.a.vx * _dt;
state.b.x += state.b.vx * _dt;
}
draw();
}
const interval = setInterval(update, dt);
invalidation.then(() => clearInterval(interval));
return ctx.canvas;
}