feat(labs): planimetry locus + emfield merger + projectile graphs + UI cleanup
Геометрия (планиметрия): - Живые измерения как объекты: длина / угол / площадь — auto-recompute, draggable chips - Инструмент ГМТ: sweep мовера через параметр, рисует кривую места точек - Новые типы точек: on_segment (скользит по отрезку, _t), on_circle (по окружности, _theta) - Toolbar: «Длина», «Угол», «Площадь», «ГМТ», «На отрезке», «На окружности» Электромагнитные поля (emfield): - Merge magnetic.js + coulomb.js в один EMFieldSim с 3 режимами (E / B / комбинированное) - Унифицированный pipeline: colormap, field lines, vectors, equipotentials, flux loop, test particle - Combined-режим: полная сила Лоренца F=q(E+v×B) - Backward compat: #coulomb и #magnetic хеши и ?sim= параметры редиректят в emfield - Удалены: magnetic.js, coulomb.js. Добавлен: emfield.js Бросок тела (projectile): - Режим целей: 3 окна, hit-детекция, HUD «Цели: N/M / Попыток: K» - Графики x(t), y(t), vx(t), vy(t) — 2×2 Canvas 2D, real-time - Двойной бросок: одновременно 2 траектории для сравнения (cyan vs gold) UI fixes (по результатам аудита): - Заменены emoji/unicode на inline SVG .ic: switch ⌇, spring 〜 (5 мест), download ⬇ (2), camera 📷 - Убраны декоративные символы ☉ ○ из geometry tool labels - Добавлены THEORY entries: geometry, hydrostatics (раньше показывали fallback) - Стандартизирована ширина panel для sim-proj и sim-coll (240px) - waves перенесён в физический блок SIMS catalog (был после биологии) - Очищен дефолтный sim-topbar-title (был «График функции») Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+293
-237
@@ -63,7 +63,7 @@
|
||||
<svg viewBox="0 0 24 24" fill="none"><polyline points="15 18 9 12 15 6"/></svg>
|
||||
Назад
|
||||
</button>
|
||||
<div class="sim-topbar-title" id="sim-topbar-title">График функции</div>
|
||||
<div class="sim-topbar-title" id="sim-topbar-title"></div>
|
||||
|
||||
<!-- graph controls -->
|
||||
<div id="ctrl-graph" class="sim-zoom-btns">
|
||||
@@ -91,11 +91,13 @@
|
||||
<button class="zoom-btn" onclick="projClearGhosts()" title="Очистить следы" style="font-size:.65rem"><svg class="ic" viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
|
||||
</div>
|
||||
|
||||
<!-- magnetic controls -->
|
||||
<div id="ctrl-mag" class="sim-zoom-btns" style="display:none">
|
||||
<button class="zoom-btn" id="mag-add-out" onclick="magMode('out')" title="Добавить провод • (ток на нас)" style="font-size:1rem">•</button>
|
||||
<button class="zoom-btn" id="mag-add-in" onclick="magMode('in')" title="Добавить провод × (ток от нас)" style="font-size:1rem">×</button>
|
||||
<button class="zoom-btn" onclick="mSim && mSim.clearAll()" title="Очистить">
|
||||
<!-- emfield controls -->
|
||||
<div id="ctrl-emfield" class="sim-zoom-btns" style="display:none">
|
||||
<button class="zoom-btn" id="em-sign-pos" onclick="emSign(1)" title="Добавлять + заряды" style="font-size:1.1rem;font-weight:900;color:#EF476F">+</button>
|
||||
<button class="zoom-btn" id="em-sign-neg" onclick="emSign(-1)" title="Добавлять − заряды" style="font-size:1.1rem;font-weight:900;color:#4CC9F0">−</button>
|
||||
<button class="zoom-btn" id="em-dir-out" onclick="emWireDir('out')" title="Провод • (ток на нас)" style="font-size:1rem">•</button>
|
||||
<button class="zoom-btn" id="em-dir-in" onclick="emWireDir('in')" title="Провод × (ток от нас)" style="font-size:1rem">×</button>
|
||||
<button class="zoom-btn" onclick="emSim && emSim.clearAll()" title="Очистить">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14H6L5 6"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -157,14 +159,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- coulomb controls -->
|
||||
<div id="ctrl-coulomb" class="sim-zoom-btns" style="display:none">
|
||||
<button class="zoom-btn" id="csign-pos" onclick="coulombSign(1)" title="Добавить + заряд" style="font-size:1.1rem;font-weight:900;color:#EF476F">+</button>
|
||||
<button class="zoom-btn" id="csign-neg" onclick="coulombSign(-1)" title="Добавить − заряд" style="font-size:1.1rem;font-weight:900;color:#4CC9F0">−</button>
|
||||
<button class="zoom-btn" onclick="csSim && csSim.reset(); csSim && csSim.draw(); _coulombUpdateUI(csSim&&csSim.info())" title="Очистить">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14H6L5 6"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- (coulomb merged into ctrl-emfield) -->
|
||||
|
||||
<!-- circuit controls -->
|
||||
<div id="ctrl-circuit" class="sim-zoom-btns" style="display:none">
|
||||
@@ -175,7 +170,7 @@
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-diode" onclick="circTool('diode',this)" title="Диод (D)" style="font-size:.75rem"><svg class="ic" viewBox="0 0 24 24"><polygon points="5 3 19 12 5 21 5 3"/></svg>|</button>
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-led" onclick="circTool('led',this)" title="LED" style="font-size:.6rem;font-weight:800">LED</button>
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-ac" onclick="circTool('ac',this)" title="AC источник" style="font-size:.65rem;font-weight:800">AC</button>
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-switch" onclick="circTool('switch',this)" title="Выключатель (S)" style="font-size:.7rem">⌇</button>
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-switch" onclick="circTool('switch',this)" title="Выключатель (S)" style="font-size:.7rem"><svg class="ic" viewBox="0 0 24 24"><line x1="3" y1="12" x2="9" y2="12"/><line x1="15" y1="12" x2="21" y2="12"/><line x1="9" y1="12" x2="17" y2="6"/></svg></button>
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-lamp" onclick="circTool('lamp',this)" title="Лампа (L)" style="font-size:.75rem"><svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-ammeter" onclick="circTool('ammeter',this)" title="Амперметр (A)" style="font-size:.6rem;font-weight:800">А</button>
|
||||
<button class="zoom-btn circ-top-btn" id="ctool-voltmeter" onclick="circTool('voltmeter',this)" title="Вольтметр (V)" style="font-size:.6rem;font-weight:800">V</button>
|
||||
@@ -199,7 +194,7 @@
|
||||
</span>
|
||||
<!-- flask tools -->
|
||||
<span id="ctrl-chem-flask" style="display:none">
|
||||
<button class="zoom-btn" onclick="flaskSim && flaskSim.dropMetal()" title="Бросить металл" style="font-size:.65rem;font-weight:800">⬇ Металл</button>
|
||||
<button class="zoom-btn" onclick="flaskSim && flaskSim.dropMetal()" title="Бросить металл" style="font-size:.65rem;font-weight:800"><svg class="ic" viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg> Металл</button>
|
||||
<button class="zoom-btn" id="flask-flame-btn" onclick="flaskToggleFlame()" title="Поджечь H₂" style="font-size:.75rem"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:inline-block;vertical-align:middle"><path d="M12 2c.5 3.5-1.5 6-1.5 6 1 1.5 3 2 3 5a4 4 0 01-8 0c0-2 .5-3 1.5-4.5C8.5 6.5 7 4.5 7 4.5S9.5 2 12 2z"/></svg></button>
|
||||
<button class="zoom-btn" id="flask-pause-btn" onclick="flaskTogglePause()" title="Пауза" style="font-size:.68rem;font-weight:800;font-family:Manrope,sans-serif"><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>
|
||||
</span>
|
||||
@@ -224,7 +219,7 @@
|
||||
<span id="ctrl-dyn-sb" style="display:contents">
|
||||
<button class="zoom-btn sb-tool-btn active" id="sbt-box" onclick="sbTool('box',this)" style="font-size:.65rem;font-weight:800"><svg class="ic" viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/></svg> Блок</button>
|
||||
<button class="zoom-btn sb-tool-btn" id="sbt-ball" onclick="sbTool('ball',this)" style="font-size:.65rem;font-weight:800"><svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="8" fill="currentColor" stroke="none"/></svg> Шар</button>
|
||||
<button class="zoom-btn sb-tool-btn" id="sbt-spring" onclick="sbTool('spring',this)" style="font-size:.65rem;font-weight:800">〜 Пружина</button>
|
||||
<button class="zoom-btn sb-tool-btn" id="sbt-spring" onclick="sbTool('spring',this)" style="font-size:.65rem;font-weight:800"><svg class="ic" viewBox="0 0 24 24" fill="none"><path d="M3 12 L6 8 L9 16 L12 8 L15 16 L18 8 L21 12"/></svg> Пружина</button>
|
||||
<button class="zoom-btn sb-tool-btn" id="sbt-rope" onclick="sbTool('rope',this)" style="font-size:.65rem;font-weight:800">— Нить</button>
|
||||
<button class="zoom-btn sb-tool-btn" id="sbt-anchor" onclick="sbTool('anchor',this)" style="font-size:.65rem;font-weight:800"><svg class="ic" viewBox="0 0 24 24"><path d="M12 2 2 12 12 22 22 12Z"/></svg> Якорь</button>
|
||||
<button class="zoom-btn sb-tool-btn" id="sbt-erase" onclick="sbTool('erase',this)" style="font-size:.65rem;font-weight:800"><svg class="ic" viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> Ластик</button>
|
||||
@@ -456,156 +451,204 @@
|
||||
|
||||
</div><!-- /#sim-graph -->
|
||||
|
||||
<!-- ── MAGNETIC sim body ── -->
|
||||
<div id="sim-mag" class="sim-proj-wrap" style="display:none">
|
||||
<!-- ══ ЭЛЕКТРОМАГНИТНЫЕ ПОЛЯ (EMField) ══
|
||||
replaces sim-mag + sim-coulomb -->
|
||||
<div id="sim-emfield" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap">
|
||||
|
||||
<div class="proj-panel" style="width:248px;gap:0">
|
||||
<div class="proj-panel" style="width:258px;gap:0">
|
||||
|
||||
<!-- Mode -->
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Режим добавления</div>
|
||||
<div style="display:flex;gap:6px;margin-bottom:12px">
|
||||
<button id="mag-mode-out" class="mag-mode-btn active" onclick="magMode('out')">
|
||||
<span style="font-size:1.2rem;font-weight:900;color:#06D6E0">•</span>
|
||||
Ток на нас
|
||||
</button>
|
||||
<button id="mag-mode-in" class="mag-mode-btn" onclick="magMode('in')">
|
||||
<span style="font-size:1.1rem;font-weight:900;color:#F15BB5">×</span>
|
||||
Ток от нас
|
||||
</button>
|
||||
<!-- Mode tabs -->
|
||||
<div style="display:flex;gap:4px;margin-bottom:12px">
|
||||
<button id="em-tab-E" class="mag-mode-btn active" onclick="emSwitchMode('E')" style="flex:1;font-size:.72rem">Электрическое</button>
|
||||
<button id="em-tab-B" class="mag-mode-btn" onclick="emSwitchMode('B')" style="flex:1;font-size:.72rem">Магнитное</button>
|
||||
<button id="em-tab-combined" class="mag-mode-btn" onclick="emSwitchMode('combined')" style="flex:1;font-size:.72rem">Комбо</button>
|
||||
</div>
|
||||
|
||||
<!-- Current -->
|
||||
<div class="param-block">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Сила тока I</span>
|
||||
<span class="param-val" id="m-curI">6 А</span>
|
||||
<!-- E controls -->
|
||||
<div id="em-ctrl-E">
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Заряд</div>
|
||||
<div style="display:flex;gap:6px;margin-bottom:10px">
|
||||
<button class="mag-mode-btn active" id="em-sign-pos" onclick="emSign(1)" style="flex:1">
|
||||
<span style="font-size:1.2rem;font-weight:900;color:#EF476F">+</span> Полож.
|
||||
</button>
|
||||
<button class="mag-mode-btn" id="em-sign-neg" onclick="emSign(-1)" style="flex:1">
|
||||
<span style="font-size:1.2rem;font-weight:900;color:#4CC9F0">−</span> Отриц.
|
||||
</button>
|
||||
</div>
|
||||
<input type="range" class="param-slider" id="sl-curI" min="1" max="20" value="6" oninput="magCurrentChange()">
|
||||
</div>
|
||||
|
||||
<!-- Layers -->
|
||||
<div class="gp-section-title" style="margin-top:4px;margin-bottom:8px">Визуализация</div>
|
||||
<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:10px">
|
||||
<label class="tri-layer-row active" id="ml-colormap" onclick="magLayer('colormap',this)">
|
||||
<span class="tri-dot" style="background:linear-gradient(90deg,#9B5DE5,#06D6E0,#F15BB5)"></span>
|
||||
<span class="tri-layer-name">Карта поля</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.4)">hue = направление</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="content:'';display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row active" id="ml-fieldlines" onclick="magLayer('fieldlines',this)">
|
||||
<span class="tri-dot" style="background:var(--cyan);box-shadow:0 0 5px var(--cyan)"></span>
|
||||
<span class="tri-layer-name">Силовые линии</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.4)">+ стрелки</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="content:'';display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row" id="ml-vectors" onclick="magLayer('vectors',this)">
|
||||
<span class="tri-dot" style="background:var(--violet);box-shadow:0 0 5px var(--violet)"></span>
|
||||
<span class="tri-layer-name">Векторное поле</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.4)">сетка стрелок</span>
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Слои E</div>
|
||||
<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:10px">
|
||||
<label class="tri-layer-row active" onclick="emLayer('E','colormap',this)">
|
||||
<span class="tri-dot" style="background:linear-gradient(90deg,#EF476F,#9B5DE5,#4CC9F0)"></span>
|
||||
<span class="tri-layer-name">Карта потенциала</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.4)">V</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row active" onclick="emLayer('E','fieldlines',this)">
|
||||
<span class="tri-dot" style="background:rgba(255,255,255,0.8)"></span>
|
||||
<span class="tri-layer-name">Линии поля E</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.4)">E</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row" onclick="emLayer('E','vectors',this)">
|
||||
<span class="tri-dot" style="background:rgba(255,255,255,0.4)"></span>
|
||||
<span class="tri-layer-name">Векторы E</span>
|
||||
<span class="tri-toggle"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:2px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row active" onclick="emLayer('E','equipotentials',this)">
|
||||
<span class="tri-dot" style="background:rgba(255,255,255,0.5)"></span>
|
||||
<span class="tri-layer-name">Эквипотенциали</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.3)">V=const</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row" onclick="emLayer('E','forces',this)">
|
||||
<span class="tri-dot" style="background:#FFD166;box-shadow:0 0 5px #FFD166"></span>
|
||||
<span class="tri-layer-name">Силы Кулона</span>
|
||||
<span class="tri-layer-hint" style="color:#FFD166">F</span>
|
||||
<span class="tri-toggle"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:2px"></span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Пресеты E</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:5px;margin-bottom:10px">
|
||||
<button class="proj-preset-chip" onclick="emPresetE('dipole')">Диполь ±</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetE('equal')">Два + заряда</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetE('quadrupole')">Квадруполь</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetE('ring')">Кольцо</button>
|
||||
</div>
|
||||
</div><!-- /#em-ctrl-E -->
|
||||
|
||||
<!-- B controls -->
|
||||
<div id="em-ctrl-B" style="display:none">
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Провод</div>
|
||||
<div style="display:flex;gap:6px;margin-bottom:10px">
|
||||
<button class="mag-mode-btn active" id="em-dir-out" onclick="emWireDir('out')" style="flex:1">
|
||||
<span style="font-size:1.2rem;font-weight:900;color:#06D6E0">•</span> Ток на нас
|
||||
</button>
|
||||
<button class="mag-mode-btn" id="em-dir-in" onclick="emWireDir('in')" style="flex:1">
|
||||
<span style="font-size:1.1rem;font-weight:900;color:#F15BB5">×</span> Ток от нас
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="param-block" style="margin-bottom:10px">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Сила тока I</span>
|
||||
<span class="param-val" id="em-curI-val">6 А</span>
|
||||
</div>
|
||||
<input type="range" class="param-slider" id="sl-emI" min="1" max="20" value="6" oninput="emCurrentChange()">
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Слои B</div>
|
||||
<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:10px">
|
||||
<label class="tri-layer-row active" onclick="emLayer('B','colormap',this)">
|
||||
<span class="tri-dot" style="background:linear-gradient(90deg,#9B5DE5,#06D6E0,#F15BB5)"></span>
|
||||
<span class="tri-layer-name">Карта поля B</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.4)">hue=угол</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row active" onclick="emLayer('B','fieldlines',this)">
|
||||
<span class="tri-dot" style="background:var(--cyan);box-shadow:0 0 5px var(--cyan)"></span>
|
||||
<span class="tri-layer-name">Силовые линии B</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,.4)">+ стрелки</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row" onclick="emLayer('B','vectors',this)">
|
||||
<span class="tri-dot" style="background:var(--violet);box-shadow:0 0 5px var(--violet)"></span>
|
||||
<span class="tri-layer-name">Векторное поле B</span>
|
||||
<span class="tri-toggle"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:2px"></span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Проводник в поле</div>
|
||||
<label class="tri-layer-row" id="em-cond-row" onclick="emCondToggle(this)" style="margin-bottom:6px">
|
||||
<span class="tri-dot" style="background:#fbbf24;box-shadow:0 0 5px #fbbf24"></span>
|
||||
<span class="tri-layer-name">Проводник (Ампер)</span>
|
||||
<span class="tri-layer-hint" style="color:#fbbf24">F=IL×B</span>
|
||||
<span class="tri-toggle"></span>
|
||||
</label>
|
||||
<div class="param-block" id="em-cond-I-block" style="display:none;margin-bottom:10px">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Ток проводника I*</span>
|
||||
<span class="param-val" id="em-condI-val">8 А</span>
|
||||
</div>
|
||||
<input type="range" class="param-slider" id="sl-emCondI" min="1" max="20" value="8" oninput="emCondCurrentChange()">
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Магнитный поток</div>
|
||||
<label class="tri-layer-row" id="em-flux-row" onclick="emFluxToggle(this)" style="margin-bottom:10px">
|
||||
<span class="tri-dot" style="background:#34d399;box-shadow:0 0 5px #34d399"></span>
|
||||
<span class="tri-layer-name">Индикатор потока</span>
|
||||
<span class="tri-layer-hint" style="color:#34d399">Φ=B·S</span>
|
||||
<span class="tri-toggle"></span>
|
||||
</label>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Пресеты B</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:5px;margin-bottom:10px">
|
||||
<button class="proj-preset-chip" onclick="emPresetB('single')">Один провод</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetB('parallel')">Параллельные</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetB('anti')">Антипарал.</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetB('solenoid')">Соленоид</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetB('quadrupole')">Квадруполь</button>
|
||||
<button class="proj-preset-chip" onclick="emPresetB('ring')">Кольцо</button>
|
||||
</div>
|
||||
</div><!-- /#em-ctrl-B -->
|
||||
|
||||
<!-- combined extra -->
|
||||
<div id="em-ctrl-combined" style="display:none">
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Тип добавляемого</div>
|
||||
<div style="display:flex;gap:6px;margin-bottom:10px">
|
||||
<button class="mag-mode-btn active" id="em-add-charge" onclick="emAddTypeSwitch('charge')" style="flex:1;font-size:.72rem">Заряд</button>
|
||||
<button class="mag-mode-btn" id="em-add-wire" onclick="emAddTypeSwitch('wire')" style="flex:1;font-size:.72rem">Провод</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Particle -->
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Частица</div>
|
||||
<label class="tri-layer-row" id="ml-particle" onclick="magParticle(this)" style="margin-bottom:10px">
|
||||
<div class="gp-section-title" style="margin-bottom:6px">Частица</div>
|
||||
<label class="tri-layer-row" id="em-particle-row" onclick="emParticle(this)" style="margin-bottom:10px">
|
||||
<span class="tri-dot" style="background:#ffff50;box-shadow:0 0 5px #ffff50"></span>
|
||||
<span class="tri-layer-name">Заряженная частица</span>
|
||||
<span class="tri-layer-hint" style="color:#ffff50">Сила Лоренца</span>
|
||||
<span class="tri-toggle" id="ml-particle-toggle"></span>
|
||||
<span class="tri-layer-hint" style="color:#ffff50">Лоренц</span>
|
||||
<span class="tri-toggle"></span>
|
||||
</label>
|
||||
|
||||
<!-- Conductor -->
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Проводник в поле</div>
|
||||
<label class="tri-layer-row" id="ml-cond" onclick="magCondToggle(this)" style="margin-bottom:6px">
|
||||
<span class="tri-dot" style="background:#fbbf24;box-shadow:0 0 5px #fbbf24"></span>
|
||||
<span class="tri-layer-name">Проводник (Ампер)</span>
|
||||
<span class="tri-layer-hint" style="color:#fbbf24">F = I·L×B</span>
|
||||
<span class="tri-toggle" id="ml-cond-toggle"></span>
|
||||
</label>
|
||||
<div class="param-block" id="cond-I-block" style="display:none;margin-bottom:10px">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Ток проводника I꜀</span>
|
||||
<span class="param-val" id="m-condI">8 А</span>
|
||||
</div>
|
||||
<input type="range" class="param-slider" id="sl-condI" min="1" max="20" value="8" oninput="magCondCurrentChange()">
|
||||
</div>
|
||||
|
||||
<!-- Flux -->
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Магнитный поток</div>
|
||||
<label class="tri-layer-row" id="ml-flux" onclick="magFluxToggle(this)" style="margin-bottom:10px">
|
||||
<span class="tri-dot" style="background:#34d399;box-shadow:0 0 5px #34d399"></span>
|
||||
<span class="tri-layer-name">Индикатор потока</span>
|
||||
<span class="tri-layer-hint" style="color:#34d399">Φ = B·S</span>
|
||||
<span class="tri-toggle" id="ml-flux-toggle"></span>
|
||||
</label>
|
||||
|
||||
<!-- Presets -->
|
||||
<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" onclick="mSim && mSim.preset('single')">Один провод</button>
|
||||
<button class="proj-preset-chip" onclick="mSim && mSim.preset('parallel')">Параллельные <svg class="ic" viewBox="0 0 24 24"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg><svg class="ic" viewBox="0 0 24 24"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg></button>
|
||||
<button class="proj-preset-chip" onclick="mSim && mSim.preset('anti')">Антипараллельные <svg class="ic" viewBox="0 0 24 24"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg><svg class="ic" viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg></button>
|
||||
<button class="proj-preset-chip" onclick="mSim && mSim.preset('solenoid')">Соленоид</button>
|
||||
<button class="proj-preset-chip" onclick="mSim && mSim.preset('quadrupole')">Квадруполь</button>
|
||||
<button class="proj-preset-chip" onclick="mSim && mSim.preset('ring')">Кольцо</button>
|
||||
<button class="proj-preset-chip" onclick="mSim && mSim.preset('dipole')">Диполь</button>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div style="margin-top:auto;padding-top:6px;display:flex;flex-direction:column;gap:5px">
|
||||
<div class="tri-stats-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Провода •</div>
|
||||
<div class="tri-stat-v" id="ms-out" style="text-align:center;color:var(--cyan)">0</div>
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Провода ×</div>
|
||||
<div class="tri-stat-v" id="ms-in" style="text-align:center;color:var(--pink)">0</div>
|
||||
<div class="tri-stats-grid" style="grid-template-columns:auto 1fr">
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Зарядов</div>
|
||||
<div class="tri-stat-v" id="embar-charges" style="color:#EF476F">0</div>
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Проводов</div>
|
||||
<div class="tri-stat-v" id="embar-wires" style="color:var(--cyan)">0</div>
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Курсор |E|</div>
|
||||
<div class="tri-stat-v" id="embar-curE" style="color:rgba(255,255,255,0.6)">—</div>
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Курсор V</div>
|
||||
<div class="tri-stat-v" id="embar-curV" style="color:rgba(255,255,255,0.5)">—</div>
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Курсор |B|</div>
|
||||
<div class="tri-stat-v" id="embar-curB" style="color:var(--cyan)">—</div>
|
||||
</div>
|
||||
<div style="font-size:0.68rem;color:var(--text-3);text-align:center;line-height:1.6;margin-top:4px">
|
||||
Клик — добавить · ПКМ / 2×клик — удалить<br>
|
||||
Перетащи провод для перемещения
|
||||
Клик — добавить · ПКМ / 2×клик — удалить<br>
|
||||
Перетащи источник для перемещения
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.proj-panel -->
|
||||
|
||||
<div class="proj-canvas-outer">
|
||||
<canvas id="mag-canvas"></canvas>
|
||||
<canvas id="emfield-canvas" style="display:block;position:absolute;top:0;left:0;width:100%;height:100%;cursor:crosshair"></canvas>
|
||||
</div>
|
||||
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
|
||||
<div class="proj-stats-bar">
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Проводов</div>
|
||||
<div class="pstat-val" id="mbar-total">0</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">• Ток на нас</div>
|
||||
<div class="pstat-val" id="mbar-out" style="color:var(--cyan)">0</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">× Ток от нас</div>
|
||||
<div class="pstat-val" id="mbar-in" style="color:var(--pink)">0</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Ток I</div>
|
||||
<div class="pstat-val" id="mbar-I">6 А</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Частица</div>
|
||||
<div class="pstat-val" id="mbar-particle">выкл</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Сила Ампера</div>
|
||||
<div class="pstat-val" id="mbar-ampere" style="color:#fbbf24">—</div>
|
||||
</div>
|
||||
<div class="pstat">
|
||||
<div class="pstat-label">Поток Φ</div>
|
||||
<div class="pstat-val" id="mbar-flux" style="color:#34d399">—</div>
|
||||
</div>
|
||||
<div class="pstat"><div class="pstat-label">Зарядов</div><div class="pstat-val" id="embar-charges-bar" style="color:#EF476F">0</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Проводов</div><div class="pstat-val" id="embar-wires-bar" style="color:var(--cyan)">0</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Частица</div><div class="pstat-val" id="embar-particle">выкл</div></div>
|
||||
<div class="pstat"><div class="pstat-label">|E| курсора</div><div class="pstat-val" id="embar-curE-bar" style="color:#EF476F">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">|B| курсора</div><div class="pstat-val" id="embar-curB-bar" style="color:var(--cyan)">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Сила Ампера</div><div class="pstat-val" id="embar-ampere" style="color:#fbbf24">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">Поток Φ</div><div class="pstat-val" id="embar-flux" style="color:#34d399">—</div></div>
|
||||
</div>
|
||||
</div><!-- /#sim-mag -->
|
||||
</div><!-- /#sim-emfield -->
|
||||
|
||||
<!-- ── TRIANGLE sim body ── -->
|
||||
<div id="sim-tri" class="sim-proj-wrap" style="display:none">
|
||||
@@ -1045,94 +1088,7 @@
|
||||
<!-- ══════════════════════════════════════════════
|
||||
ЗАКОН КУЛОНА
|
||||
══════════════════════════════════════════════ -->
|
||||
<div id="sim-coulomb" class="sim-proj-wrap" style="display:none">
|
||||
<div class="sim-body-wrap">
|
||||
|
||||
<div class="proj-panel" style="width:240px;gap:0">
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Знак заряда</div>
|
||||
<div style="display:flex;gap:6px;margin-bottom:12px">
|
||||
<button class="mag-mode-btn active" id="cbtn-pos" onclick="coulombSign(1)" style="flex:1" title="Добавить положительный заряд">
|
||||
<span style="font-size:1.3rem;font-weight:900;color:#EF476F">+</span> Положит.
|
||||
</button>
|
||||
<button class="mag-mode-btn" id="cbtn-neg" onclick="coulombSign(-1)" style="flex:1" title="Добавить отрицательный заряд">
|
||||
<span style="font-size:1.3rem;font-weight:900;color:#4CC9F0">−</span> Отрицат.
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="gp-section-title" style="margin-bottom:8px">Слои</div>
|
||||
<div style="display:flex;flex-direction:column;gap:5px;margin-bottom:10px">
|
||||
<label class="tri-layer-row active" id="cl-colormap" onclick="coulombLayer('colormap',this)">
|
||||
<span class="tri-dot" style="background:var(--violet);box-shadow:0 0 5px var(--violet)"></span>
|
||||
<span class="tri-layer-name">Карта потенциала</span>
|
||||
<span class="tri-layer-hint" style="color:var(--violet)">V</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row active" id="cl-fieldlines" onclick="coulombLayer('fieldlines',this)">
|
||||
<span class="tri-dot" style="background:rgba(255,255,255,0.8);box-shadow:0 0 5px rgba(255,255,255,0.6)"></span>
|
||||
<span class="tri-layer-name">Линии поля</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,0.5)">E</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row" id="cl-vectors" onclick="coulombLayer('vectors',this)">
|
||||
<span class="tri-dot" style="background:rgba(255,255,255,0.4)"></span>
|
||||
<span class="tri-layer-name">Векторы E</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,0.3)"><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></span>
|
||||
<span class="tri-toggle"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:2px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row active" id="cl-equipotentials" onclick="coulombLayer('equipotentials',this)">
|
||||
<span class="tri-dot" style="background:rgba(255,255,255,0.5)"></span>
|
||||
<span class="tri-layer-name">Эквипотенциали</span>
|
||||
<span class="tri-layer-hint" style="color:rgba(255,255,255,0.3)">V=const</span>
|
||||
<span class="tri-toggle" style="background:var(--violet)"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:14px"></span></span>
|
||||
</label>
|
||||
<label class="tri-layer-row" id="cl-forces" onclick="coulombLayer('forces',this)">
|
||||
<span class="tri-dot" style="background:#FFD166;box-shadow:0 0 5px #FFD166"></span>
|
||||
<span class="tri-layer-name">Силы Кулона</span>
|
||||
<span class="tri-layer-hint" style="color:#FFD166">F</span>
|
||||
<span class="tri-toggle"><span style="display:block;width:12px;height:12px;border-radius:50%;background:#fff;margin:2px;margin-left:2px"></span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<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" onclick="coulombPreset('dipole')">Диполь ±</button>
|
||||
<button class="proj-preset-chip" onclick="coulombPreset('equal')">Два + заряда</button>
|
||||
<button class="proj-preset-chip" onclick="coulombPreset('quadrupole')">Квадруполь</button>
|
||||
<button class="proj-preset-chip" onclick="coulombPreset('ring')">Кольцо</button>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:auto;display:flex;flex-direction:column;gap:5px">
|
||||
<div class="tri-stats-grid" style="grid-template-columns:auto 1fr">
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Зарядов</div>
|
||||
<div class="tri-stat-v" id="cs-total" style="color:var(--violet)">0</div>
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Курсор E</div>
|
||||
<div class="tri-stat-v" id="cs-curE" style="color:rgba(255,255,255,0.6)">—</div>
|
||||
<div style="font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3)">Курсор V</div>
|
||||
<div class="tri-stat-v" id="cs-curV" style="color:rgba(255,255,255,0.5)">—</div>
|
||||
</div>
|
||||
<div style="font-size:0.68rem;color:var(--text-3);text-align:center;line-height:1.6;margin-top:4px">
|
||||
Клик — добавить · ПКМ — удалить<br>
|
||||
Перетащи заряд для перемещения
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.proj-panel -->
|
||||
|
||||
<div class="proj-canvas-outer">
|
||||
<canvas id="coulomb-canvas" style="display:block;position:absolute;top:0;left:0;width:100%;height:100%;cursor:crosshair"></canvas>
|
||||
</div>
|
||||
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
|
||||
<div class="proj-stats-bar">
|
||||
<div class="pstat"><div class="pstat-label">Зарядов</div><div class="pstat-val" id="csbar-total">0</div></div>
|
||||
<div class="pstat"><div class="pstat-label">+ Позитивных</div><div class="pstat-val" id="csbar-pos" style="color:#EF476F">0</div></div>
|
||||
<div class="pstat"><div class="pstat-label">− Негативных</div><div class="pstat-val" id="csbar-neg" style="color:#4CC9F0">0</div></div>
|
||||
<div class="pstat"><div class="pstat-label">max |E|</div><div class="pstat-val" id="csbar-maxE">—</div></div>
|
||||
<div class="pstat"><div class="pstat-label">E курсора</div><div class="pstat-val" id="csbar-curE" style="color:rgba(255,255,255,0.7)">—</div></div>
|
||||
</div>
|
||||
</div><!-- /#sim-coulomb -->
|
||||
<!-- sim-coulomb removed: merged into sim-emfield -->
|
||||
|
||||
<!-- ══════════════════════════════════════════════
|
||||
ЭЛЕКТРИЧЕСКИЕ ЦЕПИ
|
||||
@@ -1310,7 +1266,7 @@
|
||||
|
||||
<div style="display:flex;gap:6px;margin-bottom:10px;margin-top:2px">
|
||||
<button class="proj-preset-chip" style="flex:1;background:rgba(239,71,111,0.18);border-color:rgba(239,71,111,0.4)"
|
||||
onclick="flaskSim && flaskSim.dropMetal()">⬇ Бросить металл</button>
|
||||
onclick="flaskSim && flaskSim.dropMetal()"><svg class="ic" viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg> Бросить металл</button>
|
||||
<button class="proj-preset-chip" id="flask-flame-panel" style="flex:0 0 auto"
|
||||
onclick="flaskToggleFlame()"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display:inline-block;vertical-align:middle"><path d="M12 2c.5 3.5-1.5 6-1.5 6 1 1.5 3 2 3 5a4 4 0 01-8 0c0-2 .5-3 1.5-4.5C8.5 6.5 7 4.5 7 4.5S9.5 2 12 2z"/></svg></button>
|
||||
</div>
|
||||
@@ -1454,7 +1410,7 @@
|
||||
<button class="mag-mode-btn sb-panel-tool" id="sbpt-erase" onclick="sbTool('erase',this)" style="flex:1;font-size:.72rem"><svg class="ic" viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>
|
||||
</div>
|
||||
<div style="display:flex;gap:5px;margin-bottom:10px">
|
||||
<button class="mag-mode-btn sb-panel-tool" id="sbpt-spring" onclick="sbTool('spring',this)" style="flex:1;font-size:.72rem">〜 Пружина</button>
|
||||
<button class="mag-mode-btn sb-panel-tool" id="sbpt-spring" onclick="sbTool('spring',this)" style="flex:1;font-size:.72rem"><svg class="ic" viewBox="0 0 24 24" fill="none"><path d="M3 12 L6 8 L9 16 L12 8 L15 16 L18 8 L21 12"/></svg> Пружина</button>
|
||||
<button class="mag-mode-btn sb-panel-tool" id="sbpt-rope" onclick="sbTool('rope',this)" style="flex:1;font-size:.72rem">— Нить</button>
|
||||
<button class="mag-mode-btn sb-panel-tool" id="sbpt-anchor" onclick="sbTool('anchor',this)" style="flex:1;font-size:.72rem"><svg class="ic" viewBox="0 0 24 24"><path d="M12 2 2 12 12 22 22 12Z"/></svg> Якорь</button>
|
||||
</div>
|
||||
@@ -1529,17 +1485,17 @@
|
||||
<button class="proj-preset-chip" onclick="sbPreset('ramp_slide')">Горка</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('ramp_angle')"><svg class="ic" viewBox="0 0 24 24"><path d="m8 3 4 8 5-5 5 15H2L8 3z"/></svg> Крутой спуск</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('ramp_friction')"><svg class="ic" viewBox="0 0 24 24"><rect width="20" height="5" x="2" y="3" rx="1"/><rect width="8" height="5" x="2" y="11" rx="1"/><rect width="8" height="5" x="14" y="11" rx="1"/><rect width="20" height="5" x="2" y="19" rx="1"/></svg> Трение на горке</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('spring_bounce')">〜 Пружина</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('spring_chain')">〜 Цепочка</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('spring_bounce')"><svg class="ic" viewBox="0 0 24 24" fill="none"><path d="M3 12 L6 8 L9 16 L12 8 L15 16 L18 8 L21 12"/></svg> Пружина</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('spring_chain')"><svg class="ic" viewBox="0 0 24 24" fill="none"><path d="M3 12 L6 8 L9 16 L12 8 L15 16 L18 8 L21 12"/></svg> Цепочка</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('pendulum')">⬤ Маятник</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('atwood')"><svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93 17.66 6.34M21 12h-2M19.07 19.07l-1.41-1.41M12 21v-2M6.34 17.66 4.93 19.07M3 12h2M4.93 4.93l1.41 1.41M12 3v2"/><circle cx="12" cy="12" r="7"/></svg> Машина Атвуда</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('two_body')"><svg class="ic" viewBox="0 0 24 24"><line x1="12" y1="21" x2="12" y2="3"/><polyline points="7 8 12 3 17 8"/><polyline points="17 16 12 21 7 16"/></svg> Два тела</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('elastic_collision')"><svg class="ic" viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg> Упругий удар</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('inelastic_collision')"><svg class="ic" viewBox="0 0 24 24"><path d="m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3z"/></svg> Неупругий</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('newton_cradle')"><svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93 17.66 6.34M21 12h-2M19.07 19.07l-1.41-1.41M12 21v-2M6.34 17.66 4.93 19.07M3 12h2M4.93 4.93l1.41 1.41M12 3v2"/><circle cx="12" cy="12" r="7"/></svg> Колыбель Ньютона</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('harmonic_oscillator')">〜 Осциллятор</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('harmonic_oscillator')"><svg class="ic" viewBox="0 0 24 24" fill="none"><path d="M3 12 L6 8 L9 16 L12 8 L15 16 L18 8 L21 12"/></svg> Осциллятор</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('double_pendulum')">⬤⬤ Двойной маятник</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('coupled_oscillators')">〜〜 Связанные</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('coupled_oscillators')"><svg class="ic" viewBox="0 0 24 24" fill="none"><path d="M3 12 L6 8 L9 16 L12 8 L15 16 L18 8 L21 12"/></svg> Связанные</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('stacked_boxes')"><svg class="ic" viewBox="0 0 24 24"><rect width="20" height="5" x="2" y="3" rx="1"/><rect width="8" height="5" x="2" y="11" rx="1"/><rect width="8" height="5" x="14" y="11" rx="1"/><rect width="20" height="5" x="2" y="19" rx="1"/></svg> Стопка</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('pulley_ramp')"><svg class="ic" viewBox="0 0 24 24"><path d="m8 3 4 8 5-5 5 15H2L8 3z"/></svg> Горка+блок</button>
|
||||
<button class="proj-preset-chip" onclick="sbPreset('circular_motion')">⭕ Круговое</button>
|
||||
@@ -1578,7 +1534,7 @@
|
||||
<div class="sim-body-wrap">
|
||||
|
||||
<!-- controls panel -->
|
||||
<div class="proj-panel">
|
||||
<div class="proj-panel" style="width:240px">
|
||||
<div class="gp-section-title">Параметры</div>
|
||||
|
||||
<div class="param-block">
|
||||
@@ -1694,6 +1650,58 @@
|
||||
</div>
|
||||
<div style="font-size:.6rem;color:var(--text-3);margin-top:4px">Сохрани траекторию, измени параметры и сравни</div>
|
||||
|
||||
<!-- Feature 1: Target mode -->
|
||||
<div class="gp-section-title" style="margin-top:10px">Режим целей</div>
|
||||
<button id="proj-target-btn" class="proj-preset-chip" onclick="projToggleTargetMode()" style="width:100%;text-align:left;display:flex;align-items:center;gap:6px">
|
||||
<svg class="ic" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>
|
||||
<span>Режим целей: Выкл</span>
|
||||
</button>
|
||||
<div id="proj-target-panel" style="display:none;margin-top:6px">
|
||||
<button class="proj-preset-chip" onclick="projGenTargets()" style="width:100%;text-align:center">
|
||||
<svg class="ic" viewBox="0 0 24 24"><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 id="proj-target-hud" style="font-size:.72rem;font-weight:700;color:#FFD166;margin-top:6px;text-align:center">Цели: 0/3 Попыток: 0</div>
|
||||
</div>
|
||||
|
||||
<!-- Feature 2: Graphs toggle -->
|
||||
<div class="gp-section-title" style="margin-top:10px">Графики</div>
|
||||
<button id="proj-graphs-btn" class="proj-preset-chip" onclick="projToggleGraphs()" style="width:100%;text-align:left;display:flex;align-items:center;gap:6px">
|
||||
<svg class="ic" viewBox="0 0 24 24"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
|
||||
<span>x(t), y(t), vx(t), vy(t)</span>
|
||||
</button>
|
||||
|
||||
<!-- Feature 3: Dual throw -->
|
||||
<div class="gp-section-title" style="margin-top:10px">Двойной бросок</div>
|
||||
<button id="proj-dual-btn" class="proj-preset-chip" onclick="projToggleDual()" style="width:100%;text-align:left;display:flex;align-items:center;gap:6px">
|
||||
<svg class="ic" viewBox="0 0 24 24"><circle cx="8" cy="18" r="3"/><circle cx="18" cy="6" r="3"/><path d="M8 15V9l10-6"/></svg>
|
||||
<span>Двойной: Выкл</span>
|
||||
</button>
|
||||
<div id="proj-dual-panel" style="display:none;margin-top:6px">
|
||||
<div style="font-size:.65rem;color:rgba(0,230,255,.8);font-weight:700;margin-bottom:4px">Тело 2 (cyan)</div>
|
||||
<div class="param-block">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Скорость v₀₂</span>
|
||||
<span class="param-val" id="p2-v0" style="color:#00E6FF">25 м/с</span>
|
||||
</div>
|
||||
<input type="range" class="param-slider proj-dual-slider" id="sl-p2-v0" min="1" max="100" value="25" oninput="projP2Param()">
|
||||
</div>
|
||||
<div class="param-block">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Угол θ₂</span>
|
||||
<span class="param-val" id="p2-angle" style="color:#00E6FF">30°</span>
|
||||
</div>
|
||||
<input type="range" class="param-slider proj-dual-slider" id="sl-p2-angle" min="0" max="90" value="30" oninput="projP2Param()">
|
||||
</div>
|
||||
<div class="param-block">
|
||||
<div class="param-header">
|
||||
<span class="param-name">Высота h₀₂</span>
|
||||
<span class="param-val" id="p2-h0" style="color:#00E6FF">0 м</span>
|
||||
</div>
|
||||
<input type="range" class="param-slider proj-dual-slider" id="sl-p2-h0" min="0" max="50" value="0" oninput="projP2Param()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LAUNCH BUTTON -->
|
||||
<div style="margin-top:auto; padding-top:16px; display:flex; flex-direction:column; gap:8px;">
|
||||
<button class="proj-launch-btn" id="proj-launch-main" onclick="projPlayPause()">
|
||||
@@ -1718,6 +1726,11 @@
|
||||
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
|
||||
<!-- graphs panel (Feature 2) -->
|
||||
<div id="proj-graphs-panel" style="display:none;background:#05050e;border-top:1px solid rgba(255,255,255,.07)">
|
||||
<canvas id="proj-graphs-canvas" class="proj-graphs-canvas"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- stats bar -->
|
||||
<div class="proj-stats-bar">
|
||||
<div class="pstat">
|
||||
@@ -1748,6 +1761,15 @@
|
||||
<div class="pstat-label">Δ дальность</div>
|
||||
<div class="pstat-val" id="ps-loss">—</div>
|
||||
</div>
|
||||
<!-- dual throw stats (Feature 3) -->
|
||||
<div class="pstat" id="ps-p2-wrap" style="display:none">
|
||||
<div class="pstat-label" style="color:rgba(0,230,255,.7)">Дальн. 2</div>
|
||||
<div class="pstat-val" id="ps-p2-range" style="color:#00E6FF">—</div>
|
||||
</div>
|
||||
<div class="pstat" id="ps-p2-tf-wrap" style="display:none">
|
||||
<div class="pstat-label" style="color:rgba(0,230,255,.7)">Время 2</div>
|
||||
<div class="pstat-val" id="ps-p2-tf" style="color:#00E6FF">—</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /#sim-proj -->
|
||||
|
||||
@@ -1756,7 +1778,7 @@
|
||||
<div class="sim-body-wrap">
|
||||
|
||||
<!-- controls panel -->
|
||||
<div class="proj-panel">
|
||||
<div class="proj-panel" style="width:240px">
|
||||
<div class="gp-section-title">Параметры</div>
|
||||
|
||||
<div class="param-block">
|
||||
@@ -2415,7 +2437,7 @@
|
||||
<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>
|
||||
<label style="display:flex;align-items:center;gap:4px;font-size:.72rem;color:#ccc;cursor:pointer;grid-column:span 2"><input type="checkbox" id="mtog-point" onchange="mirrorSetPointMode(this.checked)"> Точечный объект</label>
|
||||
</div>
|
||||
<button onclick="if(mirrorSim)mirrorSim.exportPng()" style="width:100%;padding:5px 0;border-radius:6px;border:1px solid #333;background:#1a1a2e;color:#888;font-size:.72rem;cursor:pointer;margin-bottom:8px">📷 Экспорт PNG</button>
|
||||
<button onclick="if(mirrorSim)mirrorSim.exportPng()" style="width:100%;padding:5px 0;border-radius:6px;border:1px solid #333;background:#1a1a2e;color:#888;font-size:.72rem;cursor:pointer;margin-bottom:8px"><svg class="ic" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> Экспорт PNG</button>
|
||||
<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="mirrorPreset('flat')">Плоское</button>
|
||||
@@ -3245,11 +3267,11 @@
|
||||
</button>
|
||||
<button id="geo-btn-circumcircle" class="geo-tool-btn geo-tool-wide" onclick="geoSetTool('circumcircle',this)" title="Описанная окружность — 3 точки треугольника">
|
||||
<svg viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke-width="1.5" stroke-dasharray="4,3"/><polygon points="6,18 18,18 12,6" stroke-width="1.5" fill="none"/></svg>
|
||||
Описанная ☉
|
||||
Описанная
|
||||
</button>
|
||||
<button id="geo-btn-incircle" class="geo-tool-btn geo-tool-wide" onclick="geoSetTool('incircle',this)" title="Вписанная окружность — 3 точки треугольника">
|
||||
<svg viewBox="0 0 24 24" fill="none"><polygon points="4,20 20,20 12,4" stroke-width="1.5" fill="none"/><circle cx="12" cy="15" r="5" stroke-width="1.5" stroke-dasharray="4,3"/></svg>
|
||||
Вписанная ○
|
||||
Вписанная
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -3362,6 +3384,40 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Constrained points for locus -->
|
||||
<div class="gp-section-title" style="margin-top:4px">Точки на объектах</div>
|
||||
<div class="geo-tool-grid">
|
||||
<button id="geo-btn-point_on_segment" class="geo-tool-btn" onclick="geoSetTool('point_on_segment',this)" title="Точка на отрезке — кликни на отрезок, получишь скользящую точку">
|
||||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="20" x2="21" y2="4"/><circle cx="12" cy="12" r="3" fill="currentColor" stroke="none"/></svg>
|
||||
На отрезке
|
||||
</button>
|
||||
<button id="geo-btn-point_on_circle" class="geo-tool-btn" onclick="geoSetTool('point_on_circle',this)" title="Точка на окружности — кликни на окружность, получишь скользящую точку">
|
||||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="3" r="2.5" fill="currentColor" stroke="none"/></svg>
|
||||
На окружности
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Measurement + Locus tools -->
|
||||
<div class="gp-section-title" style="margin-top:4px">Измерения и ГМТ</div>
|
||||
<div class="geo-tool-grid">
|
||||
<button id="geo-btn-measure_length" class="geo-tool-btn" onclick="geoSetTool('measure_length',this)" title="Длина отрезка — кликни на отрезок, получишь живой чип">
|
||||
<svg viewBox="0 0 24 24" fill="none"><line x1="3" y1="12" x2="21" y2="12" stroke-width="2"/><line x1="3" y1="8" x2="3" y2="16" stroke-width="2" stroke-linecap="round"/><line x1="21" y1="8" x2="21" y2="16" stroke-width="2" stroke-linecap="round"/></svg>
|
||||
Длина
|
||||
</button>
|
||||
<button id="geo-btn-measure_angle" class="geo-tool-btn" onclick="geoSetTool('measure_angle',this)" title="Угол — 3 клика: точка A, вершина, точка B">
|
||||
<svg viewBox="0 0 24 24" fill="none"><path d="M3 20 L20 20" stroke-width="2" stroke-linecap="round"/><path d="M3 20 L14 6" stroke-width="2" stroke-linecap="round"/><path d="M7 20 A10 10 0 0 1 11.5 12" stroke-width="1.5" fill="none"/></svg>
|
||||
Угол
|
||||
</button>
|
||||
<button id="geo-btn-measure_area" class="geo-tool-btn" onclick="geoSetTool('measure_area',this)" title="Площадь многоугольника — кликни на полигон">
|
||||
<svg viewBox="0 0 24 24" fill="none"><polygon points="12,3 21,9 18,20 6,20 3,9" stroke-width="2" fill="none"/></svg>
|
||||
Площадь
|
||||
</button>
|
||||
<button id="geo-btn-locus" class="geo-tool-btn" onclick="geoSetTool('locus',this)" title="ГМТ — выбери точку-мовер (on_segment/on_circle), затем целевую точку">
|
||||
<svg viewBox="0 0 24 24" fill="none"><path d="M4 20 Q8 4 12 12 Q16 20 20 6" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/><circle cx="8" cy="14" r="2" fill="currentColor"/></svg>
|
||||
ГМТ
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Display options -->
|
||||
<div class="gp-section-title" style="margin-top:6px">Параметры</div>
|
||||
<label class="geo-toggle-row" onclick="geoToggle('showGrid',this)">
|
||||
@@ -3449,7 +3505,7 @@
|
||||
<script src="/js/sidebar.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/three@0.149.0/build/three.min.js"></script>
|
||||
<script src="/js/labs/graph.js"></script>
|
||||
<script src="/js/labs/magnetic.js"></script>
|
||||
<script src="/js/labs/emfield.js"></script>
|
||||
<script src="/js/labs/triangle.js"></script>
|
||||
<script src="/js/labs/projectile.js"></script>
|
||||
<script src="/js/labs/collision.js"></script>
|
||||
@@ -3457,7 +3513,7 @@
|
||||
<script src="/js/labs/states.js"></script>
|
||||
<script src="/js/labs/brownian.js"></script>
|
||||
<script src="/js/labs/diffusion.js"></script>
|
||||
<script src="/js/labs/coulomb.js"></script>
|
||||
<!-- coulomb.js removed: merged into emfield.js -->
|
||||
<script src="/js/labs/circuit.js"></script>
|
||||
<script src="/js/labs/reactions.js"></script>
|
||||
<script src="/js/labs/flask.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user