feat(phys10 ch1 wave4): §7 «Твёрдые тела» + §8 «Жидкости»
This commit is contained in:
@@ -2803,34 +2803,784 @@ function build_p6(){
|
||||
function build_p7(){
|
||||
const box = document.getElementById('p7-body');
|
||||
let html = '';
|
||||
html += makeCard('theory', "Строение и свойства твёрдых тел", "§7", `
|
||||
<p><b>Строение и свойства твёрдых тел</b> — этот параграф в разработке (Phase 1+).</p>
|
||||
<p>Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.92rem">
|
||||
<b>Phase 0:</b> создан скелет учебника. <b>Phase 1+:</b> наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
|
||||
</p>
|
||||
|
||||
/* THEORY 1 — Кристаллические и аморфные тела */
|
||||
html += makeCard('theory', "Кристаллические и аморфные тела", "§7", `
|
||||
<p><b>Кристаллические тела</b> имеют упорядоченное расположение частиц — <b>кристаллическую решётку</b>.</p>
|
||||
<p style="margin-top:8px">Виды кристаллических тел:</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li><b>Монокристалл</b> — единая решётка во всём объёме (кварц, алмаз, поваренная соль, сахар).</li>
|
||||
<li><b>Поликристалл</b> — много мелких кристалликов, ориентированных хаотически (металлы, лёд, керамика).</li>
|
||||
</ul>
|
||||
<p>У кристаллических тел есть <b>точная температура плавления</b>: при $t_{\\text{пл}}$ решётка разрушается, и тело переходит в жидкое состояние.</p>
|
||||
<p style="margin-top:10px"><b>Аморфные тела</b> (стекло, смола, пластмассы, янтарь, воск) не имеют упорядоченной решётки. Их называют «переохлаждёнными жидкостями». При нагревании они <b>размягчаются плавно</b>, без чёткой температуры плавления.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 2 — Анизотропия и изотропия */
|
||||
html += makeCard('rule', "Анизотропия и изотропия", "§7", `
|
||||
<p><b>Анизотропия</b> — зависимость физических свойств от направления (твёрдость, теплопроводность, скорость распространения света). <b>Характерна для монокристаллов.</b></p>
|
||||
<p style="margin-top:8px">Примеры:</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li>Алмаз в одном направлении режется легче, чем в другом.</li>
|
||||
<li>Графит легко расщепляется на тонкие чешуйки (вдоль слоёв).</li>
|
||||
<li>В кварце скорость звука зависит от оси кристалла.</li>
|
||||
</ul>
|
||||
<p><b>Изотропия</b> — свойства одинаковы во всех направлениях. <b>Характерна для поликристаллов и аморфных тел.</b></p>
|
||||
<p style="margin-top:8px">Поликристаллы состоят из множества мелких разно ориентированных кристалликов, поэтому в среднем свойства одинаковы по всем направлениям.</p>
|
||||
`);
|
||||
|
||||
/* THEORY 3 — Типы кристаллических решёток */
|
||||
html += makeCard('example', "Типы кристаллических решёток", "§7", `
|
||||
<p>По типу связи частиц различают четыре основных типа решёток:</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.85">
|
||||
<li><b style="color:#e11d48">Ионная</b> (NaCl, KCl, CaF$_2$): чередование «+» и «−» ионов. Очень прочные, твёрдые, высокая $t_{\\text{пл}}$.</li>
|
||||
<li><b style="color:#475569">Атомная</b> (алмаз, графит, кремний, германий): атомы связаны ковалентными связями. Очень твёрдые, тугоплавкие.</li>
|
||||
<li><b style="color:#0ea5e9">Молекулярная</b> (лёд, нафталин, парафин, сахар, йод): связи между молекулами слабые. Мягкие, легкоплавкие.</li>
|
||||
<li><b style="color:#f59e0b">Металлическая</b> (медь, железо, алюминий): положительные ионы в «море» свободных электронов. Пластичные, хорошо проводят ток и тепло.</li>
|
||||
</ul>
|
||||
<p style="margin-top:8px">Один и тот же элемент может образовывать разные решётки: <b>алмаз</b> (атомная решётка, очень твёрдый) и <b>графит</b> (слоистая, мягкий) — оба состоят из углерода.</p>
|
||||
`);
|
||||
|
||||
/* INTERACTIVE 1 — Визуализатор кристаллической решётки */
|
||||
html += `<div class="wg" id="p7-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Визуализатор кристаллической решётки</div></div>
|
||||
<div class="wg-help">Переключай тип решётки и наблюдай расположение частиц. Просмотри все 4 типа.</div>
|
||||
<div style="display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-bottom:10px" id="p7-iv1-tabs">
|
||||
<button class="btn primary" data-mode="ion" style="background:#e11d48;border-color:#e11d48">Ионная</button>
|
||||
<button class="btn" data-mode="atom">Атомная</button>
|
||||
<button class="btn" data-mode="mol">Молекулярная</button>
|
||||
<button class="btn" data-mode="met">Металлическая</button>
|
||||
</div>
|
||||
<div style="background:var(--card);border:1px solid var(--border);border-radius:10px;padding:10px;display:flex;justify-content:center">
|
||||
<svg id="p7-iv1-svg" viewBox="0 0 380 280" width="100%" style="max-width:520px;height:auto"></svg>
|
||||
</div>
|
||||
<div style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.94rem;line-height:1.75" id="p7-iv1-info"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Кристалл или аморфное (DnD) */
|
||||
html += `<div class="wg" id="p7-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Кристалл или аморфное?</div></div>
|
||||
<div class="wg-help">Перетащи 8 веществ в нужный ящик.</div>
|
||||
<div class="dnd-hint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 11V6a3 3 0 0 1 6 0v5"/><path d="M9 11h6v8a4 4 0 0 1-8 0z"/></svg> 8 веществ — 2 группы</div>
|
||||
<div id="p7-iv2-pool"></div>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;margin-top:8px">
|
||||
<div class="drop-box"><h5 data-cat="cryst" style="color:#2563eb">Кристаллическое</h5><div class="drop-items" data-cat="cryst"></div></div>
|
||||
<div class="drop-box"><h5 data-cat="amorph" style="color:#10b981">Аморфное</h5><div class="drop-items" data-cat="amorph"></div></div>
|
||||
</div>
|
||||
<div class="actions"><button class="btn primary" id="p7-iv2-check">Проверить</button><button class="btn" id="p7-iv2-reset">Сначала</button></div>
|
||||
<div class="feedback" id="p7-iv2-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — квикфайр: свойство → тип решётки */
|
||||
html += `<div class="wg" id="p7-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Какой тип решётки?</div></div>
|
||||
<div class="wg-help">6 веществ. Жми кнопку с типом решётки.</div>
|
||||
<div class="score-display"><span>Задача <b id="p7-iv3-i">1</b> / 6</span><span>Очки: <b id="p7-iv3-s">0</b> / 6</span></div>
|
||||
<div id="p7-iv3-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div id="p7-iv3-opts" style="display:grid;grid-template-columns:1fr 1fr;gap:8px"></div>
|
||||
<div class="feedback" id="p7-iv3-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p7-iv3-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — тренажёр свойств твёрдых тел */
|
||||
html += `<div class="wg" id="p7-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр свойств твёрдых тел</div></div>
|
||||
<div class="wg-help">5 задач. Допуск для чисел $\\pm 5\\%$.</div>
|
||||
<div class="score-display"><span>Задача <b id="p7-iv4-i">1</b> / 5</span><span>Очки: <b id="p7-iv4-s">0</b> / 5</span></div>
|
||||
<div id="p7-iv4-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">ответ =</span>
|
||||
<input type="number" id="p7-iv4-ans" class="tinp" style="width:130px;text-align:center" step="any">
|
||||
<button class="btn primary" id="p7-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p7-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p7-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p6', 'p8');
|
||||
html += readButton('p7');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Визуализатор решётки */
|
||||
(function(){
|
||||
const tabs = document.getElementById('p7-iv1-tabs');
|
||||
const svg = document.getElementById('p7-iv1-svg');
|
||||
const info = document.getElementById('p7-iv1-info');
|
||||
const seen = new Set();
|
||||
let _done = false;
|
||||
let mode = 'ion';
|
||||
|
||||
function drawIon(){
|
||||
// 5×5 сетка чередующихся Na+/Cl−
|
||||
let g = '<rect x="0" y="0" width="380" height="280" fill="#fafafa"/>';
|
||||
const cols = 6, rows = 5, sx = 50, sy = 30, dx = 56, dy = 48;
|
||||
for(let j = 0; j < rows; j++){
|
||||
for(let i = 0; i < cols; i++){
|
||||
const cx = sx + i * dx, cy = sy + j * dy;
|
||||
const isPlus = ((i + j) % 2 === 0);
|
||||
// соединительные линии (соседи справа/снизу)
|
||||
if(i < cols-1) g += '<line x1="'+cx+'" y1="'+cy+'" x2="'+(cx+dx)+'" y2="'+cy+'" stroke="#94a3b8" stroke-width="1" stroke-dasharray="3 3"/>';
|
||||
if(j < rows-1) g += '<line x1="'+cx+'" y1="'+cy+'" x2="'+cx+'" y2="'+(cy+dy)+'" stroke="#94a3b8" stroke-width="1" stroke-dasharray="3 3"/>';
|
||||
}
|
||||
}
|
||||
for(let j = 0; j < rows; j++){
|
||||
for(let i = 0; i < cols; i++){
|
||||
const cx = sx + i * dx, cy = sy + j * dy;
|
||||
const isPlus = ((i + j) % 2 === 0);
|
||||
const col = isPlus ? '#e11d48' : '#2563eb';
|
||||
const r = isPlus ? 13 : 17;
|
||||
g += '<circle cx="'+cx+'" cy="'+cy+'" r="'+r+'" fill="'+col+'" stroke="#0f172a" stroke-width="1.2"/>';
|
||||
g += '<text x="'+cx+'" y="'+(cy+4)+'" text-anchor="middle" font-size="11" font-weight="700" fill="#fff">'+(isPlus?'Na⁺':'Cl⁻')+'</text>';
|
||||
}
|
||||
}
|
||||
svg.innerHTML = g;
|
||||
}
|
||||
|
||||
function drawAtom(){
|
||||
// Тетраэдрическая сетка алмаза — упрощённая 2D-проекция
|
||||
let g = '<rect x="0" y="0" width="380" height="280" fill="#fafafa"/>';
|
||||
const sx = 50, sy = 40, dx = 70, dy = 60;
|
||||
const nodes = [];
|
||||
for(let j = 0; j < 4; j++){
|
||||
for(let i = 0; i < 5; i++){
|
||||
const off = (j % 2) * dx / 2;
|
||||
nodes.push({x: sx + i*dx + off, y: sy + j*dy, i, j});
|
||||
}
|
||||
}
|
||||
// соединения — ковалентные связи (жирные линии к ближайшим)
|
||||
for(const a of nodes){
|
||||
for(const b of nodes){
|
||||
if(a === b) continue;
|
||||
const d = Math.hypot(a.x - b.x, a.y - b.y);
|
||||
if(d < dx * 1.05 && d > 0.1){
|
||||
g += '<line x1="'+a.x+'" y1="'+a.y+'" x2="'+b.x+'" y2="'+b.y+'" stroke="#475569" stroke-width="3" opacity="0.7"/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
for(const n of nodes){
|
||||
g += '<circle cx="'+n.x+'" cy="'+n.y+'" r="11" fill="#64748b" stroke="#0f172a" stroke-width="1.2"/>';
|
||||
g += '<text x="'+n.x+'" y="'+(n.y+4)+'" text-anchor="middle" font-size="10" font-weight="700" fill="#fff">C</text>';
|
||||
}
|
||||
svg.innerHTML = g;
|
||||
}
|
||||
|
||||
function drawMol(){
|
||||
// Молекулы H₂O в упорядоченной сетке + водородные связи (пунктир)
|
||||
let g = '<rect x="0" y="0" width="380" height="280" fill="#fafafa"/>';
|
||||
const cols = 4, rows = 3, sx = 60, sy = 50, dx = 90, dy = 80;
|
||||
const centers = [];
|
||||
for(let j = 0; j < rows; j++){
|
||||
for(let i = 0; i < cols; i++){
|
||||
centers.push({x: sx + i*dx, y: sy + j*dy});
|
||||
}
|
||||
}
|
||||
// водородные связи (пунктир) между соседями
|
||||
for(let i = 0; i < centers.length; i++){
|
||||
for(let k = i+1; k < centers.length; k++){
|
||||
const d = Math.hypot(centers[i].x - centers[k].x, centers[i].y - centers[k].y);
|
||||
if(d < dx * 1.05){
|
||||
g += '<line x1="'+centers[i].x+'" y1="'+centers[i].y+'" x2="'+centers[k].x+'" y2="'+centers[k].y+'" stroke="#94a3b8" stroke-width="1.5" stroke-dasharray="4 4"/>';
|
||||
}
|
||||
}
|
||||
}
|
||||
// молекулы H₂O: 1 кислород (синий) + 2 водорода (белые)
|
||||
for(const c of centers){
|
||||
const ox = c.x, oy = c.y;
|
||||
const ang1 = -Math.PI/2 - 0.5, ang2 = -Math.PI/2 + 0.5;
|
||||
const hr = 18;
|
||||
const h1x = ox + hr*Math.cos(ang1), h1y = oy + hr*Math.sin(ang1);
|
||||
const h2x = ox + hr*Math.cos(ang2), h2y = oy + hr*Math.sin(ang2);
|
||||
g += '<line x1="'+ox+'" y1="'+oy+'" x2="'+h1x+'" y2="'+h1y+'" stroke="#0f172a" stroke-width="2"/>';
|
||||
g += '<line x1="'+ox+'" y1="'+oy+'" x2="'+h2x+'" y2="'+h2y+'" stroke="#0f172a" stroke-width="2"/>';
|
||||
g += '<circle cx="'+ox+'" cy="'+oy+'" r="11" fill="#0ea5e9" stroke="#0f172a" stroke-width="1.2"/>';
|
||||
g += '<text x="'+ox+'" y="'+(oy+4)+'" text-anchor="middle" font-size="10" font-weight="700" fill="#fff">O</text>';
|
||||
g += '<circle cx="'+h1x+'" cy="'+h1y+'" r="7" fill="#fff" stroke="#0f172a" stroke-width="1"/>';
|
||||
g += '<text x="'+h1x+'" y="'+(h1y+3)+'" text-anchor="middle" font-size="9" font-weight="700" fill="#0f172a">H</text>';
|
||||
g += '<circle cx="'+h2x+'" cy="'+h2y+'" r="7" fill="#fff" stroke="#0f172a" stroke-width="1"/>';
|
||||
g += '<text x="'+h2x+'" y="'+(h2y+3)+'" text-anchor="middle" font-size="9" font-weight="700" fill="#0f172a">H</text>';
|
||||
}
|
||||
svg.innerHTML = g;
|
||||
}
|
||||
|
||||
function drawMet(){
|
||||
// Положительные ионы (большие синие круги) + свободные электроны (точки)
|
||||
let g = '<rect x="0" y="0" width="380" height="280" fill="#fafafa"/>';
|
||||
const cols = 5, rows = 4, sx = 50, sy = 40, dx = 70, dy = 60;
|
||||
// электронное «море» — фоновая дымка
|
||||
g += '<rect x="20" y="20" width="340" height="240" fill="#fde68a" opacity="0.3" rx="8"/>';
|
||||
// свободные электроны (50 хаотичных точек)
|
||||
for(let k = 0; k < 70; k++){
|
||||
const ex = 30 + Math.random() * 320;
|
||||
const ey = 30 + Math.random() * 220;
|
||||
g += '<circle cx="'+ex.toFixed(1)+'" cy="'+ey.toFixed(1)+'" r="2.5" fill="#e11d48" opacity="0.85"/>';
|
||||
g += '<text x="'+(ex+4).toFixed(1)+'" y="'+(ey+2).toFixed(1)+'" font-size="8" fill="#e11d48" font-weight="700">−</text>';
|
||||
}
|
||||
// положительные ионы
|
||||
for(let j = 0; j < rows; j++){
|
||||
for(let i = 0; i < cols; i++){
|
||||
const cx = sx + i*dx, cy = sy + j*dy;
|
||||
g += '<circle cx="'+cx+'" cy="'+cy+'" r="15" fill="#f59e0b" stroke="#0f172a" stroke-width="1.4"/>';
|
||||
g += '<text x="'+cx+'" y="'+(cy+4)+'" text-anchor="middle" font-size="11" font-weight="700" fill="#fff">+</text>';
|
||||
}
|
||||
}
|
||||
svg.innerHTML = g;
|
||||
}
|
||||
|
||||
const INFO = {
|
||||
ion: '<b style="color:#e11d48">Ионная решётка</b> (пример: NaCl, поваренная соль). Связь: электростатическая между «+» и «−» ионами. Свойства: твёрдые, $t_{\\text{пл}}$ высокая (≈ 800°C), хрупкие, в расплаве проводят ток.',
|
||||
atom: '<b style="color:#475569">Атомная решётка</b> (пример: алмаз, кремний). Связь: ковалентная между атомами. Свойства: очень твёрдые, тугоплавкие ($t_{\\text{пл}}$ > 1000°C), плохо проводят ток.',
|
||||
mol: '<b style="color:#0ea5e9">Молекулярная решётка</b> (пример: лёд H$_2$O, нафталин, йод). Связь: слабая (Ван-дер-Ваальса, водородные связи). Свойства: мягкие, легкоплавкие, не проводят ток.',
|
||||
met: '<b style="color:#f59e0b">Металлическая решётка</b> (пример: Cu, Fe, Al). «+» ионы в «море» свободных электронов. Свойства: пластичные, отлично проводят ток и тепло, имеют металлический блеск.'
|
||||
};
|
||||
|
||||
function render(){
|
||||
if(mode === 'ion') drawIon();
|
||||
else if(mode === 'atom') drawAtom();
|
||||
else if(mode === 'mol') drawMol();
|
||||
else drawMet();
|
||||
info.innerHTML = INFO[mode];
|
||||
renderMath(info);
|
||||
seen.add(mode);
|
||||
if(!_done && seen.size >= 4){ _done = true; addXp(10, 'p7-iv1'); bumpProgress('p7', 15); }
|
||||
}
|
||||
tabs.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
mode = b.dataset.mode;
|
||||
const colMap = { ion:'#e11d48', atom:'#475569', mol:'#0ea5e9', met:'#f59e0b' };
|
||||
tabs.querySelectorAll('button').forEach(x => { x.className = 'btn'; x.style.background=''; x.style.borderColor=''; });
|
||||
b.className = 'btn primary';
|
||||
b.style.background = colMap[mode]; b.style.borderColor = colMap[mode];
|
||||
render();
|
||||
});
|
||||
});
|
||||
render();
|
||||
})();
|
||||
|
||||
/* IV2 — DnD: кристалл/аморф */
|
||||
(function(){
|
||||
const items = [
|
||||
{ id:'s1', cat:'cryst', html:'Поваренная соль (NaCl)' },
|
||||
{ id:'s2', cat:'amorph', html:'Стекло' },
|
||||
{ id:'s3', cat:'cryst', html:'Алмаз' },
|
||||
{ id:'s4', cat:'amorph', html:'Янтарь' },
|
||||
{ id:'s5', cat:'cryst', html:'Лёд' },
|
||||
{ id:'s6', cat:'amorph', html:'Парафин' },
|
||||
{ id:'s7', cat:'cryst', html:'Железо' },
|
||||
{ id:'s8', cat:'amorph', html:'Резина' },
|
||||
];
|
||||
const sorter = setupSorter({
|
||||
poolId:'p7-iv2-pool',
|
||||
scopeSelector:'#p7-iv2',
|
||||
items: items,
|
||||
cats:['cryst','amorph'],
|
||||
columnLayout:false,
|
||||
});
|
||||
document.getElementById('p7-iv2-check').addEventListener('click', () => {
|
||||
const fb = document.getElementById('p7-iv2-fb');
|
||||
const placedCount = items.filter(it => sorter.placed[it.id]).length;
|
||||
const correct = items.filter(it => sorter.placed[it.id] === it.cat).length;
|
||||
if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 8 веществ.'); return; }
|
||||
if(correct === items.length){ feedback(fb, true, '✓ Все 8 верно! +10 XP'); addXp(10,'p7-iv2'); bumpProgress('p7', 15); }
|
||||
else feedback(fb, false, '✗ Правильно ' + correct + ' из 8. Попробуй ещё.');
|
||||
});
|
||||
document.getElementById('p7-iv2-reset').addEventListener('click', () => { sorter.reset(); document.getElementById('p7-iv2-fb').style.display = 'none'; });
|
||||
})();
|
||||
|
||||
/* IV3 — квикфайр: тип решётки */
|
||||
(function(){
|
||||
// ans: 0=ион, 1=атом, 2=мол, 3=метал
|
||||
const Q = [
|
||||
{ q:'NaCl — поваренная соль', ans:0, why:'Чередование Na⁺ и Cl⁻ — ионная решётка.' },
|
||||
{ q:'Алмаз', ans:1, why:'Атомы углерода связаны ковалентными связями — атомная решётка.' },
|
||||
{ q:'Лёд (H$_2$O в твёрдом состоянии)', ans:2, why:'Между молекулами H$_2$O слабые водородные связи — молекулярная решётка.' },
|
||||
{ q:'Медь, железо, алюминий', ans:3, why:'Положительные ионы в «море» свободных электронов — металлическая.' },
|
||||
{ q:'Кремний (полупроводник)', ans:1, why:'Атомная решётка (как у алмаза), ковалентные связи.' },
|
||||
{ q:'Йод (I$_2$)', ans:2, why:'Молекулы I$_2$ связаны слабыми силами — молекулярная.' },
|
||||
];
|
||||
const LABELS = ['Ионная','Атомная','Молекулярная','Металлическая'];
|
||||
const COLS = ['#e11d48','#475569','#0ea5e9','#f59e0b'];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p7-iv3-q');
|
||||
const oEl = document.getElementById('p7-iv3-opts');
|
||||
const fb = document.getElementById('p7-iv3-fb');
|
||||
const iEl = document.getElementById('p7-iv3-i');
|
||||
const sEl = document.getElementById('p7-iv3-s');
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
oEl.innerHTML = '';
|
||||
if(score === Q.length){ addXp(15, 'p7-iv3'); bumpProgress('p7', 25); }
|
||||
else if(score >= 4){ addXp(8, 'p7-iv3'); bumpProgress('p7', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1); sEl.textContent = score;
|
||||
qEl.innerHTML = Q[i].q;
|
||||
let opts = '';
|
||||
for(let k = 0; k < 4; k++){
|
||||
opts += '<button class="btn primary" data-v="'+k+'" style="background:'+COLS[k]+';border-color:'+COLS[k]+'">'+LABELS[k]+'</button>';
|
||||
}
|
||||
oEl.innerHTML = opts;
|
||||
fb.style.display = 'none';
|
||||
renderMath(qEl);
|
||||
oEl.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
const v = +b.dataset.v;
|
||||
if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! ' + Q[i].why + ' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Правильно: '+LABELS[Q[i].ans]+'. '+Q[i].why+' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
oEl.querySelectorAll('button').forEach(x => x.disabled = true);
|
||||
i++;
|
||||
setTimeout(show, 1700);
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p7-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр свойств твёрдых тел */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'В монокристалле скорость звука вдоль оси $X$ равна $5000$ м/с, вдоль $Y$ — $3000$ м/с. Найди разность в м/с (это пример анизотропии).', ans:2000, hint:'$5000 - 3000 = 2000$ м/с — разные направления, разные скорости.' },
|
||||
{ q:'Стекло — это кристаллическое (1) или аморфное (2) тело?', ans:2, hint:'Стекло не имеет упорядоченной решётки — это «переохлаждённая жидкость».' },
|
||||
{ q:'Алмаз и графит — оба состоят из углерода. У какого больше твёрдость? Введи: алмаз = 1, графит = 2.', ans:1, hint:'У алмаза 3D-решётка ковалентных связей — он твёрже. Графит — слоистый.' },
|
||||
{ q:'Сколько типов кристаллических решёток рассматривается в §7?', ans:4, hint:'Ионная, атомная, молекулярная, металлическая.' },
|
||||
{ q:'Какой тип решётки у меди? Введи цифру: 1 = ионная, 2 = атомная, 3 = молекулярная, 4 = металлическая.', ans:4, hint:'Cu — металл, значит решётка металлическая («+» ионы в «море» электронов).' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p7-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15, 'p7-iv4'); bumpProgress('p7', 25); }
|
||||
else if(score >= 3){ addXp(8, 'p7-iv4'); bumpProgress('p7', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p7-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p7-iv4-s').textContent = score;
|
||||
document.getElementById('p7-iv4-q').innerHTML = Q[i].q;
|
||||
document.getElementById('p7-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p7-iv4-q'));
|
||||
document.getElementById('p7-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p7-iv4-fb');
|
||||
const raw = document.getElementById('p7-iv4-ans').value.replace(',', '.');
|
||||
const ans = parseFloat(raw);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
|
||||
const tol = Math.max(0.05 * Math.abs(Q[i].ans), 0.5);
|
||||
if(Math.abs(ans - Q[i].ans) < tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶');
|
||||
document.getElementById('p7-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1800);
|
||||
}
|
||||
document.getElementById('p7-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p7-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
|
||||
document.getElementById('p7-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p7');
|
||||
}
|
||||
|
||||
function build_p8(){
|
||||
const box = document.getElementById('p8-body');
|
||||
let html = '';
|
||||
html += makeCard('theory', "Строение и свойства жидкостей", "§8", `
|
||||
<p><b>Строение и свойства жидкостей</b> — этот параграф в разработке (Phase 1+).</p>
|
||||
<p>Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.</p>
|
||||
<p style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.92rem">
|
||||
<b>Phase 0:</b> создан скелет учебника. <b>Phase 1+:</b> наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
|
||||
</p>
|
||||
|
||||
/* THEORY 1 — Свойства и строение жидкостей */
|
||||
html += makeCard('theory', "Свойства и строение жидкостей", "§8", `
|
||||
<p>Жидкости занимают <b>промежуточное положение</b> между газами и твёрдыми телами:</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li>От <b>твёрдых тел</b> жидкость унаследовала: <b>сохранение объёма</b> (несжимаемость).</li>
|
||||
<li>От <b>газов</b>: <b>отсутствие собственной формы</b> — жидкость принимает форму сосуда.</li>
|
||||
</ul>
|
||||
<p>Молекулы жидкости расположены тесно (как в твёрдом теле), но могут перемещаться (как в газе).</p>
|
||||
<p style="margin-top:8px"><b>Ближний порядок</b> — упорядоченность молекул в области порядка нескольких диаметров молекулы. На больших расстояниях упорядоченности нет (в отличие от кристалла).</p>
|
||||
<p style="margin-top:8px">При охлаждении жидкость может <b>кристаллизоваться</b> (вода → лёд) или, при особых условиях, остаться аморфной (стекло — переохлаждённая жидкость).</p>
|
||||
`);
|
||||
|
||||
/* THEORY 2 — Поверхностное натяжение */
|
||||
html += makeCard('rule', "Поверхностное натяжение", "§8", `
|
||||
<p>На поверхности жидкости молекулы испытывают силу, направленную <b>внутрь жидкости</b>. Это объясняется тем, что молекула в объёме окружена молекулами со всех сторон, а молекула на поверхности — только снизу и с боков.</p>
|
||||
<p style="margin-top:8px">В результате жидкость стремится <b>минимизировать площадь поверхности</b>. Поэтому маленькая капля принимает почти сферическую форму.</p>
|
||||
<p style="margin-top:10px"><b>Сила поверхностного натяжения</b> на границе пленки длиной $L$:</p>
|
||||
<p style="text-align:center;margin:10px 0">$$F = \\sigma L$$</p>
|
||||
<p>где $\\sigma$ — <b>коэффициент поверхностного натяжения</b> (Н/м).</p>
|
||||
<p style="margin-top:8px">Значения $\\sigma$ при $20°$C:</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.7">
|
||||
<li>вода: $\\sigma_{\\text{в}} \\approx 0{,}073$ Н/м;</li>
|
||||
<li>спирт: $\\sigma_{\\text{сп}} \\approx 0{,}022$ Н/м;</li>
|
||||
<li>ртуть: $\\sigma_{\\text{Hg}} \\approx 0{,}465$ Н/м.</li>
|
||||
</ul>
|
||||
`);
|
||||
|
||||
/* THEORY 3 — Смачивание и капиллярность */
|
||||
html += makeCard('example', "Смачивание и капиллярность", "§8", `
|
||||
<p>Когда жидкость соприкасается с твёрдой поверхностью, поверхность жидкости образует <b>краевой угол</b> $\\theta$ с твёрдым телом:</p>
|
||||
<ul style="margin:6px 0 8px 22px;line-height:1.75">
|
||||
<li>$\\theta < 90°$ — <b>смачивание</b> (вода на чистом стекле: $\\theta \\approx 0°$).</li>
|
||||
<li>$\\theta > 90°$ — <b>несмачивание</b> (ртуть на стекле: $\\theta \\approx 140°$).</li>
|
||||
</ul>
|
||||
<p><b>Капиллярные явления</b>: в тонкой трубке (капилляре) смачивающая жидкость <b>поднимается</b>, несмачивающая — <b>опускается</b> ниже общего уровня.</p>
|
||||
<p style="margin-top:8px">Высота поднятия в капилляре радиуса $r$:</p>
|
||||
<p style="text-align:center;margin:10px 0">$$h = \\dfrac{2 \\sigma \\cos\\theta}{\\rho g r}$$</p>
|
||||
<p>где $\\rho$ — плотность жидкости, $g$ — ускорение свободного падения.</p>
|
||||
<p style="margin-top:8px"><b>Пример.</b> Вода в капилляре $r = 1$ мм: $h = \\dfrac{2 \\cdot 0{,}073}{1000 \\cdot 10 \\cdot 10^{-3}} \\approx 0{,}015$ м $= 15$ мм.</p>
|
||||
<p style="margin-top:8px">Капиллярность важна в природе: вода поднимается по корням растений, по тонким сосудам в почве, по фитилю свечи.</p>
|
||||
`);
|
||||
|
||||
/* INTERACTIVE 1 — Симуляция жидкости */
|
||||
html += `<div class="wg" id="p8-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Симуляция жидкости: молекулы плотно упакованы</div></div>
|
||||
<div class="wg-help">Молекулы расположены тесно и колеблются. Меняй $t$: при росте температуры амплитуда колебаний растёт, при $t \\to 100°$C — молекулы начинают «вырываться» (испарение → §9).</div>
|
||||
<div class="sliders">
|
||||
<label>Температура $t$: <b id="p8-iv1-tL">20</b> °C <input type="range" id="p8-iv1-t" min="0" max="100" value="20" step="5"></label>
|
||||
</div>
|
||||
<div style="background:#1e293b;border:1px solid var(--border);border-radius:10px;padding:6px;margin-top:8px">
|
||||
<svg id="p8-iv1-svg" viewBox="0 0 360 240" width="100%" style="max-width:520px;height:auto;display:block;margin:0 auto"></svg>
|
||||
</div>
|
||||
<div class="actions" style="justify-content:center">
|
||||
<button class="btn" id="p8-iv1-pause">Пауза</button>
|
||||
<button class="btn" id="p8-iv1-reset">Сначала</button>
|
||||
</div>
|
||||
<div style="margin-top:8px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.93rem;line-height:1.75" id="p8-iv1-info"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Калькулятор поверхностного натяжения */
|
||||
html += `<div class="wg" id="p8-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор поверхностного натяжения</div></div>
|
||||
<div class="wg-help">Выбери жидкость, введи длину $L$ — получишь силу $F = \\sigma L$. Дополнительно — высота поднятия в капилляре $r = 1$ мм.</div>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px;margin-bottom:10px">
|
||||
<label style="display:block;font-size:.9rem;color:var(--muted);background:var(--card);padding:8px 12px;border-radius:8px;border:1px solid var(--border)">Жидкость
|
||||
<select id="p8-iv2-liq" class="tinp" style="width:100%;margin-top:6px">
|
||||
<option value="water">Вода (σ = 0,073 Н/м, ρ = 1000)</option>
|
||||
<option value="alc">Спирт (σ = 0,022 Н/м, ρ = 790)</option>
|
||||
<option value="hg">Ртуть (σ = 0,465 Н/м, ρ = 13600)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label style="display:block;font-size:.9rem;color:var(--muted);background:var(--card);padding:8px 12px;border-radius:8px;border:1px solid var(--border)">Длина $L$, м
|
||||
<input type="number" id="p8-iv2-L" class="tinp" style="width:100%;margin-top:6px" value="0.2" step="any">
|
||||
</label>
|
||||
<label style="display:block;font-size:.9rem;color:var(--muted);background:var(--card);padding:8px 12px;border-radius:8px;border:1px solid var(--border)">Радиус капилляра $r$, мм
|
||||
<input type="number" id="p8-iv2-r" class="tinp" style="width:100%;margin-top:6px" value="1" step="any">
|
||||
</label>
|
||||
</div>
|
||||
<div class="actions" style="justify-content:center">
|
||||
<button class="btn primary" id="p8-iv2-go">Вычислить</button>
|
||||
</div>
|
||||
<div id="p8-iv2-out" style="margin-top:10px;padding:12px 14px;background:var(--card);border-radius:9px;font-size:.94rem;min-height:80px;line-height:1.85"></div>
|
||||
<div class="feedback" id="p8-iv2-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — квикфайр: смачивает или нет */
|
||||
html += `<div class="wg" id="p8-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Смачивает или нет?</div></div>
|
||||
<div class="wg-help">6 ситуаций. Жми соответствующую кнопку.</div>
|
||||
<div class="score-display"><span>Задача <b id="p8-iv3-i">1</b> / 6</span><span>Очки: <b id="p8-iv3-s">0</b> / 6</span></div>
|
||||
<div id="p8-iv3-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div id="p8-iv3-opts" style="display:grid;grid-template-columns:1fr 1fr;gap:8px"></div>
|
||||
<div class="feedback" id="p8-iv3-fb"></div>
|
||||
<div class="actions"><button class="btn" id="p8-iv3-restart">Начать заново</button></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — Тренажёр жидкости */
|
||||
html += `<div class="wg" id="p8-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр жидкости</div></div>
|
||||
<div class="wg-help">5 задач. Допуск ±5%.</div>
|
||||
<div class="score-display"><span>Задача <b id="p8-iv4-i">1</b> / 5</span><span>Очки: <b id="p8-iv4-s">0</b> / 5</span></div>
|
||||
<div id="p8-iv4-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center;min-height:54px"></div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">ответ =</span>
|
||||
<input type="number" id="p8-iv4-ans" class="tinp" style="width:130px;text-align:center" step="any">
|
||||
<button class="btn primary" id="p8-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p8-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p8-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p7', 'p9');
|
||||
html += readButton('p8');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Симуляция жидкости */
|
||||
(function(){
|
||||
const svg = document.getElementById('p8-iv1-svg');
|
||||
const tInp = document.getElementById('p8-iv1-t');
|
||||
const tLab = document.getElementById('p8-iv1-tL');
|
||||
const btnPause = document.getElementById('p8-iv1-pause');
|
||||
const btnReset = document.getElementById('p8-iv1-reset');
|
||||
const info = document.getElementById('p8-iv1-info');
|
||||
const W = 360, H = 240;
|
||||
const N = 60; // число молекул
|
||||
let raf = null, lastT = 0, paused = false;
|
||||
let parts = [];
|
||||
const tempChanges = new Set();
|
||||
let _xpDone = false;
|
||||
|
||||
function makeParts(){
|
||||
parts = [];
|
||||
const cols = 10, rows = 6, sx = 30, sy = 80, dx = 30, dy = 24;
|
||||
for(let j = 0; j < rows; j++){
|
||||
for(let i = 0; i < cols; i++){
|
||||
parts.push({
|
||||
x0: sx + i*dx + (j%2)*dx/2,
|
||||
y0: sy + j*dy,
|
||||
x: sx + i*dx + (j%2)*dx/2,
|
||||
y: sy + j*dy,
|
||||
vx: 0, vy: 0,
|
||||
escaped: false
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function frame(t){
|
||||
raf = requestAnimationFrame(frame);
|
||||
if(!lastT){ lastT = t; return; }
|
||||
let dt = (t - lastT) / 1000;
|
||||
lastT = t;
|
||||
if(paused){ render(); return; }
|
||||
if(dt > 0.06) dt = 0.06;
|
||||
|
||||
const T = +tInp.value;
|
||||
// амплитуда колебаний ~ T (px)
|
||||
const amp = 1 + T * 0.12;
|
||||
// вероятность испарения ~ при T → 100
|
||||
const escapeProb = Math.max(0, (T - 75)) / 25 * 0.0005;
|
||||
|
||||
for(const p of parts){
|
||||
if(p.escaped){
|
||||
// улетает вверх
|
||||
p.x += p.vx * dt;
|
||||
p.y += p.vy * dt;
|
||||
p.vy -= 30 * dt; // тянет вверх (отрицательное y)
|
||||
if(p.y < -10){
|
||||
// респаун обратно в массу
|
||||
p.escaped = false;
|
||||
p.vx = 0; p.vy = 0;
|
||||
p.x = p.x0; p.y = p.y0;
|
||||
}
|
||||
} else {
|
||||
// случайные толчки + возврат к равновесному положению
|
||||
p.vx += (Math.random() - 0.5) * amp * 20 * dt;
|
||||
p.vy += (Math.random() - 0.5) * amp * 20 * dt;
|
||||
// пружина к (x0, y0)
|
||||
p.vx += (p.x0 - p.x) * 8 * dt;
|
||||
p.vy += (p.y0 - p.y) * 8 * dt;
|
||||
// демпфирование
|
||||
p.vx *= 0.92;
|
||||
p.vy *= 0.92;
|
||||
p.x += p.vx * dt;
|
||||
p.y += p.vy * dt;
|
||||
// шанс испариться (для верхнего ряда)
|
||||
if(p.y0 < 100 && Math.random() < escapeProb){
|
||||
p.escaped = true;
|
||||
p.vx = (Math.random() - 0.5) * 40;
|
||||
p.vy = -60 - Math.random() * 40;
|
||||
}
|
||||
}
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
function render(){
|
||||
let g = '';
|
||||
g += '<rect x="0" y="0" width="'+W+'" height="'+H+'" fill="#1e293b"/>';
|
||||
// «поверхность» воды
|
||||
g += '<line x1="0" y1="70" x2="'+W+'" y2="70" stroke="#0ea5e9" stroke-width="1.2" stroke-dasharray="4 4" opacity="0.5"/>';
|
||||
g += '<text x="6" y="64" font-size="10" fill="#7dd3fc">поверхность</text>';
|
||||
// дно
|
||||
g += '<line x1="0" y1="'+(H-10)+'" x2="'+W+'" y2="'+(H-10)+'" stroke="#94a3b8" stroke-width="1"/>';
|
||||
for(const p of parts){
|
||||
const col = p.escaped ? '#fbbf24' : '#60a5fa';
|
||||
g += '<circle cx="'+p.x.toFixed(1)+'" cy="'+p.y.toFixed(1)+'" r="5" fill="'+col+'" stroke="#0f172a" stroke-width="0.6"/>';
|
||||
}
|
||||
svg.innerHTML = g;
|
||||
}
|
||||
|
||||
function updateInfo(T){
|
||||
let txt;
|
||||
if(T < 30){
|
||||
txt = '<b>Низкая $t$.</b> Молекулы колеблются слабо, плотно упакованы. Ближний порядок чётко виден.';
|
||||
} else if(T < 70){
|
||||
txt = '<b>Комнатная $t$.</b> Амплитуда колебаний растёт, отдельные молекулы могут менять соседей.';
|
||||
} else if(T < 95){
|
||||
txt = '<b>Высокая $t$.</b> Колебания сильные, ближний порядок размывается. Возможно появление пузырьков пара.';
|
||||
} else {
|
||||
txt = '<b>$t \\to 100°$C.</b> Молекулы у поверхности «вырываются» наружу — <b>испарение</b> (см. §9).';
|
||||
}
|
||||
info.innerHTML = txt;
|
||||
renderMath(info);
|
||||
}
|
||||
|
||||
makeParts();
|
||||
raf = requestAnimationFrame(frame);
|
||||
updateInfo(+tInp.value);
|
||||
|
||||
tInp.addEventListener('input', () => {
|
||||
const T = +tInp.value;
|
||||
tLab.textContent = T;
|
||||
updateInfo(T);
|
||||
tempChanges.add(Math.round(T/20));
|
||||
if(!_xpDone && tempChanges.size >= 3){
|
||||
_xpDone = true;
|
||||
addXp(10, 'p8-iv1');
|
||||
bumpProgress('p8', 15);
|
||||
}
|
||||
});
|
||||
btnPause.addEventListener('click', () => {
|
||||
paused = !paused;
|
||||
btnPause.textContent = paused ? 'Продолжить' : 'Пауза';
|
||||
});
|
||||
btnReset.addEventListener('click', () => { makeParts(); });
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if(document.hidden && raf){ cancelAnimationFrame(raf); raf = null; lastT = 0; }
|
||||
else if(!document.hidden && !raf){ raf = requestAnimationFrame(frame); }
|
||||
});
|
||||
})();
|
||||
|
||||
/* IV2 — Калькулятор поверхностного натяжения */
|
||||
(function(){
|
||||
const liqSel = document.getElementById('p8-iv2-liq');
|
||||
const lInp = document.getElementById('p8-iv2-L');
|
||||
const rInp = document.getElementById('p8-iv2-r');
|
||||
const out = document.getElementById('p8-iv2-out');
|
||||
const fb = document.getElementById('p8-iv2-fb');
|
||||
const go = document.getElementById('p8-iv2-go');
|
||||
const DATA = {
|
||||
water: { sigma: 0.073, rho: 1000, name: 'Вода' },
|
||||
alc: { sigma: 0.022, rho: 790, name: 'Спирт' },
|
||||
hg: { sigma: 0.465, rho: 13600, name: 'Ртуть' },
|
||||
};
|
||||
const used = new Set();
|
||||
let _done = false;
|
||||
function calc(){
|
||||
const liq = liqSel.value;
|
||||
const d = DATA[liq];
|
||||
const L = parseFloat((lInp.value||'').replace(',','.'));
|
||||
const r_mm = parseFloat((rInp.value||'').replace(',','.'));
|
||||
if(!isFinite(L) || L <= 0 || !isFinite(r_mm) || r_mm <= 0){
|
||||
feedback(fb, false, '✗ $L$ и $r$ должны быть положительными.');
|
||||
return;
|
||||
}
|
||||
const F = d.sigma * L;
|
||||
const r = r_mm / 1000;
|
||||
const g = 9.8;
|
||||
// для смачивающей (вода/спирт) θ ≈ 0, cosθ = 1; для ртути — несмачивает, θ > 90 → h отрицательное
|
||||
let h_m, hLabel;
|
||||
if(liq === 'hg'){
|
||||
// ртуть на стекле: θ ≈ 140°, cos ≈ −0.766
|
||||
h_m = 2 * d.sigma * Math.cos(140 * Math.PI / 180) / (d.rho * g * r);
|
||||
hLabel = 'опускается на $|h| \\approx '+(Math.abs(h_m)*1000).toFixed(2)+'$ мм (несмачивание)';
|
||||
} else {
|
||||
h_m = 2 * d.sigma / (d.rho * g * r);
|
||||
hLabel = 'поднимается на $h \\approx '+(h_m*1000).toFixed(2)+'$ мм';
|
||||
}
|
||||
out.innerHTML =
|
||||
'<div><b>'+d.name+':</b> $\\sigma = '+d.sigma+'$ Н/м, $\\rho = '+d.rho+'$ кг/м³</div>'
|
||||
+ '<div style="margin-top:6px"><b>Сила натяжения:</b> $F = \\sigma L = '+d.sigma+' \\cdot '+L+' \\approx '+(+F.toFixed(5))+'$ Н</div>'
|
||||
+ '<div style="margin-top:6px"><b>В капилляре $r = '+r_mm+'$ мм:</b> жидкость '+hLabel+'</div>';
|
||||
renderMath(out);
|
||||
feedback(fb, true, '✓ Вычислено.');
|
||||
used.add(liq);
|
||||
if(!_done && used.size >= 2){ _done = true; addXp(10, 'p8-iv2'); bumpProgress('p8', 15); }
|
||||
}
|
||||
go.addEventListener('click', calc);
|
||||
})();
|
||||
|
||||
/* IV3 — квикфайр: смачивает или нет */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'Вода на чистом стекле', ans:1, why:'Стекло хорошо смачивается водой ($\\theta \\approx 0°$).' },
|
||||
{ q:'Ртуть на стекле', ans:0, why:'Ртуть не смачивает стекло, $\\theta \\approx 140°$, образует выпуклый мениск.' },
|
||||
{ q:'Вода на парафине (свечном воске)', ans:0, why:'Парафин гидрофобен — вода не смачивает, скатывается каплями.' },
|
||||
{ q:'Спирт на стекле', ans:1, why:'Спирт смачивает стекло ещё лучше воды.' },
|
||||
{ q:'Жидкое мыло на тарелке', ans:1, why:'Мыло — поверхностно-активное вещество, отлично смачивает.' },
|
||||
{ q:'Капля воды на листе лотоса', ans:0, why:'Лист лотоса имеет микрорельеф и воск — вода скатывается шариками.' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
const qEl = document.getElementById('p8-iv3-q');
|
||||
const oEl = document.getElementById('p8-iv3-opts');
|
||||
const fb = document.getElementById('p8-iv3-fb');
|
||||
const iEl = document.getElementById('p8-iv3-i');
|
||||
const sEl = document.getElementById('p8-iv3-s');
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
oEl.innerHTML = '';
|
||||
if(score === Q.length){ addXp(15, 'p8-iv3'); bumpProgress('p8', 25); }
|
||||
else if(score >= 4){ addXp(8, 'p8-iv3'); bumpProgress('p8', 15); }
|
||||
return;
|
||||
}
|
||||
iEl.textContent = (i+1); sEl.textContent = score;
|
||||
qEl.innerHTML = Q[i].q;
|
||||
oEl.innerHTML = '<button class="btn primary" data-v="1">Смачивает</button><button class="btn primary" data-v="0" style="background:#ef4444;border-color:#ef4444">Не смачивает</button>';
|
||||
fb.style.display = 'none';
|
||||
renderMath(qEl);
|
||||
oEl.querySelectorAll('button').forEach(b => {
|
||||
b.addEventListener('click', () => {
|
||||
const v = +b.dataset.v;
|
||||
if(v === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. '+Q[i].why+' Дальше ▶');
|
||||
sEl.textContent = score;
|
||||
oEl.querySelectorAll('button').forEach(x => x.disabled = true);
|
||||
i++;
|
||||
setTimeout(show, 1700);
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p8-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр жидкости */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'$\\sigma = 0{,}073$ Н/м, $L = 0{,}2$ м. Найди силу $F$ в Н (с точностью до 3 знаков).', ans:0.0146, hint:'$F = \\sigma L = 0{,}073 \\cdot 0{,}2 = 0{,}0146$ Н.', tol:0.002 },
|
||||
{ q:'При одинаковой длине $L = 1$ м что больше: $F$ для воды или для ртути? Введи 1 = вода, 2 = ртуть.', ans:2, hint:'$\\sigma_{\\text{Hg}} = 0{,}465 > \\sigma_{\\text{в}} = 0{,}073$ — больше у ртути.', tol:0.1 },
|
||||
{ q:'Высота поднятия воды в капилляре $r = 0{,}5$ мм. Введи в мм (целое). $\\sigma = 0{,}073$, $\\rho = 1000$, $g = 10$, $\\cos\\theta = 1$.', ans:29, hint:'$h = \\dfrac{2\\sigma}{\\rho g r} = \\dfrac{2 \\cdot 0{,}073}{1000 \\cdot 10 \\cdot 0{,}0005} \\approx 0{,}029$ м $\\approx 29$ мм.', tol:3 },
|
||||
{ q:'Жидкость, у которой $\\theta < 90°$ на твёрдой поверхности — смачивает (1) или нет (2)?', ans:1, hint:'По определению, $\\theta < 90°$ — это смачивание.', tol:0.1 },
|
||||
{ q:'В капилляре жидкость поднимается выше при меньшем (1) или большем (2) радиусе?', ans:1, hint:'$h \\sim 1/r$ — чем тоньше капилляр, тем выше поднятие.', tol:0.1 },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p8-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15, 'p8-iv4'); bumpProgress('p8', 25); }
|
||||
else if(score >= 3){ addXp(8, 'p8-iv4'); bumpProgress('p8', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p8-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p8-iv4-s').textContent = score;
|
||||
document.getElementById('p8-iv4-q').innerHTML = Q[i].q;
|
||||
document.getElementById('p8-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p8-iv4-q'));
|
||||
document.getElementById('p8-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p8-iv4-fb');
|
||||
const raw = document.getElementById('p8-iv4-ans').value.replace(',', '.');
|
||||
const ans = parseFloat(raw);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
|
||||
const tol = Q[i].tol || Math.max(0.05 * Math.abs(Q[i].ans), 0.05);
|
||||
if(Math.abs(ans - Q[i].ans) < tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶');
|
||||
document.getElementById('p8-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1900);
|
||||
}
|
||||
document.getElementById('p8-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p8-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
|
||||
document.getElementById('p8-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p8');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user