feat(labs): wave 3 — 5 new sims + optics merger
Оптическая скамья (opticsbench) — merger thinlens + mirror + refraction - 4 режима: «Свободная сборка» / «Линза» / «Зеркало» / «Преломление» - Все 3 движка слиты в OpticsBenchSim (1583 строк) - Backward compat: #thinlens / #mirrors / #refraction → #opticsbench - Удалены: thinlens.js, mirror.js, refraction.js Радиоактивный распад (radioactive) — новая сима - Monte-Carlo распад: λ·dt вероятность на тик, частицы меняют цвет, эмитируются α/β/γ - Real-time N(t) график с теоретической кривой N₀·exp(-λt) - 7 изотопов: ¹⁴C, ¹³¹I, ¹³⁷Cs, ²²⁶Ra, ⁴⁰K, ²³⁸U-chain, ²³⁵U-chain - Цепочки распадов (U-238: 14 шагов сокращены до 5 ключевых) - Dating mode для C-14: t = ln(N₀/N)/λ - HUD: периодов прошло, % распалось, активность в Бк Тепловые двигатели (heatengine) — новая сима - 4 цикла: Карно / Отто / Дизель / Брайтон - PV-диаграмма с замкнутым циклом, заполненной площадью работы - Аналитически точные изотермы (PV=nRT) и адиабаты (PV^γ=const) - Анимированный поршень с резервуарами (красный T_h / синий T_c) - Частицы газа, скорость ∝ √T - Hover-tooltips с формулами для каждого сегмента Логические схемы (logic) — новая сима для информатики - Drag-drop конструктор: 12 типов компонентов (INPUT/CLOCK/OUTPUT/AND/OR/NOT/XOR/NAND/NOR/XNOR/BUF/wire) - Топологическая сортировка для propagation, цветовая подсветка HIGH/LOW - Авто-генерация булевого выражения (∧ ∨ ¬ ⊕) - Авто-таблица истинности (до 2^6 = 64 строк) - 6 пресетов: полусумматор, полный сумматор, RS-триггер, D-триггер, декодер 2-в-4, мультиплексор 2-в-1 Стехиометрия (stoichiometry) — новая сима - 10 реакций: Zn+HCl, H₂+O₂, CH₄+O₂, N₂+H₂ (Габер), Al+CuSO₄, Mg+O₂, CaCO₃→, HCl+NaOH, KMnO₄→, C₂H₅OH+O₂ - Sliders с переключением m/n/V (для газов V=n·22.4 при н.у.) - Анимация частиц при реакции, подсветка лимитирующего реагента - Пошаговый расчёт m→n→n_product→m_product с KaTeX - HUD: лимит, избытки, теоретический выход Каталог: 33 → 35 сим (5 новых − 3 удалённых merger) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+347
-76
@@ -328,6 +328,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- radioactive controls -->
|
||||
<div id="ctrl-radioactive" class="sim-zoom-btns" style="display:none">
|
||||
<button class="zoom-btn" id="rd-ctrl-play" onclick="radioactivePlay()" title="Старт / Пауза">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><polygon points="5,3 19,12 5,21"/></svg>
|
||||
</button>
|
||||
<button class="zoom-btn" onclick="radioactiveReset()" title="Сброс">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- theory toggle (all sims) -->
|
||||
<button class="zoom-btn" id="theory-toggle" onclick="toggleTheory()" title="Теория и формулы" style="margin-left:auto">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2z"/><path d="M22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z"/></svg>
|
||||
@@ -1235,6 +1245,85 @@
|
||||
</div>
|
||||
</div><!-- /#sim-circuit -->
|
||||
|
||||
<!-- ══════════════════════════════════════════════
|
||||
ЛОГИЧЕСКИЕ СХЕМЫ
|
||||
══════════════════════════════════════════════ -->
|
||||
<div id="sim-logic" class="sim-proj-wrap" style="display:none">
|
||||
|
||||
<!-- left panel: palette + presets -->
|
||||
<div class="sim-body-wrap" style="flex-direction:column">
|
||||
|
||||
<div style="display:flex;flex:1;min-height:0;overflow:hidden">
|
||||
|
||||
<div class="proj-panel" style="width:220px;gap:0;overflow-y:auto">
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Инструмент</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:5px;margin-bottom:10px">
|
||||
<button class="proj-preset-chip lgc-tool-btn active" data-tool="select" onclick="logicTool('select',this)">Выбор</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="INPUT" onclick="logicTool('INPUT',this)">INPUT</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="CLOCK" onclick="logicTool('CLOCK',this)">CLOCK</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="OUTPUT" onclick="logicTool('OUTPUT',this)">OUTPUT</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="AND" onclick="logicTool('AND',this)">AND</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="OR" onclick="logicTool('OR',this)">OR</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="NOT" onclick="logicTool('NOT',this)">NOT</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="XOR" onclick="logicTool('XOR',this)">XOR</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="NAND" onclick="logicTool('NAND',this)">NAND</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="NOR" onclick="logicTool('NOR',this)">NOR</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="XNOR" onclick="logicTool('XNOR',this)">XNOR</button>
|
||||
<button class="proj-preset-chip lgc-tool-btn" data-tool="BUFFER" onclick="logicTool('BUFFER',this)">BUF</button>
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:8px;margin-top:4px">Пресеты</div>
|
||||
<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:10px">
|
||||
<button class="proj-preset-chip" onclick="logicPreset('half-adder')">Полусумматор</button>
|
||||
<button class="proj-preset-chip" onclick="logicPreset('full-adder')">Полный сумматор</button>
|
||||
<button class="proj-preset-chip" onclick="logicPreset('rs-latch')">RS-триггер</button>
|
||||
<button class="proj-preset-chip" onclick="logicPreset('d-latch')">D-триггер</button>
|
||||
<button class="proj-preset-chip" onclick="logicPreset('decoder-2to4')">Декодер 2-в-4</button>
|
||||
<button class="proj-preset-chip" onclick="logicPreset('mux-2to1')">Мультиплексор 2-в-1</button>
|
||||
<button class="proj-preset-chip" onclick="logicPreset('and-gate')">AND (пример)</button>
|
||||
</div>
|
||||
|
||||
<button class="proj-preset-chip" style="margin-top:auto;background:rgba(239,71,111,0.12);border-color:rgba(239,71,111,0.35);color:#EF476F" onclick="logicClearAll()">Очистить</button>
|
||||
|
||||
<div style="margin-top:10px;font-size:0.67rem;color:var(--text-3);text-align:center;line-height:1.7;padding-top:4px">
|
||||
Клик = добавить элемент<br>
|
||||
Перетащи выход (кружок) на вход<br>
|
||||
2×клик по INPUT — переключить 0/1<br>
|
||||
ПКМ — удалить | Ctrl+Z отмена
|
||||
</div>
|
||||
|
||||
</div><!-- /.proj-panel -->
|
||||
|
||||
<div class="proj-canvas-outer" style="flex:1;position:relative">
|
||||
<canvas id="logic-canvas" style="display:block;position:absolute;top:0;left:0;width:100%;height:100%;cursor:default"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- right: boolean expression panel -->
|
||||
<div class="proj-panel" style="width:200px;gap:0;overflow-y:auto">
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Выражение</div>
|
||||
<div id="logic-expr" style="font-size:0.82rem;color:rgba(255,255,255,0.8);line-height:1.7;word-break:break-all;min-height:40px">
|
||||
Добавьте OUTPUT для вывода выражения
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.flex row -->
|
||||
|
||||
<!-- truth table panel (collapsible) -->
|
||||
<div id="logic-tt-panel" style="max-height:200px;overflow:auto;border-top:1px solid rgba(255,255,255,0.08);padding:8px 12px">
|
||||
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px">
|
||||
<span style="font-size:0.75rem;font-weight:700;color:rgba(255,255,255,0.55);letter-spacing:.08em;text-transform:uppercase">Таблица истинности</span>
|
||||
<button id="btn-logic-tt" class="zoom-btn active" onclick="logicToggleTable()" style="font-size:0.65rem;padding:2px 7px">скрыть</button>
|
||||
</div>
|
||||
<div id="logic-tt-body" style="font-size:0.78rem">
|
||||
<span style="color:rgba(255,255,255,0.35)">Добавьте INPUT и OUTPUT</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
|
||||
</div><!-- /#sim-logic -->
|
||||
|
||||
<!-- ══════════════════════════════════════════════
|
||||
КИНЕТИКА РЕАКЦИЙ
|
||||
══════════════════════════════════════════════ -->
|
||||
@@ -2419,10 +2508,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── THIN LENS sim body ── -->
|
||||
<div id="sim-thinlens" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap">
|
||||
<div class="proj-panel" style="width:220px;gap:0">
|
||||
<!-- ── OPTICSBENCH sim body ── -->
|
||||
<div id="sim-opticsbench" class="sim-proj-wrap" style="display:none;flex-direction:column">
|
||||
<!-- Tab bar -->
|
||||
<div style="display:flex;gap:0;border-bottom:1px solid #2a2a3e;background:#12121e;flex-shrink:0">
|
||||
<button id="ob-tab-lens" onclick="obSwitchMode('lens')" class="ob-tab active" style="flex:1;padding:8px 0;border:none;background:transparent;color:#ccc;font-size:.78rem;font-weight:600;cursor:pointer;border-bottom:2px solid transparent;transition:all .15s">Тонкая линза</button>
|
||||
<button id="ob-tab-mirror" onclick="obSwitchMode('mirror')" class="ob-tab" style="flex:1;padding:8px 0;border:none;background:transparent;color:#ccc;font-size:.78rem;font-weight:600;cursor:pointer;border-bottom:2px solid transparent;transition:all .15s">Зеркала</button>
|
||||
<button id="ob-tab-refraction" onclick="obSwitchMode('refraction')" class="ob-tab" style="flex:1;padding:8px 0;border:none;background:transparent;color:#ccc;font-size:.78rem;font-weight:600;cursor:pointer;border-bottom:2px solid transparent;transition:all .15s">Преломление</button>
|
||||
</div>
|
||||
<!-- Body row: control panels + shared canvas -->
|
||||
<div style="display:flex;flex:1;min-height:0;overflow:hidden">
|
||||
<!-- ── Lens control panel ── -->
|
||||
<div id="ob-ctrl-lens" class="proj-panel" style="width:220px;gap:0;flex-shrink:0">
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Параметры</div>
|
||||
<div class="proj-slider-row" style="margin-bottom:8px">
|
||||
<label style="font-size:.78rem;color:#ccc;width:55px">f = <span id="lens-f-val" style="color:var(--cyan);font-weight:700">100</span></label>
|
||||
@@ -2446,22 +2543,8 @@
|
||||
</div>
|
||||
<div class="pp-hint">Тащи стрелку-предмет или фокус мышью</div>
|
||||
</div>
|
||||
<div class="proj-canvas-outer">
|
||||
<canvas id="thinlens-canvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="proj-stats-bar" id="lensbar">
|
||||
<div class="pstat"><div class="pstat-label">f</div><div class="pstat-val" id="lensbar-v1" style="color:var(--cyan)">100</div></div>
|
||||
<div class="pstat"><div class="pstat-label">d'</div><div class="pstat-val" id="lensbar-v2" style="color:#EF476F">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">M</div><div class="pstat-val" id="lensbar-v3" style="color:#FFD166">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Тип</div><div class="pstat-val" id="lensbar-v4" style="color:var(--violet)">—</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── MIRRORS sim body ── -->
|
||||
<div id="sim-mirrors" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap">
|
||||
<div class="proj-panel" style="width:264px;gap:0">
|
||||
<!-- ── Mirror control panel ── -->
|
||||
<div id="ob-ctrl-mirror" class="proj-panel" style="width:264px;gap:0;flex-shrink:0;display:none">
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Тип зеркала</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:4px;margin-bottom:10px">
|
||||
<button class="preset-btn mirror-type-btn" id="mtype-flat" onclick="mirrorType('flat',this)" style="font-size:.72rem">Плоское</button>
|
||||
@@ -2482,24 +2565,24 @@
|
||||
<input type="range" id="sl-mirror-h" min="20" max="80" step="2" value="60" oninput="mirrorParam('h',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div style="display:flex;gap:6px;margin-top:8px;margin-bottom:8px;align-items:center">
|
||||
<button id="mirror-play-btn" onclick="mirrorTogglePlay(this)" style="flex:1;padding:6px 0;border-radius:8px;border:none;background:linear-gradient(135deg,var(--cyan),var(--violet));color:#fff;font-size:.78rem;font-weight:700;cursor:pointer">▶ Анимация</button>
|
||||
<button id="mirror-play-btn" onclick="mirrorTogglePlay(this)" style="flex:1;padding:6px 0;border-radius:8px;border:none;background:linear-gradient(135deg,var(--cyan),var(--violet));color:#fff;font-size:.78rem;font-weight:700;cursor:pointer">▶ Анимация</button>
|
||||
<div style="display:flex;flex-direction:column;align-items:center;gap:2px">
|
||||
<span style="font-size:.62rem;color:#888">скорость</span>
|
||||
<select id="mirror-speed-sel" onchange="mirrorSetSpeed(this.value)" style="background:#1a1a2e;color:#ccc;border:1px solid #333;border-radius:4px;font-size:.7rem;padding:2px 4px">
|
||||
<option value="0.25">×¼</option><option value="0.5">×½</option>
|
||||
<option value="1" selected>×1</option><option value="2">×2</option>
|
||||
<option value="0.25">×¼</option><option value="0.5">×½</option>
|
||||
<option value="1" selected>×1</option><option value="2">×2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:4px;margin-bottom:10px">
|
||||
<button onclick="mirrorStepNext()" style="flex:1;padding:5px 0;border-radius:6px;border:1px solid #333;background:#1a1a2e;color:#7BF5A4;font-size:.73rem;cursor:pointer" title="Показать следующий луч">① Пошагово</button>
|
||||
<button onclick="mirrorStepReset()" style="padding:5px 9px;border-radius:6px;border:1px solid #333;background:#1a1a2e;color:#888;font-size:.78rem;cursor:pointer" title="Показать все лучи">↺</button>
|
||||
<button onclick="mirrorStepNext()" style="flex:1;padding:5px 0;border-radius:6px;border:1px solid #333;background:#1a1a2e;color:#7BF5A4;font-size:.73rem;cursor:pointer" title="Показать следующий луч">① Пошагово</button>
|
||||
<button onclick="mirrorStepReset()" style="padding:5px 9px;border-radius:6px;border:1px solid #333;background:#1a1a2e;color:#888;font-size:.78rem;cursor:pointer" title="Показать все лучи">↺</button>
|
||||
</div>
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Отображение</div>
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:3px 10px;margin-bottom:10px">
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer"><input type="checkbox" id="mtog-normals" checked onchange="mirrorToggle('normals',this.checked)"> Нормали</label>
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer"><input type="checkbox" id="mtog-dims" checked onchange="mirrorToggle('dims',this.checked)"> Размеры</label>
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer"><input type="checkbox" id="mtog-angles" checked onchange="mirrorToggle('angles',this.checked)"> Углы θ</label>
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer"><input type="checkbox" id="mtog-angles" checked onchange="mirrorToggle('angles',this.checked)"> Углы θ</label>
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer"><input type="checkbox" id="mtog-photons" checked onchange="mirrorToggle('photons',this.checked)"> Фотоны</label>
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer"><input type="checkbox" id="mtog-grid" onchange="mirrorToggle('grid',this.checked)"> Сетка</label>
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer"><input type="checkbox" id="mtog-zones" checked onchange="mirrorToggle('zones',this.checked)"> Зоны</label>
|
||||
@@ -2517,16 +2600,59 @@
|
||||
</div>
|
||||
<div class="pp-hint">Тащи предмет, фокус или изображение мышью</div>
|
||||
</div>
|
||||
<div class="proj-canvas-outer">
|
||||
<canvas id="mirror-canvas"></canvas>
|
||||
<!-- ── Refraction control panel ── -->
|
||||
<div id="ob-ctrl-refraction" class="proj-panel" style="width:220px;gap:0;flex-shrink:0;display:none">
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Параметры</div>
|
||||
<div class="proj-slider-row" style="margin-bottom:8px">
|
||||
<label style="font-size:.78rem;color:#ccc;width:55px">n₁ = <span id="refr-n1-val" style="color:var(--violet);font-weight:700">1.00</span></label>
|
||||
<input type="range" id="sl-refr-n1" min="1" max="2.5" step="0.01" value="1" oninput="refrParam('n1',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div class="proj-slider-row" style="margin-bottom:8px">
|
||||
<label style="font-size:.78rem;color:#ccc;width:55px">n₂ = <span id="refr-n2-val" style="color:var(--cyan);font-weight:700">1.50</span></label>
|
||||
<input type="range" id="sl-refr-n2" min="1" max="2.5" step="0.01" value="1.5" oninput="refrParam('n2',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div class="proj-slider-row" style="margin-bottom:8px">
|
||||
<label style="font-size:.78rem;color:#ccc;width:55px">θ = <span id="refr-angle-val" style="color:#FFD166;font-weight:700">30</span>°</label>
|
||||
<input type="range" id="sl-refr-angle" min="0" max="89" step="1" value="30" oninput="refrParam('angle',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div style="margin-top:8px"></div>
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Пресеты</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:4px;margin-bottom:8px">
|
||||
<button class="preset-btn" onclick="refrPreset(1,1.5,30)">Воздух→Стекло</button>
|
||||
<button class="preset-btn" onclick="refrPreset(1.5,1,30)">Стекло→Воздух</button>
|
||||
<button class="preset-btn" onclick="refrPreset(1.33,1.5,30)">Вода→Стекло</button>
|
||||
<button class="preset-btn" onclick="refrPreset(1,2.42,45)">Алмаз</button>
|
||||
</div>
|
||||
<div class="pp-hint">Тащи луч мышью для изменения угла</div>
|
||||
</div>
|
||||
<!-- ── Shared canvas area (all 3 canvases stacked) ── -->
|
||||
<div class="proj-canvas-outer" style="position:relative;flex:1;min-width:0">
|
||||
<canvas id="ob-lens-canvas" style="position:absolute;top:0;left:0;width:100%;height:100%"></canvas>
|
||||
<canvas id="ob-mirror-canvas" style="position:absolute;top:0;left:0;width:100%;height:100%;display:none"></canvas>
|
||||
<canvas id="ob-refr-canvas" style="position:absolute;top:0;left:0;width:100%;height:100%;display:none"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="proj-stats-bar" id="mirrorbar">
|
||||
<div class="pstat"><div class="pstat-label">f</div><div class="pstat-val" id="mirrorbar-v1" style="color:var(--cyan)">120</div></div>
|
||||
<div class="pstat"><div class="pstat-label">d</div><div class="pstat-val" id="mirrorbar-v5" style="color:var(--violet)">240</div></div>
|
||||
<div class="pstat"><div class="pstat-label">d'</div><div class="pstat-val" id="mirrorbar-v2" style="color:#EF476F">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">M</div><div class="pstat-val" id="mirrorbar-v3" style="color:#FFD166">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Тип изобр.</div><div class="pstat-val" id="mirrorbar-v4" style="color:var(--violet)">—</div></div>
|
||||
<!-- Stats bar -->
|
||||
<div class="proj-stats-bar" id="ob-statsbar" style="padding:0">
|
||||
<div id="ob-stats-lens" style="display:flex;flex:1;gap:0">
|
||||
<div class="pstat"><div class="pstat-label">f</div><div class="pstat-val" id="lensbar-v1" style="color:var(--cyan)">100</div></div>
|
||||
<div class="pstat"><div class="pstat-label">d’</div><div class="pstat-val" id="lensbar-v2" style="color:#EF476F">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">M</div><div class="pstat-val" id="lensbar-v3" style="color:#FFD166">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Тип</div><div class="pstat-val" id="lensbar-v4" style="color:var(--violet)">—</div></div>
|
||||
</div>
|
||||
<div id="ob-stats-mirror" style="display:none;flex:1;gap:0">
|
||||
<div class="pstat"><div class="pstat-label">f</div><div class="pstat-val" id="mirrorbar-v1" style="color:var(--cyan)">120</div></div>
|
||||
<div class="pstat"><div class="pstat-label">d</div><div class="pstat-val" id="mirrorbar-v5" style="color:var(--violet)">240</div></div>
|
||||
<div class="pstat"><div class="pstat-label">d’</div><div class="pstat-val" id="mirrorbar-v2" style="color:#EF476F">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">M</div><div class="pstat-val" id="mirrorbar-v3" style="color:#FFD166">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Тип изобр.</div><div class="pstat-val" id="mirrorbar-v4" style="color:var(--violet)">—</div></div>
|
||||
</div>
|
||||
<div id="ob-stats-refr" style="display:none;flex:1;gap:0">
|
||||
<div class="pstat"><div class="pstat-label">θ₁</div><div class="pstat-val" id="refrbar-v1" style="color:var(--violet)">30°</div></div>
|
||||
<div class="pstat"><div class="pstat-label">θ₂</div><div class="pstat-val" id="refrbar-v2" style="color:var(--cyan)">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Крит. угол</div><div class="pstat-val" id="refrbar-v3" style="color:#FFD166">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">ПВО</div><div class="pstat-val" id="refrbar-v4" style="color:#EF476F">Нет</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2628,45 +2754,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── REFRACTION sim body ── -->
|
||||
<div id="sim-refraction" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap">
|
||||
<div class="proj-panel" style="width:220px;gap:0">
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Параметры</div>
|
||||
<div class="proj-slider-row" style="margin-bottom:8px">
|
||||
<label style="font-size:.78rem;color:#ccc;width:55px">n₁ = <span id="refr-n1-val" style="color:var(--violet);font-weight:700">1.00</span></label>
|
||||
<input type="range" id="sl-refr-n1" min="1" max="2.5" step="0.01" value="1" oninput="refrParam('n1',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div class="proj-slider-row" style="margin-bottom:8px">
|
||||
<label style="font-size:.78rem;color:#ccc;width:55px">n₂ = <span id="refr-n2-val" style="color:var(--cyan);font-weight:700">1.50</span></label>
|
||||
<input type="range" id="sl-refr-n2" min="1" max="2.5" step="0.01" value="1.5" oninput="refrParam('n2',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div class="proj-slider-row" style="margin-bottom:8px">
|
||||
<label style="font-size:.78rem;color:#ccc;width:55px">θ = <span id="refr-angle-val" style="color:#FFD166;font-weight:700">30</span>°</label>
|
||||
<input type="range" id="sl-refr-angle" min="0" max="89" step="1" value="30" oninput="refrParam('angle',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div style="margin-top:8px"></div>
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Пресеты</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:4px;margin-bottom:8px">
|
||||
<button class="preset-btn" onclick="refrPreset(1,1.5,30)">Воздух<svg class="ic" viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>Стекло</button>
|
||||
<button class="preset-btn" onclick="refrPreset(1.5,1,30)">Стекло<svg class="ic" viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>Воздух</button>
|
||||
<button class="preset-btn" onclick="refrPreset(1.33,1.5,30)">Вода<svg class="ic" viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>Стекло</button>
|
||||
<button class="preset-btn" onclick="refrPreset(1,2.42,45)">Алмаз</button>
|
||||
</div>
|
||||
<div class="pp-hint">Тащи луч мышью для изменения угла</div>
|
||||
</div>
|
||||
<div class="proj-canvas-outer">
|
||||
<canvas id="refraction-canvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="proj-stats-bar" id="refrbar">
|
||||
<div class="pstat"><div class="pstat-label">θ₁</div><div class="pstat-val" id="refrbar-v1" style="color:var(--violet)">30°</div></div>
|
||||
<div class="pstat"><div class="pstat-label">θ₂</div><div class="pstat-val" id="refrbar-v2" style="color:var(--cyan)">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Крит. угол</div><div class="pstat-val" id="refrbar-v3" style="color:#FFD166">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">ПВО</div><div class="pstat-val" id="refrbar-v4" style="color:#EF476F">Нет</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── PROBABILITY sim body ── -->
|
||||
<div id="sim-probability" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap">
|
||||
@@ -3326,6 +3413,99 @@
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
</div><!-- /#sim-hydro -->
|
||||
|
||||
<!-- ══════════════════════════════════════════════
|
||||
РАДИОАКТИВНЫЙ РАСПАД
|
||||
══════════════════════════════════════════════ -->
|
||||
<div id="sim-radioactive" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap">
|
||||
|
||||
<!-- left panel: controls -->
|
||||
<div class="proj-panel" style="width:228px;gap:0;overflow-y:auto">
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Изотоп</div>
|
||||
<select id="rd-isotope-sel" onchange="radioactiveIsotope(this.value)"
|
||||
style="width:100%;background:#1a1a2e;color:#ccc;border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:5px 8px;font-size:.82rem;margin-bottom:10px;cursor:pointer">
|
||||
<option value="C-14">¹⁴C — углерод (T½ = 5730 лет)</option>
|
||||
<option value="I-131">¹³¹I — йод (T½ = 8.0 сут)</option>
|
||||
<option value="Cs-137">¹³⁷Cs — цезий (T½ = 30.2 г)</option>
|
||||
<option value="Ra-226">²²⁶Ra — радий → цепочка</option>
|
||||
<option value="K-40">⁴⁰K — калий (T½ = 1.25·10⁹ г)</option>
|
||||
<option value="U-238">²³⁸U → цепочка → ²⁰⁶Pb</option>
|
||||
<option value="U-235">²³⁵U → цепочка → ²⁰⁷Pb</option>
|
||||
</select>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Начальное N₀</div>
|
||||
<div class="param-block">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Частиц</span>
|
||||
<span class="param-val" id="rd-n0-val" style="color:var(--violet)">500</span>
|
||||
</div>
|
||||
<input type="range" id="sl-rd-n0" class="param-slider" min="50" max="2000" step="50" value="500"
|
||||
oninput="radioactiveN0(this.value)">
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-top:4px;margin-bottom:6px">Скорость симуляции</div>
|
||||
<div class="param-block">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Масштаб</span>
|
||||
<span class="param-val" id="rd-speed-val" style="color:var(--cyan)">×10</span>
|
||||
</div>
|
||||
<input type="range" id="sl-rd-speed" class="param-slider" min="1" max="1000" step="1" value="10"
|
||||
oninput="radioactiveSpeed(this.value)">
|
||||
</div>
|
||||
|
||||
<div style="display:flex;gap:6px;margin-top:8px;flex-wrap:wrap">
|
||||
<button id="rd-play-btn" class="preset-btn" onclick="radioactivePlay()" style="flex:1;min-width:70px">Старт</button>
|
||||
<button class="preset-btn" onclick="radioactiveReset()" style="flex:1;min-width:70px">Сброс</button>
|
||||
</div>
|
||||
|
||||
<!-- Dating mode -->
|
||||
<div style="margin-top:16px;border-top:1px solid rgba(255,255,255,0.08);padding-top:12px">
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Радиоуглеродное датирование</div>
|
||||
<div class="param-block">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Осталось ¹⁴C</span>
|
||||
<span class="param-val" id="rd-dating-pct-val" style="color:#FFD166">50% осталось</span>
|
||||
</div>
|
||||
<input type="range" id="sl-rd-dating" class="param-slider" min="1" max="99" step="1" value="50"
|
||||
oninput="radioactiveDating(this.value)">
|
||||
</div>
|
||||
<div id="rd-dating-result" style="font-size:.8rem;color:var(--cyan);text-align:center;margin-top:4px">—</div>
|
||||
<div class="pp-hint">Только для ¹⁴C — другие изотопы игнорируют</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.proj-panel -->
|
||||
|
||||
<!-- particle canvas -->
|
||||
<div class="proj-canvas-outer" style="flex:1;min-width:0">
|
||||
<canvas id="radioactive-canvas"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- graph canvas -->
|
||||
<div class="proj-canvas-outer" style="width:280px;flex-shrink:0">
|
||||
<canvas id="radioactive-graph"></canvas>
|
||||
</div>
|
||||
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
|
||||
<!-- HUD bar -->
|
||||
<div class="proj-stats-bar" id="rd-hud">
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Прошло периодов</div>
|
||||
<div class="pstat-val" id="rd-hud-periods" style="color:var(--violet)">0 T½</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Распалось</div>
|
||||
<div class="pstat-val" id="rd-hud-decayed" style="color:#EF476F">0%</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Активность</div>
|
||||
<div class="pstat-val" id="rd-hud-activity" style="color:var(--cyan)">0 Бк</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /#sim-radioactive -->
|
||||
|
||||
<!-- ══════════════════════════════════════════════
|
||||
ПЛАНИМЕТРИЯ
|
||||
══════════════════════════════════════════════ -->
|
||||
@@ -3658,6 +3838,95 @@
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
</div><!-- /#sim-geometry -->
|
||||
|
||||
<!-- ── STOICHIOMETRY sim body ── -->
|
||||
<div id="sim-stoichiometry" class="sim-proj-wrap" style="display:none">
|
||||
<div id="stoichiometry-wrap" style="flex:1;min-height:0;overflow:hidden;"></div>
|
||||
</div>
|
||||
|
||||
<!-- ── HEAT ENGINE sim body ── -->
|
||||
<div id="sim-heatengine" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap" style="flex-direction:column">
|
||||
|
||||
<!-- top: two canvases side by side -->
|
||||
<div style="display:flex;flex:1;min-height:0;gap:0">
|
||||
|
||||
<!-- left: PV diagram -->
|
||||
<div class="proj-canvas-outer" style="flex:1">
|
||||
<canvas id="he-pv-canvas"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- right: piston animation -->
|
||||
<div class="proj-canvas-outer" style="width:220px;border-left:1px solid var(--border)">
|
||||
<canvas id="he-piston-canvas"></canvas>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- bottom: control panel -->
|
||||
<div style="display:flex;gap:12px;padding:10px 14px;border-top:1px solid var(--border);flex-wrap:wrap;align-items:flex-start;background:rgba(255,255,255,0.015)">
|
||||
|
||||
<!-- cycle selector -->
|
||||
<div style="display:flex;flex-direction:column;gap:4px;min-width:140px">
|
||||
<div class="gp-section-title" style="margin-bottom:4px">Цикл</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:3px">
|
||||
<button class="preset-btn he-cycle-btn active" onclick="heSetCycle('carnot',this)" style="font-size:.72rem">Карно</button>
|
||||
<button class="preset-btn he-cycle-btn" onclick="heSetCycle('otto',this)" style="font-size:.72rem">Отто</button>
|
||||
<button class="preset-btn he-cycle-btn" onclick="heSetCycle('diesel',this)" style="font-size:.72rem">Дизель</button>
|
||||
<button class="preset-btn he-cycle-btn" onclick="heSetCycle('brayton',this)" style="font-size:.72rem">Брайтон</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- sliders -->
|
||||
<div style="display:flex;flex-direction:column;gap:6px;flex:1;min-width:180px">
|
||||
<div class="gp-section-title" style="margin-bottom:2px">Параметры</div>
|
||||
<div class="proj-slider-row">
|
||||
<label style="font-size:.78rem;color:#ccc;width:90px">T<sub>гор</sub> = <span id="he-th-val" style="color:#EF476F;font-weight:700">800</span> K</label>
|
||||
<input type="range" id="sl-he-th" min="300" max="1500" step="10" value="800" oninput="heParam('Th',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div class="proj-slider-row">
|
||||
<label style="font-size:.78rem;color:#ccc;width:90px">T<sub>хол</sub> = <span id="he-tc-val" style="color:#06D6E0;font-weight:700">300</span> K</label>
|
||||
<input type="range" id="sl-he-tc" min="200" max="500" step="10" value="300" oninput="heParam('Tc',this.value)" style="flex:1">
|
||||
</div>
|
||||
<div class="proj-slider-row" id="he-cr-row" style="display:none">
|
||||
<label style="font-size:.78rem;color:#ccc;width:90px">r<sub>сж</sub> = <span id="he-cr-val" style="color:#FFD166;font-weight:700">8</span></label>
|
||||
<input type="range" id="sl-he-cr" min="2" max="20" step="1" value="8" oninput="heParam('cr',this.value)" style="flex:1">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- buttons -->
|
||||
<div style="display:flex;flex-direction:column;gap:5px;min-width:120px">
|
||||
<div class="gp-section-title" style="margin-bottom:2px">Управление</div>
|
||||
<div style="display:flex;gap:4px">
|
||||
<button onclick="heStart()" style="flex:1;padding:6px 0;border-radius:7px;border:none;background:linear-gradient(135deg,#EF476F,#9B5DE5);color:#fff;font-size:.78rem;font-weight:700;cursor:pointer" title="Старт">
|
||||
<svg class="ic" viewBox="0 0 24 24"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||
</button>
|
||||
<button onclick="hePause()" style="flex:1;padding:6px 0;border-radius:7px;border:1px solid #444;background:#1a1a2e;color:#ccc;font-size:.78rem;cursor:pointer" title="Пауза">
|
||||
<svg class="ic" viewBox="0 0 24 24"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>
|
||||
</button>
|
||||
<button onclick="heStep()" style="flex:1;padding:6px 0;border-radius:7px;border:1px solid #444;background:#1a1a2e;color:#ccc;font-size:.78rem;cursor:pointer" title="Шаг">
|
||||
<svg class="ic" viewBox="0 0 24 24"><polygon points="5 4 15 12 5 20 5 4"/><line x1="19" y1="5" x2="19" y2="19"/></svg>
|
||||
</button>
|
||||
<button onclick="heReset()" style="flex:1;padding:6px 0;border-radius:7px;border:1px solid #444;background:#1a1a2e;color:#888;font-size:.78rem;cursor:pointer" title="Сброс">
|
||||
<svg class="ic" viewBox="0 0 24 24"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-3.5"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /controls -->
|
||||
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
|
||||
<!-- stats bar -->
|
||||
<div class="proj-stats-bar">
|
||||
<div class="pstat"><div class="pstat-label">T<sub>гор</sub></div><div class="pstat-val" id="hebar-th" style="color:#EF476F">800 K</div></div>
|
||||
<div class="pstat"><div class="pstat-label">T<sub>хол</sub></div><div class="pstat-val" id="hebar-tc" style="color:#06D6E0">300 K</div></div>
|
||||
<div class="pstat"><div class="pstat-label">η</div><div class="pstat-val" id="hebar-eta" style="color:#7BF5A4">—%</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Q<sub>гор</sub>, Дж</div><div class="pstat-val" id="hebar-qh" style="color:#FFD166">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Q<sub>хол</sub>, Дж</div><div class="pstat-val" id="hebar-qc" style="color:var(--cyan)">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">W, Дж</div><div class="pstat-val" id="hebar-w" style="color:var(--violet)">—</div></div>
|
||||
</div>
|
||||
</div><!-- /#sim-heatengine -->
|
||||
|
||||
<!-- ── Theory panel (overlay right) ── -->
|
||||
<div class="theory-panel" id="theory-panel">
|
||||
<div class="theory-panel-inner" id="theory-content"></div>
|
||||
@@ -3697,6 +3966,7 @@
|
||||
<script src="/js/labs/angrybirds.js"></script>
|
||||
<script src="/js/labs/waves.js"></script>
|
||||
<script src="/js/labs/chemsandbox.js"></script>
|
||||
<script src="/js/labs/stoichiometry.js"></script>
|
||||
<script src="/js/labs/celldivision.js"></script>
|
||||
<script src="/js/labs/photosynthesis.js"></script>
|
||||
<script src="/js/labs/crystal.js"></script>
|
||||
@@ -3708,15 +3978,16 @@
|
||||
<script src="/js/labs/graphtransform.js"></script>
|
||||
<script src="/js/labs/pendulum.js"></script>
|
||||
<script src="/js/labs/equilibrium.js"></script>
|
||||
<script src="/js/labs/thinlens.js"></script>
|
||||
<script src="/js/labs/mirror.js"></script>
|
||||
<script src="/js/labs/opticsbench.js"></script>
|
||||
<script src="/js/labs/isoprocess.js"></script>
|
||||
<script src="/js/labs/titration.js"></script>
|
||||
<script src="/js/labs/refraction.js"></script>
|
||||
<script src="/js/labs/probability.js"></script>
|
||||
<script src="/js/labs/bohratom.js"></script>
|
||||
<script src="/js/labs/electrolysis.js"></script>
|
||||
<script src="/js/labs/hydrostatics.js"></script>
|
||||
<script src="/js/labs/radioactive.js"></script>
|
||||
<script src="/js/labs/geometry.js"></script>
|
||||
<script src="/js/labs/logic.js"></script>
|
||||
<script src="/js/labs/heatengine.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user