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:
Maxim Dolgolyov
2026-05-08 14:54:54 +03:00
parent d5f77bb648
commit ae31e4c4e8
35 changed files with 3657 additions and 3589 deletions
+105 -1
View File
@@ -1,4 +1,4 @@
'use strict';
'use strict';
/* ══════════════════════════════════════════════════════════
MagneticSim — magnetic field of current-carrying wires
• Click canvas to place wire (• out / × in)
@@ -1053,3 +1053,107 @@ class MagneticSim {
ctx.restore();
}
}
/* ─── lab UI init ─────────────────────────────────── */
function _openMagnetic() {
document.getElementById('sim-topbar-title').textContent = 'Магнитное поле токов';
_simShow('sim-mag');
_simShow('ctrl-mag');
requestAnimationFrame(() => requestAnimationFrame(() => {
if (!mSim) {
mSim = new MagneticSim(document.getElementById('mag-canvas'));
mSim.onUpdate = _magUpdateUI;
}
mSim.fit();
// default preset on first open
if (mSim.sources.length === 0) mSim.preset('anti');
_magUpdateUI(mSim.info());
}));
}
function magMode(dir) {
if (!mSim) return;
mSim.addMode = dir;
document.getElementById('mag-add-out').classList.toggle('active', dir === 'out');
document.getElementById('mag-add-in').classList.toggle('active', dir === 'in');
document.getElementById('mag-mode-out').classList.toggle('active', dir === 'out');
document.getElementById('mag-mode-in').classList.toggle('active', dir === 'in');
}
function magCurrentChange() {
const I = +document.getElementById('sl-curI').value;
document.getElementById('m-curI').textContent = I + ' А';
document.getElementById('mbar-I').textContent = I + ' А';
if (mSim) mSim.setCurrentAll(I);
}
function magLayer(name, rowEl) {
if (!mSim) return;
mSim.layers[name] = !mSim.layers[name];
rowEl.classList.toggle('active', mSim.layers[name]);
mSim._invalidateCache();
mSim.draw();
}
function magParticle(rowEl) {
if (!mSim) return;
mSim.toggleParticle();
rowEl.classList.toggle('active', mSim.particleOn);
_magUpdateUI(mSim.info());
}
function magCondToggle(rowEl) {
if (!mSim) return;
mSim.toggleConductor();
const on = mSim._cond.on;
rowEl.classList.toggle('active', on);
document.getElementById('cond-I-block').style.display = on ? '' : 'none';
_magUpdateUI(mSim.info());
}
function magCondCurrentChange() {
if (!mSim) return;
const I = parseFloat(document.getElementById('sl-condI').value);
document.getElementById('m-condI').textContent = I + ' А';
mSim.setConductorI(I);
}
function magFluxToggle(rowEl) {
if (!mSim) return;
mSim.toggleFlux();
rowEl.classList.toggle('active', mSim._flux.on);
_magUpdateUI(mSim.info());
}
function _magUpdateUI(info) {
document.getElementById('ms-out').textContent = info.out;
document.getElementById('ms-in').textContent = info.inn;
document.getElementById('mbar-total').textContent = info.total;
document.getElementById('mbar-out').textContent = info.out;
document.getElementById('mbar-in').textContent = info.inn;
document.getElementById('mbar-particle').textContent = info.particleOn ? 'вкл' : 'выкл';
document.getElementById('mbar-particle').style.color = info.particleOn ? '#ffff50' : '';
// Ampere force
const fEl = document.getElementById('mbar-ampere');
if (info.condOn && info.Fz !== 0) {
const dir = info.Fz > 0 ? '⊙' : '⊗';
fEl.textContent = dir + ' ' + Math.abs(info.Fz).toFixed(3);
fEl.style.color = '#fbbf24';
} else {
fEl.textContent = '—';
fEl.style.color = '#fbbf24';
}
// Flux
const phEl = document.getElementById('mbar-flux');
if (info.fluxOn) {
phEl.textContent = info.flux.toExponential(2) + ' Вб';
phEl.style.color = '#34d399';
} else {
phEl.textContent = '—';
phEl.style.color = '#34d399';
}
}
/* ── triangle ── */