refactor: distribute lab-init.js into 34 engine files
lab-init.js: 4098 -> 543 lines (infrastructure + THEORY only) Each sim's _open*() + UI helpers moved to its engine file: graph.js, projectile.js, collision.js, magnetic.js, triangle.js, geometry.js, trigcircle.js, gas.js (molphys), coulomb.js, circuit.js, reactions.js (chemistry), newton.js (dynamics), chemsandbox.js, celldivision.js, photosynthesis.js, angrybirds.js, quadratic.js, normaldist.js, graphtransform.js, pendulum.js, equilibrium.js, thinlens.js, mirror.js, isoprocess.js, titration.js, refraction.js, probability.js, bohratom.js, electrolysis.js, waves.js, crystal.js, orbitals.js, stereo.js, hydrostatics.js All 34 engine files syntax-checked OK.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
/* ═══════════════════════════════════════════════
|
||||
CollisionSim — 2D elastic/inelastic ball collision
|
||||
@@ -1008,3 +1008,123 @@ function _roundRect(ctx, x, y, w, h, r) {
|
||||
ctx.lineTo(x, y + r); ctx.arcTo(x, y, x+r, y, r);
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
/* ─── lab UI init ─────────────────────────────────── */
|
||||
function _openCollision() {
|
||||
document.getElementById('sim-topbar-title').textContent = 'Столкновение шаров';
|
||||
_simShow('sim-coll');
|
||||
_simShow('ctrl-coll');
|
||||
_registerSimState('collision', () => cSim?.getParams(), st => cSim?.setParams(st));
|
||||
if (_embedMode) _startStateEmit('collision');
|
||||
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => {
|
||||
if (!cSim) {
|
||||
cSim = new CollisionSim(document.getElementById('coll-canvas'));
|
||||
cSim.onUpdate = _collUpdateUI;
|
||||
cSim.onPlayPause = collPlayPause;
|
||||
}
|
||||
cSim.fit();
|
||||
cSim.setSpeed(+document.getElementById('sl-speed').value);
|
||||
collParam();
|
||||
cSim.draw();
|
||||
_collUpdateUI(cSim.stats());
|
||||
}));
|
||||
}
|
||||
|
||||
function collPlayPause() {
|
||||
if (!cSim) return;
|
||||
if (cSim.playing) { cSim.pause(); } else { cSim.play(); }
|
||||
_collSyncBtn();
|
||||
}
|
||||
|
||||
function _collSyncBtn() {
|
||||
const tb = document.getElementById('coll-play-btn');
|
||||
const lb = document.getElementById('coll-launch-main');
|
||||
const lbl = document.getElementById('coll-launch-label');
|
||||
const lic = document.getElementById('coll-launch-icon');
|
||||
if (!cSim) return;
|
||||
const playing = cSim.playing;
|
||||
|
||||
if (tb) {
|
||||
tb.innerHTML = playing
|
||||
? '<svg viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>'
|
||||
: '<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>';
|
||||
tb.title = playing ? 'Пауза' : 'Запустить';
|
||||
tb.classList.toggle('active', playing);
|
||||
}
|
||||
|
||||
if (lb && lbl && lic) {
|
||||
lb.classList.toggle('paused', playing);
|
||||
lb.classList.remove('done');
|
||||
if (playing) {
|
||||
lic.innerHTML = '<rect x="5" y="3" width="4" height="18"/><rect x="15" y="3" width="4" height="18"/>';
|
||||
lbl.textContent = 'Пауза';
|
||||
} else {
|
||||
lic.innerHTML = '<polygon points="5 3 19 12 5 21 5 3"/>';
|
||||
lbl.textContent = 'Запустить';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function collParam() {
|
||||
const m1 = +document.getElementById('sl-m1').value;
|
||||
const m2 = +document.getElementById('sl-m2').value;
|
||||
const v1 = +document.getElementById('sl-cv1').value;
|
||||
const v2 = +document.getElementById('sl-cv2').value;
|
||||
const angle = +document.getElementById('sl-cangle').value;
|
||||
const e = +document.getElementById('sl-e').value;
|
||||
const spd = +document.getElementById('sl-speed').value;
|
||||
|
||||
document.getElementById('c-m1').textContent = m1 + ' кг';
|
||||
document.getElementById('c-m2').textContent = m2 + ' кг';
|
||||
document.getElementById('c-v1').textContent = v1 + ' м/с';
|
||||
document.getElementById('c-v2').textContent = v2 + ' м/с';
|
||||
document.getElementById('c-angle').textContent = angle + '°';
|
||||
document.getElementById('c-e').textContent = e.toFixed(2);
|
||||
document.getElementById('c-speed').textContent = spd.toFixed(2) + '×';
|
||||
|
||||
if (cSim) {
|
||||
/* speed change doesn't require a reset */
|
||||
const speedChanged = Math.abs(cSim.speed - spd) > 0.001;
|
||||
if (speedChanged) cSim.setSpeed(spd);
|
||||
|
||||
const physChanged = cSim.m1 !== m1 || cSim.m2 !== m2 ||
|
||||
cSim.v1 !== v1 || cSim.v2 !== v2 ||
|
||||
cSim.angle !== angle || cSim.e !== e;
|
||||
if (physChanged) cSim.setParams({ m1, m2, v1, v2, angle, e });
|
||||
_collSyncBtn();
|
||||
}
|
||||
}
|
||||
|
||||
function collPreset(m1, m2, v1, v2, angle, e) {
|
||||
document.getElementById('sl-m1').value = m1;
|
||||
document.getElementById('sl-m2').value = m2;
|
||||
document.getElementById('sl-cv1').value = v1;
|
||||
document.getElementById('sl-cv2').value = v2;
|
||||
document.getElementById('sl-cangle').value = angle;
|
||||
document.getElementById('sl-e').value = e;
|
||||
collParam();
|
||||
}
|
||||
|
||||
function _collUpdateUI(s) {
|
||||
// before/after are arrays [{m, vx, vy, ke}, ...]
|
||||
function snapKE(arr) { return arr ? arr.reduce((t, b) => t + b.ke, 0) : null; }
|
||||
function snapP(arr) {
|
||||
if (!arr) return null;
|
||||
return Math.hypot(arr.reduce((t, b) => t + b.m * b.vx, 0),
|
||||
arr.reduce((t, b) => t + b.m * b.vy, 0));
|
||||
}
|
||||
const bKE = snapKE(s.before), bP = snapP(s.before);
|
||||
const aKE = snapKE(s.after), aP = snapP(s.after);
|
||||
const f2 = v => v !== null ? v.toFixed(2) : '—';
|
||||
|
||||
document.getElementById('cs-pbefore').textContent = bP !== null ? f2(bP) + ' кг·м/с' : '—';
|
||||
document.getElementById('cs-pafter').textContent = aP !== null ? f2(aP) + ' кг·м/с' : '—';
|
||||
document.getElementById('cs-kebefore').textContent = bKE !== null ? f2(bKE) + ' Дж' : '—';
|
||||
document.getElementById('cs-keafter').textContent = aKE !== null ? f2(aKE) + ' Дж' : '—';
|
||||
document.getElementById('cs-count').textContent = s.colCount;
|
||||
_collSyncBtn();
|
||||
}
|
||||
|
||||
/* ── magnetic ── */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user