feat(labs): wave 2 — depth features across 6 sims
Электрические цепи (circuit): - Индуктивность L как новый компонент (1–1000 мГн, шорт в DC, jωL в AC) - RLC preset для демонстрации резонанса - Осциллограф: U(t)/I(t) для выбранного компонента, 100 sample, dual-axis - Heatmap мощности: радиальный градиент halo от blue→red пропорционально P=UI Стереометрия 3D (stereo): - Сечение через 3 произвольные точки: pick на гранях/рёбрах/вершинах - Плоскость + полигон пересечения с авто-определением типа (3–6-угольник) и площадью - Step-by-step режим: визуализация P1→линия→P2→линия→P3→плоскость→сечение - Поддержка всех solids (включая cylinder/cone через sampling fallback) Планиметрия (geometry): - Задачник framework: CHALLENGES[] с setup/check функциями - 5 стартовых задач: серединный перпендикуляр, биссектриса, описанная окружность, ГМТ, касательная - Авто-checker: толерантности ±0.5° для углов, ±1–5% для расстояний - UI: collapsible панель с статус-иконками, конфетти + «Молодец!» на success Электромагнитные поля (emfield): - Preset «Тороид»: 16+16 проводов в концентрических кольцах - Поверхность Гаусса: draggable круг, считает Φ = q_enc/ε₀, подсвечивает охваченные заряды - Motional EMF: draggable rod, arrow-keys управление, считает ε = ∫(v×B)·dl Химическая песочница (chemsandbox): - Live-overlay с уравнением реакции: молекулярное / полное ионное / сокращённое ионное - Coverage: 49/49 молекулярных, 34/49 ионных, 36/49 сокращённых - Auto-hide через 5 сек, fade-in animation, цветовая кодировка типов Волны и звук (waves): - Doppler: source+observer drag, expanding wavefronts, f_obs формула, Mach cone при v>c - Beats: f1+f2, sum waveform с envelope, индикация f_beat=|f1-f2| - Spectrum (DFT): N=256 samples pure JS, bar-chart с пиками и labels, «Добавить гармонику» Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -500,7 +500,8 @@ class ChemSandboxSim {
|
||||
type: r ? r.type : null,
|
||||
equation: r ? r.eq : null,
|
||||
products: r && !r.fx.none ? this._productsStr(r) : null,
|
||||
ionNet: r ? r.ionNet || null : null,
|
||||
ionFull: r ? r.ionFull || null : null,
|
||||
ionNet: r ? r.ionNet || null : null,
|
||||
why: r ? r.why || null : null,
|
||||
};
|
||||
}
|
||||
@@ -1834,6 +1835,58 @@ class ChemSandboxSim {
|
||||
_lastReportedEquation = info.equation;
|
||||
if (window.LS?.reportLabActivity) LS.reportLabActivity(1).catch(() => {});
|
||||
}
|
||||
// ── HTML overlay: 3-form equation display ──
|
||||
_chemSandShowEqOverlay(info);
|
||||
}
|
||||
|
||||
/* equation overlay timer handle */
|
||||
let _csEqOverlayTimer = null;
|
||||
|
||||
function _chemSandShowEqOverlay(info) {
|
||||
const overlay = document.getElementById('chemsand-eq-overlay');
|
||||
if (!overlay) return;
|
||||
|
||||
// clear any existing hide timer
|
||||
if (_csEqOverlayTimer) { clearTimeout(_csEqOverlayTimer); _csEqOverlayTimer = null; }
|
||||
|
||||
if (!info.reaction || !info.equation) {
|
||||
overlay.classList.remove('visible');
|
||||
return;
|
||||
}
|
||||
|
||||
/* helpers: strip SVG arrow markup → plain text "=" */
|
||||
function _stripSvg(s) {
|
||||
if (!s) return '';
|
||||
return s.replace(/<svg[^>]*class="ic"[^>]*>[\s\S]*?<\/svg>/g, '=');
|
||||
}
|
||||
|
||||
const molLine = document.getElementById('chemsand-eq-mol');
|
||||
const fullLine = document.getElementById('chemsand-eq-full');
|
||||
const netLine = document.getElementById('chemsand-eq-net');
|
||||
const typeBadge = document.getElementById('chemsand-eq-type');
|
||||
|
||||
molLine.innerHTML = _stripSvg(info.equation);
|
||||
fullLine.innerHTML = info.ionFull ? _stripSvg(info.ionFull) : '<span style="opacity:.45">ионное уравнение недоступно</span>';
|
||||
netLine.innerHTML = info.ionNet ? _stripSvg(info.ionNet) : '<span style="opacity:.45">сокращённое ионное недоступно</span>';
|
||||
|
||||
const tpColor = info.type === 'Нет реакции' ? '#EF476F'
|
||||
: info.type === 'Индикатор' ? '#9B59B6'
|
||||
: info.type === 'Нейтрализация'? '#FFD166'
|
||||
: info.type === 'Замещение' ? '#06D6E0'
|
||||
: info.type === 'Обмен' ? '#7BF5A4'
|
||||
: info.type === 'Акт. металл' ? '#EF476F'
|
||||
: 'rgba(255,255,255,.5)';
|
||||
typeBadge.textContent = info.type || '';
|
||||
typeBadge.style.color = tpColor;
|
||||
typeBadge.style.borderColor = tpColor + '55';
|
||||
|
||||
overlay.classList.add('visible');
|
||||
|
||||
/* auto-hide after 5 s */
|
||||
_csEqOverlayTimer = setTimeout(() => {
|
||||
overlay.classList.remove('visible');
|
||||
_csEqOverlayTimer = null;
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
/* ── Cell Division ── */
|
||||
|
||||
Reference in New Issue
Block a user