diff --git a/frontend/js/phys7_ch3_widgets.js b/frontend/js/phys7_ch3_widgets.js new file mode 100644 index 0000000..bceb9a8 --- /dev/null +++ b/frontend/js/phys7_ch3_widgets.js @@ -0,0 +1,1082 @@ +// Физика 7 · Глава 3 «Движение и силы» · виджеты §§14–20 (часть 1: кинематика). +// Силы §§21–27 + финал — в Phase 4 (phys7_ch3b_widgets.js или этот же файл, расширим). +// Палитра главы — red (#dc2626). + +(function(){ +'use strict'; + +const ACCENT = '#dc2626'; +const ACCENT_D = '#991b1b'; +const ACCENT_SOFT = '#fee2e2'; + +function renderMath(root){ + if(window.renderMathInElement){ + try{ + window.renderMathInElement(root, { + delimiters: [{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false}], + throwOnError: false + }); + }catch(e){} + } +} + +function makeCard(kind, title, badge, body){ + const colorByKind = { theory:ACCENT, rule:'#0284c7', example:'#10b981' }; + const labelByKind = { theory:'Теория', rule:'Правило', example:'Пример' }; + const c = colorByKind[kind] || ACCENT; + return '
' + + '
' + + '' + labelByKind[kind] + '' + + '' + (badge||'') + '' + + '' + title + '' + + '
' + + '
' + body + '
' + + '
'; +} + +function wgWrap(id, badge, title, hint, body){ + return '
' + + '
' + + '' + badge + '' + + '' + title + '' + + '
' + + (hint ? '
' + hint + '
' : '') + + body + + '
'; +} + +function readButton(pid){ + return '
'; +} + +function wireReadBtn(pid){ + const btn = document.querySelector('.ph7-read-btn[data-pid="' + pid + '"]'); + if(!btn) return; + const KEY = 'physics7_ch3_read_' + pid; + if(localStorage.getItem(KEY) === '1'){ + btn.innerHTML = ' Прочитано'; + btn.disabled = true; btn.style.background = '#94a3b8'; btn.style.cursor = 'default'; + return; + } + btn.addEventListener('click', function(){ + if(localStorage.getItem(KEY) === '1') return; + localStorage.setItem(KEY, '1'); + if(typeof window.bumpProgress === 'function') window.bumpProgress(pid, 30); + if(typeof window.addXp === 'function') window.addXp(10, 'read-' + pid); + btn.innerHTML = ' Прочитано'; + btn.disabled = true; btn.style.background = '#94a3b8'; btn.style.cursor = 'default'; + }); +} + +function wireDnd(host, items){ + const root = document.getElementById(host); + if(!root) return; + const checkBtn = root.querySelector('.dnd-check'); + const fb = root.querySelector('.dnd-fb'); + let placed = {}, armed = null; + root.querySelectorAll('.dnd-chip').forEach(chip => chip.addEventListener('click', () => { + if(armed === chip){ armed.classList.remove('armed'); armed.style.boxShadow = ''; armed = null; return; } + if(armed){ armed.classList.remove('armed'); armed.style.boxShadow = ''; } + armed = chip; + chip.classList.add('armed'); + chip.style.boxShadow = '0 0 0 3px rgba(220,38,38,.3)'; + })); + root.querySelectorAll('.drop-box').forEach(box => box.addEventListener('click', () => { + if(!armed) return; + const cat = box.dataset.cat; + const id = armed.dataset.id; + placed[id] = cat; + const clone = armed.cloneNode(true); + clone.classList.remove('armed'); clone.classList.add('placed'); + clone.style.background = ACCENT_SOFT; clone.style.borderColor = ACCENT; clone.style.boxShadow = ''; + clone.addEventListener('click', e => { + e.stopPropagation(); + delete placed[id]; + clone.remove(); + armed = null; + const orig = root.querySelector('.dnd-chip[data-id="' + id + '"]:not(.placed)'); + if(orig) orig.style.display = ''; + }); + box.querySelector('.drop-items').appendChild(clone); + armed.style.display = 'none'; + armed.classList.remove('armed'); armed.style.boxShadow = ''; + armed = null; + })); + if(checkBtn) checkBtn.addEventListener('click', () => { + const total = items.length; + let correct = 0; + items.forEach(it => { if(placed[it.id] === it.cat) correct++; }); + fb.style.display = 'block'; + if(correct === total){ + fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981'; + fb.innerHTML = '✓ Идеально! ' + total + '/' + total + '.'; + if(typeof window.addXp === 'function') window.addXp(15, 'dnd-' + host); + } else { + fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626'; + fb.innerHTML = '✗ Правильно: ' + correct + '/' + total + '. Попробуй ещё раз.'; + } + }); +} + +function dndPool(host, items, cats){ + const chips = items.map(it => '').join(''); + const boxes = cats.map(c => '
' + c.label + '
').join(''); + return '
' + + '
Кликни по карточке, потом по корзине. Чтобы вернуть — кликни в корзине.
' + + '
' + chips + '
' + + '
' + boxes + '
' + + '
' + + '' + + '
'; +} + +function quizQuestion(host, idx, q, opts, correctIdx, explain){ + const optsHtml = opts.map((o,i) => '').join(''); + return '
' + + '
' + (idx+1) + '. ' + q + '
' + + '
' + optsHtml + '
' + + '' + + '
'; +} + +function wireQuiz(host, onAllCorrect){ + const root = document.getElementById(host); + if(!root) return; + const all = root.querySelectorAll('.qz-q'); + const done = new Set(); + all.forEach(qDiv => { + const opts = qDiv.querySelectorAll('.qz-opt'); + const correct = +qDiv.querySelector('.qz-opts').dataset.correct; + const explain = qDiv.querySelector('.qz-opts').dataset.explain; + const fb = qDiv.querySelector('.qz-fb'); + opts.forEach(o => o.addEventListener('click', () => { + if(done.has(qDiv)) return; + const i = +o.dataset.i; + opts.forEach(x => x.disabled = true); + if(i === correct){ + o.style.background = '#d1fae5'; o.style.borderColor = '#10b981'; o.style.color = '#065f46'; + fb.style.display = 'block'; fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981'; + fb.innerHTML = '✓ Верно!' + (explain ? ' ' + explain : ''); + done.add(qDiv); + if(done.size === all.length && typeof onAllCorrect === 'function') onAllCorrect(); + } else { + o.style.background = '#fee2e2'; o.style.borderColor = '#dc2626'; o.style.color = '#7f1d1d'; + opts[correct].style.background = '#d1fae5'; opts[correct].style.borderColor = '#10b981'; opts[correct].style.color = '#065f46'; + fb.style.display = 'block'; fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626'; + fb.innerHTML = '✗ Неверно. Правильно: «' + opts[correct].textContent + '».' + (explain ? ' ' + explain : ''); + done.add(qDiv); + } + })); + }); +} + +/* ========================================================== */ +/* §14 — Механическое движение. Относительность */ +/* ========================================================== */ +function add_p14(){ + const body = document.getElementById('p14-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Что такое механическое движение', '§ 14.1', + 'Механическое движение — это изменение положения тела относительно других тел с течением времени.

' + + 'Чтобы описать движение, нужно выбрать тело отсчёта — то, относительно которого смотрим. ' + + 'Тело отсчёта + связанные с ним оси координат + часы = система отсчёта (СО).'); + + h += makeCard('rule', 'Относительность движения и покоя', '§ 14.2', + 'Одно и то же тело может одновременно и покоиться, и двигаться — в зависимости от выбранной СО.

' + + 'Пример: пассажир в вагоне сидит на месте — относительно вагона он покоится; ' + + 'относительно земли он движется вместе с поездом со скоростью $v$.

' + + 'Часто за тело отсчёта удобно брать Землю.'); + + h += makeCard('example', 'Облако и самолёт', '§ 14.3', + 'Из иллюминатора самолёта вы видите облако.
' + + 'Относительно земли: самолёт летит со скоростью $900$ км/ч, облако почти неподвижно.
' + + 'Относительно самолёта: самолёт «стоит на месте» — а облако «летит» назад со скоростью $\\approx 900$ км/ч.
' + + 'И то, и другое — правильно. Просто СО разные.'); + + /* IV-1 СИМ: 2 СО — поезд + пассажир + станция */ + h += wgWrap('p14-iv1', 'СИМ', 'Откуда смотришь — то и видишь', 'Переключай систему отсчёта и наблюдай, кто движется, а кто стоит.', + '
' + + '' + + '' + + '
' + + '' + + '
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p14-iv2', 'КВИЗ', 'Покой или движение?', '', + '
' + + quizQuestion('p14-q', 0, 'Пассажир сидит в едущем автобусе. Относительно сидящих рядом пассажиров он:', ['Движется','Покоится','И то, и другое','Невозможно определить'], 1) + + quizQuestion('p14-q', 1, 'Тот же пассажир относительно дороги:', ['Движется','Покоится','Невозможно сказать','Только при остановке'], 0) + + quizQuestion('p14-q', 2, 'Дерево у дороги относительно проезжающей машины:', ['Покоится','Движется в сторону, противоположную машине','Движется в ту же сторону','Зависит от скорости'], 1, 'Если за СО взять машину, дерево «летит» назад со скоростью машины.') + + quizQuestion('p14-q', 3, 'Что такое система отсчёта?', ['Только тело отсчёта','Тело отсчёта + оси координат + часы','Только часы','Любая точка'], 1) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p14-iv3', 'DnD', 'Что движется относительно чего', '', + dndPool('p14-dnd', [ + { id:'a1', cat:'mov', html:'Луна относительно Земли' }, + { id:'a2', cat:'mov', html:'Машина относительно дороги' }, + { id:'a3', cat:'rest', html:'Светильник относительно потолка' }, + { id:'a4', cat:'rest', html:'Пассажир относительно вагона' }, + { id:'a5', cat:'mov', html:'Стрелка часов относительно циферблата' }, + { id:'a6', cat:'rest', html:'Книга на столе относительно стола' } + ], [ + { cat:'mov', label:'Движется' }, + { cat:'rest', label:'Покоится' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p14-iv4', 'ТРН', 'Тренажёр §14', '', + '
' + + quizQuestion('p14-tr', 0, 'Что НЕ входит в систему отсчёта?', ['Тело отсчёта','Оси координат','Часы','Скорость движения'], 3) + + quizQuestion('p14-tr', 1, 'Покой или движение — это:', ['Абсолютные понятия','Относительные понятия (зависят от СО)','Существует только покой','Существует только движение'], 1) + + quizQuestion('p14-tr', 2, 'Если за тело отсчёта взять движущийся поезд, то платформа:', ['Покоится','Движется','Не существует','Не имеет значения'], 1) + + quizQuestion('p14-tr', 3, 'Можно ли утверждать, что Земля покоится?', ['Да, всегда','Нет, в одной СО — да, в другой — нет','Нет, никогда','Только ночью'], 1, 'Относительно Солнца Земля движется. Относительно дома — обычно её удобно считать покоящейся.') + + '
'); + + h += readButton('p14'); + body.innerHTML = h; + + // §14 IV-1 wire + let frame14 = 0, raf14 = 0; + function draw14(){ + const co = body.querySelector('.p14-co[style*="background: rgb(220, 38, 38)"], .p14-co[style*="background:#dc2626"]'); + const isGround = !co || co.dataset.co === 'ground'; + const W = 380, H = 160; + let trainX, treeX; + if(isGround){ + trainX = 20 + (frame14 % 320); + treeX = 250; + } else { + trainX = 100; // поезд стоит + treeX = 380 - (frame14 % 320); + } + let s = ''; + // Небо + s += ''; + // Земля + s += ''; + // Рельсы + s += ''; + s += ''; + // Дерево + s += ''; + s += ''; + // Поезд + s += ''; + s += ''; + s += ''; + s += ''; + s += ''; + // Пассажир в окне + s += ''; + // Стрелка «направление обзора» + if(isGround){ + s += 'Наблюдатель на земле'; + } else { + s += 'Наблюдатель в поезде'; + } + document.getElementById('p14-svg').innerHTML = s; + const info = document.getElementById('p14-info'); + if(isGround){ + info.innerHTML = 'СО: Земля. Поезд движется направо. Дерево покоится.'; + } else { + info.innerHTML = 'СО: Поезд. Поезд покоится. Дерево «движется» назад с той же скоростью.'; + } + } + function loop14(){ + frame14 += 1; + if(!document.getElementById('p14-svg')){ cancelAnimationFrame(raf14); return; } + draw14(); + raf14 = requestAnimationFrame(loop14); + } + body.querySelectorAll('.p14-co').forEach(btn => btn.addEventListener('click', () => { + body.querySelectorAll('.p14-co').forEach(b => { b.style.background = '#fff'; b.style.color = '#dc2626'; b.style.border = '2px solid #dc2626'; }); + btn.style.background = '#dc2626'; btn.style.color = '#fff'; btn.style.border = 'none'; + btn.style.padding = '8px 16px'; // компенсировать border + frame14 = 0; + draw14(); + })); + raf14 = requestAnimationFrame(loop14); + + wireDnd('p14-dnd', [ + { id:'a1', cat:'mov' },{ id:'a2', cat:'mov' },{ id:'a3', cat:'rest' }, + { id:'a4', cat:'rest' },{ id:'a5', cat:'mov' },{ id:'a6', cat:'rest' } + ]); + wireQuiz('p14-q-host', () => { if(window.addXp) window.addXp(10, 'q-p14'); }); + wireQuiz('p14-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p14'); }); + wireReadBtn('p14'); + renderMath(body); +} + +/* ========================================================== */ +/* §15 — Траектория, путь, время */ +/* ========================================================== */ +function add_p15(){ + const body = document.getElementById('p15-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Три ключевых понятия', '§ 15.1', + 'Траектория — это линия, по которой движется тело.
' + + 'Путь $s$ — длина этой линии. $[s] = $ м (метр).
' + + 'Время $t$ — длительность движения. $[t] = $ с (секунда).'); + + h += makeCard('rule', 'Виды траекторий', '§ 15.2', + '
    ' + + '
  • Прямолинейная — лифт, шарик в трубке.
  • ' + + '
  • Криволинейная — поворот машины, спутник вокруг Земли.
  • ' + + '
  • Замкнутая — бегун на круговой дорожке возвращается в старт; путь $\\neq 0$, а вот «перемещение» (вектор) равно $0$.
  • ' + + '
' + + 'Длина траектории не зависит от направления — это всегда положительное число.'); + + h += makeCard('example', 'Школьник идёт в школу', '§ 15.3', + 'Сценарий: школьник прошёл $200$ м прямо, потом свернул и прошёл ещё $150$ м, через $5$ мин был в школе.
' + + 'Траектория: ломаная из двух прямых.
' + + 'Путь: $s = 200 + 150 = 350$ м.
' + + 'Время: $t = 5$ мин $= 300$ с.'); + + /* IV-1 СИМ: интерактивная траектория — нажимай по квадратам, считаем путь */ + h += wgWrap('p15-iv1', 'СИМ', 'Считаем путь по траектории', 'Кликай по точкам сетки, чтобы построить ломаную траекторию. Путь будет суммироваться.', + '
' + + '' + + '
Каждая клетка — $\\textbf{1}$ м.
' + + '
' + + '' + + '
Кликай по клеткам, чтобы построить путь.
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p15-iv2', 'КВИЗ', 'Что есть что', '', + '
' + + quizQuestion('p15-q', 0, 'Длина траектории — это:', ['Время','Скорость','Путь','Перемещение'], 2) + + quizQuestion('p15-q', 1, 'Бегун пробежал круг $400$ м и вернулся в старт. Путь равен:', ['0 м','200 м','400 м','800 м'], 2, 'Путь = длина траектории, не зависит от того, что бегун вернулся.') + + quizQuestion('p15-q', 2, 'Единица пути в СИ:', ['Секунда','Метр','Километр','Минута'], 1) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p15-iv3', 'DnD', 'Тип траектории', '', + dndPool('p15-dnd', [ + { id:'a1', cat:'st', html:'Лифт' }, + { id:'a2', cat:'st', html:'Падающий мяч (вертикально)' }, + { id:'a3', cat:'cv', html:'Поворот машины' }, + { id:'a4', cat:'cv', html:'Спутник вокруг Земли' }, + { id:'a5', cat:'cl', html:'Бегун по круговой дорожке' }, + { id:'a6', cat:'cl', html:'Стрелка часов' } + ], [ + { cat:'st', label:'Прямолинейная' }, + { cat:'cv', label:'Криволинейная' }, + { cat:'cl', label:'Замкнутая' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p15-iv4', 'ТРН', 'Тренажёр §15', '', + '
' + + quizQuestion('p15-tr', 0, 'Велосипедист проехал $2$ км и вернулся обратно. Какой путь он проехал?', ['0 км','1 км','2 км','4 км'], 3, 'Путь — сумма длин всех участков: $2 + 2 = 4$ км.') + + quizQuestion('p15-tr', 1, '$5$ мин $= ?$ с', ['50','300','500','3000'], 1) + + quizQuestion('p15-tr', 2, '$1{,}5$ км $= ?$ м', ['15','150','1 500','15 000'], 2) + + quizQuestion('p15-tr', 3, 'Может ли путь быть отрицательным?', ['Да','Нет — это длина, всегда $\\ge 0$','Только в нестандартных СО','Зависит от направления'], 1) + + quizQuestion('p15-tr', 4, 'Что такое траектория?', ['Скорость движения','Линия, по которой движется тело','Длина пути','Время в пути'], 1) + + '
'); + + h += readButton('p15'); + body.innerHTML = h; + + // §15 IV-1: clickable path + const W = 360, H = 220, cell = 20; + const points = []; + function draw15(){ + let s = ''; + // Сетка + for(let x = 0; x <= W; x += cell) s += ''; + for(let y = 0; y <= H; y += cell) s += ''; + // Линии между точками + if(points.length > 1){ + let d = 'M ' + points[0].x + ' ' + points[0].y; + for(let i = 1; i < points.length; i++) d += ' L ' + points[i].x + ' ' + points[i].y; + s += ''; + } + // Точки + points.forEach((p, i) => { + s += ''; + if(i === 0) s += 'старт'; + else if(i === points.length - 1) s += '' + (i+1) + ''; + }); + document.getElementById('p15-svg').innerHTML = s; + // Считаем путь + let total = 0; + for(let i = 1; i < points.length; i++){ + total += Math.hypot(points[i].x - points[i-1].x, points[i].y - points[i-1].y); + } + const meters = (total / cell); + document.getElementById('p15-info').innerHTML = points.length < 2 + ? 'Кликай по клеткам, чтобы построить путь. (Кликнуто: ' + points.length + ')' + : 'Точек: ' + points.length + '  ·  Путь $s = $ ' + meters.toFixed(1) + ' м'; + renderMath(document.getElementById('p15-info')); + } + document.getElementById('p15-svg').addEventListener('click', e => { + const rect = e.target.getBoundingClientRect(); + const svgW = rect.width, svgH = rect.height; + const rawX = (e.clientX - rect.left) * (W / svgW); + const rawY = (e.clientY - rect.top) * (H / svgH); + const x = Math.round(rawX / cell) * cell; + const y = Math.round(rawY / cell) * cell; + points.push({ x, y }); + draw15(); + }); + document.getElementById('p15-reset').addEventListener('click', () => { points.length = 0; draw15(); }); + draw15(); + + wireDnd('p15-dnd', [ + { id:'a1', cat:'st' },{ id:'a2', cat:'st' },{ id:'a3', cat:'cv' }, + { id:'a4', cat:'cv' },{ id:'a5', cat:'cl' },{ id:'a6', cat:'cl' } + ]); + wireQuiz('p15-q-host', () => { if(window.addXp) window.addXp(10, 'q-p15'); }); + wireQuiz('p15-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p15'); }); + wireReadBtn('p15'); + renderMath(body); +} + +/* ========================================================== */ +/* §16 — Равномерное движение. Скорость */ +/* ========================================================== */ +function add_p16(){ + const body = document.getElementById('p16-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Равномерное прямолинейное движение', '§ 16.1', + 'Равномерное — это движение, при котором за любые равные промежутки времени тело проходит равные расстояния.

' + + 'Скорость такого движения:
' + + '$$v = \\dfrac{s}{t}$$
' + + '$[v] = $ м/с (или км/ч). Это векторная величина — у неё есть направление, но в 7-м классе мы пишем как скаляр (без минуса).'); + + h += makeCard('rule', 'Единицы скорости', '§ 16.2', + '' + + '' + + [['м/с','1 м/с = 3,6 км/ч','физика, наука'],['км/ч','1 км/ч ≈ 0,28 м/с','транспорт, спидометры'],['см/с','100 см/с = 1 м/с','биология, мелкие объекты'],['км/с','1 км/с = 1000 м/с','космос, ракеты']].map(r => + '').join('') + + '
ЕдиницаПереводГде встречается
' + r[0] + '' + r[1] + '' + r[2] + '
'); + + h += makeCard('example', 'Простой расчёт', '§ 16.3', + 'Поезд за $t = 2$ ч проехал $s = 180$ км равномерно.
' + + '$v = s/t = 180\\,\\text{км}/2\\,\\text{ч} = 90$ км/ч $= 25$ м/с.

' + + 'Из формулы $v = s/t$ можно выразить и другие: $s = v t$, $t = s/v$.'); + + /* IV-1 СИМ: автомобиль с slider v */ + h += wgWrap('p16-iv1', 'СИМ', 'Автомобиль со скоростью v', 'Меняй скорость — наблюдай, как меняется путь за одно и то же время.', + '
' + + '' + + '
'); + + /* IV-2 КАЛЬК: v = s/t */ + h += wgWrap('p16-iv2', 'КАЛЬК', 'Калькулятор $v = s/t$', '', + '
' + + '' + + '' + + '
' + + '
' + + '$v = s/t = $ 5 м/с $= $ 18 км/ч' + + '
'); + + /* IV-3 DnD: скорости из жизни */ + h += wgWrap('p16-iv3', 'DnD', 'Скорости в жизни', 'Сопоставь объекты с их скоростями.', + dndPool('p16-dnd', [ + { id:'a1', cat:'low', html:'$1$ м/с' }, + { id:'a2', cat:'low', html:'$5$ км/ч' }, + { id:'a3', cat:'mid', html:'$60$ км/ч' }, + { id:'a4', cat:'mid', html:'$20$ м/с' }, + { id:'a5', cat:'high', html:'$900$ км/ч' }, + { id:'a6', cat:'high', html:'$340$ м/с' } + ], [ + { cat:'low', label:'Пешеход' }, + { cat:'mid', label:'Машина / велосипедист' }, + { cat:'high', label:'Самолёт / звук' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p16-iv4', 'ТРН', 'Тренажёр §16', '', + '
' + + quizQuestion('p16-tr', 0, 'Велосипедист за $30$ с проехал $150$ м. Скорость?', ['3 м/с','5 м/с','10 м/с','15 м/с'], 1, '$v = s/t = 150/30 = 5$ м/с.') + + quizQuestion('p16-tr', 1, 'Автобус едет $54$ км/ч. Какой это путь за $10$ с?', ['90 м','120 м','150 м','180 м'], 2, '$v = 54/3{,}6 = 15$ м/с; $s = vt = 15 \\cdot 10 = 150$ м.') + + quizQuestion('p16-tr', 2, 'Самолёт пролетает $720$ км за $1$ ч $30$ мин. Скорость в км/ч?', ['360','480','540','720'], 1, '$1$ ч $30$ мин $= 1{,}5$ ч. $v = 720/1{,}5 = 480$ км/ч.') + + quizQuestion('p16-tr', 3, 'За какое время поезд проедет $300$ км со скоростью $100$ км/ч?', ['1 ч','2 ч','3 ч','4 ч'], 2, '$t = s/v = 300/100 = 3$ ч.') + + quizQuestion('p16-tr', 4, 'Звук в воздухе $340$ м/с. Сколько это км/ч?', ['1024 км/ч','1224 км/ч','1340 км/ч','1500 км/ч'], 1, '$340 \\cdot 3{,}6 = 1224$ км/ч.') + + '
'); + + h += readButton('p16'); + body.innerHTML = h; + + // §16 IV-1: car sim + let frame16 = 0, raf16 = 0; + function draw16(){ + const v = +document.getElementById('p16-v-r').value; + document.getElementById('p16-v').textContent = v; + const W = 380, H = 110; + const t = frame16 / 60; // секунды (60 fps) + const pxPerM = 5; + let pos = (v * t * pxPerM) % (W - 60); + let s = ''; + s += ''; + s += ''; + // Разметка + for(let x = 0; x < W; x += 20){ + s += ''; + } + // Машина + s += ''; + s += ''; + s += ''; + s += ''; + s += ''; + document.getElementById('p16-svg').innerHTML = s; + const traveled = (v * t).toFixed(1); + document.getElementById('p16-info').innerHTML = '$v = ' + v + '$ м/с · время $t = ' + t.toFixed(1) + '$ с · путь $s = vt = $ ' + traveled + ' м'; + renderMath(document.getElementById('p16-info')); + } + function loop16(){ + frame16 += 1; + if(!document.getElementById('p16-svg')){ cancelAnimationFrame(raf16); return; } + draw16(); + raf16 = requestAnimationFrame(loop16); + } + document.getElementById('p16-v-r').addEventListener('input', () => { frame16 = 0; draw16(); }); + raf16 = requestAnimationFrame(loop16); + + // §16 IV-2: calc v=s/t + const upd16c = () => { + const s = +document.getElementById('p16c-s-r').value; + const t = +document.getElementById('p16c-t-r').value; + document.getElementById('p16c-s').textContent = s; + document.getElementById('p16c-t').textContent = t; + const v = s / t; + document.getElementById('p16c-v').textContent = v.toFixed(2); + document.getElementById('p16c-vkmh').textContent = (v * 3.6).toFixed(1); + }; + ['p16c-s-r','p16c-t-r'].forEach(id => document.getElementById(id).addEventListener('input', upd16c)); + upd16c(); + + wireDnd('p16-dnd', [ + { id:'a1', cat:'low' },{ id:'a2', cat:'low' },{ id:'a3', cat:'mid' }, + { id:'a4', cat:'mid' },{ id:'a5', cat:'high' },{ id:'a6', cat:'high' } + ]); + wireQuiz('p16-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p16'); }); + wireReadBtn('p16'); + renderMath(body); +} + +/* ========================================================== */ +/* §17 — Графики пути и скорости (ГЛАВНЫЙ ВИЗУАЛ КИНЕМАТИКИ) */ +/* ========================================================== */ +function add_p17(){ + const body = document.getElementById('p17-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'График $s(t)$', '§ 17.1', + 'При равномерном движении путь растёт линейно со временем: $s = v t$.
' + + 'На графике «путь от времени» — это прямая линия, проходящая через начало координат ' + + '(если в момент $t = 0$ тело было в стартовой точке).

' + + 'Наклон прямой равен скорости $v$. Чем круче линия — тем быстрее движется тело.'); + + h += makeCard('rule', 'График $v(t)$', '§ 17.2', + 'При равномерном движении скорость постоянна: $v(t) = $ const.
' + + 'На графике «скорость от времени» — это горизонтальная линия.

' + + 'Площадь под графиком $v(t)$ равна пройденному пути: $s = v \\cdot t$ (площадь прямоугольника).'); + + h += makeCard('example', 'Два тела на одном графике', '§ 17.3', + 'Если на $s(t)$ две прямые — та, у которой больше наклон, движется быстрее. ' + + 'Если линии пересекаются — в эту точку оба тела пришли одновременно. ' + + 'Параллельные прямые → одинаковые скорости.'); + + /* IV-1 ГЛАВНЫЙ ВИЗУАЛ: интерактивные графики */ + h += wgWrap('p17-iv1', 'СИМ', 'Главный визуал: графики s(t) и v(t)', 'Меняй $v_1$ и $v_2$ — наблюдай два тела одновременно.', + '
' + + '' + + '' + + '
' + + '
' + + '
График $s(t)$
' + + '
График $v(t)$
' + + '
' + + '
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p17-iv2', 'КВИЗ', 'Чтение графиков', '', + '
' + + quizQuestion('p17-q', 0, 'На графике $s(t)$ прямая поднимается круче — что это значит?', ['Тело тяжелее','Тело движется быстрее','Тело покоится','Тело останавливается'], 1, 'Чем круче наклон, тем больше $v = s/t$.') + + quizQuestion('p17-q', 1, 'На графике $v(t)$ — горизонтальная линия. Что движется?', ['Тело ускоряется','Тело движется равномерно','Тело покоится','Невозможно сказать'], 1) + + quizQuestion('p17-q', 2, 'Что равно площадь под графиком $v(t)$ (прямоугольник)?', ['Скорости','Времени','Пути','Массе'], 2, '$s = v \\cdot t$ — это произведение, оно же площадь прямоугольника.') + + quizQuestion('p17-q', 3, 'Две параллельные прямые на $s(t)$ — что это значит?', ['Тела имеют одинаковую скорость','Тела покоятся','Тела движутся в разных направлениях','Тела разной массы'], 0) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p17-iv3', 'DnD', 'Опиши график', '', + dndPool('p17-dnd', [ + { id:'a1', cat:'st_rest', html:'$s(t)$ — горизонтальная' }, + { id:'a2', cat:'st_move', html:'$s(t)$ — наклонная вверх' }, + { id:'a3', cat:'v_rest', html:'$v(t)$ — лежит на оси $t$' }, + { id:'a4', cat:'v_move', html:'$v(t)$ — горизонтальная не на 0' }, + { id:'a5', cat:'st_move', html:'$s = 3t$' }, + { id:'a6', cat:'v_move', html:'$v = 5$ м/с (const)' } + ], [ + { cat:'st_rest', label:'Тело покоится' }, + { cat:'st_move', label:'Равномерное движение' }, + { cat:'v_rest', label:'$v = 0$ (покой)' }, + { cat:'v_move', label:'$v \\ne 0$ (движется)' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p17-iv4', 'ТРН', 'Тренажёр §17', '', + '
' + + quizQuestion('p17-tr', 0, 'Тело прошло $40$ м за $8$ с равномерно. Скорость $v$?', ['3 м/с','4 м/с','5 м/с','8 м/с'], 2) + + quizQuestion('p17-tr', 1, 'На графике $v(t)$ — линия $v = 4$ м/с. Какой путь за $6$ с?', ['10 м','18 м','24 м','30 м'], 2, '$s = vt = 4 \\cdot 6 = 24$ м (площадь прямоугольника).') + + quizQuestion('p17-tr', 2, 'Два тела. На $s(t)$ первое — прямая $s = 2t$, второе — $s = 5t$. Кто быстрее?', ['Первое','Второе','Одинаково','Нельзя определить'], 1, '$v_2 = 5$ м/с $> v_1 = 2$ м/с.') + + quizQuestion('p17-tr', 3, 'Тело покоится. Как выглядит $s(t)$?', ['Прямая через 0','Горизонтальная линия','Линия под углом 45°','Парабола'], 1) + + '
'); + + h += readButton('p17'); + body.innerHTML = h; + + // §17 IV-1 graphs + function draw17(){ + const v1 = +document.getElementById('p17-v1-r').value; + const v2 = +document.getElementById('p17-v2-r').value; + document.getElementById('p17-v1').textContent = v1; + document.getElementById('p17-v2').textContent = v2; + const W = 220, H = 170, pad = 30; + const tMax = 10, vMax = 12, sMax = 100; + // s(t) + function toXs(t){ return pad + (W - 2*pad) * t / tMax; } + function toYs(s){ return H - pad - (H - 2*pad) * s / sMax; } + let ss = ''; + ss += ''; + ss += ''; + ss += 't, с'; + ss += 's, м'; + // ticks + for(let t = 0; t <= tMax; t += 2){ + const x = toXs(t); + ss += ''; + if(t > 0) ss += '' + t + ''; + } + for(let s = 0; s <= sMax; s += 20){ + const y = toYs(s); + ss += ''; + if(s > 0) ss += '' + s + ''; + } + // Lines + ss += ''; + ss += ''; + ss += 'тело 1: v=' + v1 + ''; + ss += 'тело 2: v=' + v2 + ''; + document.getElementById('p17-svg-s').innerHTML = ss; + // v(t) + function toYv(v){ return H - pad - (H - 2*pad) * v / vMax; } + let sv = ''; + sv += ''; + sv += ''; + sv += 't, с'; + sv += 'v, м/с'; + for(let t = 0; t <= tMax; t += 2){ + const x = toXs(t); + sv += ''; + if(t > 0) sv += '' + t + ''; + } + for(let v = 0; v <= vMax; v += 2){ + const y = toYv(v); + sv += ''; + if(v > 0) sv += '' + v + ''; + } + // Площадь под v1 (заливка) + sv += ''; + sv += ''; + sv += ''; + sv += 's₁ = v₁·t'; + document.getElementById('p17-svg-v').innerHTML = sv; + // Info + document.getElementById('p17-info').innerHTML = 'За $t = 10$ с тело 1 пройдёт $s_1 = v_1 t = ' + (v1 * 10) + '$ м, тело 2 — $s_2 = v_2 t = ' + (v2 * 10) + '$ м. ' + (v1 === v2 ? 'Скорости равны — графики $s(t)$ параллельны.' : 'Скорости разные → разный наклон.'); + renderMath(document.getElementById('p17-info')); + } + ['p17-v1-r','p17-v2-r'].forEach(id => document.getElementById(id).addEventListener('input', draw17)); + draw17(); + + wireDnd('p17-dnd', [ + { id:'a1', cat:'st_rest' },{ id:'a2', cat:'st_move' },{ id:'a3', cat:'v_rest' }, + { id:'a4', cat:'v_move' },{ id:'a5', cat:'st_move' },{ id:'a6', cat:'v_move' } + ]); + wireQuiz('p17-q-host', () => { if(window.addXp) window.addXp(10, 'q-p17'); }); + wireQuiz('p17-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p17'); }); + wireReadBtn('p17'); + renderMath(body); +} + +/* ========================================================== */ +/* §18 — Неравномерное движение. Средняя скорость */ +/* ========================================================== */ +function add_p18(){ + const body = document.getElementById('p18-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Неравномерное движение', '§ 18.1', + 'В реальности тела почти никогда не движутся идеально равномерно: машина в городе разгоняется, тормозит у светофоров, ' + + 'снова разгоняется. Скорость меняется со временем — это неравномерное (переменное) движение.

' + + 'Чтобы охарактеризовать его «в среднем», используют среднюю скорость.'); + + h += makeCard('rule', 'Формула средней скорости', '§ 18.2', + '$$\\langle v\\rangle = \\dfrac{s_{полн}}{t_{полн}}$$
' + + '«Средняя скорость = весь путь, делённый на всё время».

' + + 'Внимание! Часто путают: $\\langle v\\rangle \\ne (v_1 + v_2)/2$ — среднеарифметическое не работает, ' + + 'если на участках разное время. Среднее по пути считается через массы (произведение $v \\cdot t$ на каждом участке).'); + + h += makeCard('example', 'Пешеход и метро', '§ 18.3', + 'Девочка прошла пешком $0{,}5$ км за $10$ мин, потом проехала $5$ км на метро за $10$ мин.
' + + '$s_{полн} = 0{,}5 + 5 = 5{,}5$ км, $t_{полн} = 20$ мин $= 1/3$ ч.
' + + '$\\langle v\\rangle = 5{,}5 / (1/3) = 16{,}5$ км/ч.

' + + 'Хотя метро ехало $30$ км/ч, а пешком — $3$ км/ч, средняя — не $(30+3)/2 = 16{,}5$. Совпало здесь только потому, что время оказалось равным!'); + + /* IV-1 КАЛЬК */ + h += wgWrap('p18-iv1', 'КАЛЬК', 'Средняя на двух участках', 'Меняй $v_1, t_1, v_2, t_2$ — сравнивай среднюю и среднеарифметическое.', + '
' + + '' + + '' + + '' + + '' + + '
' + + '
' + + '
$\\langle v\\rangle = (v_1 t_1 + v_2 t_2)/(t_1+t_2) = $ 13.33 м/с
' + + '
Ловушка: $(v_1+v_2)/2 = $ 15.00 м/с — НЕВЕРНО
' + + '
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p18-iv2', 'КВИЗ', 'Среднеарифметическое и средняя', '', + '
' + + quizQuestion('p18-q', 0, 'Когда $\\langle v\\rangle$ равна среднему арифметическому?', ['Всегда','Когда время на участках одинаковое','Когда путь одинаковый','Никогда'], 1, 'Среднее арифметическое — это $\\langle v\\rangle$ только если $t_1 = t_2$.') + + quizQuestion('p18-q', 1, 'Половину пути тело шло $5$ м/с, вторую половину — $20$ м/с. $\\langle v\\rangle$ ближе к…', ['5 м/с','12,5 м/с','20 м/с','8 м/с'], 3, 'Если одинаковые пути, то $\\langle v\\rangle = 2 v_1 v_2 / (v_1 + v_2) = 8$ м/с (ближе к меньшей).') + + quizQuestion('p18-q', 2, 'Если тело часть времени стояло (т.е. $v = 0$), $\\langle v\\rangle$ всего пути…', ['Стала больше','Уменьшилась','Не изменилась','Стала равна нулю'], 1) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p18-iv3', 'DnD', 'Какое движение?', '', + dndPool('p18-dnd', [ + { id:'a1', cat:'eq', html:'Лифт между этажами на постоянной скорости' }, + { id:'a2', cat:'eq', html:'Шарик в воде, опускающийся равномерно' }, + { id:'a3', cat:'neq', html:'Машина в городе' }, + { id:'a4', cat:'neq', html:'Падающий камень (в воздухе)' }, + { id:'a5', cat:'neq', html:'Поезд от станции до станции' }, + { id:'a6', cat:'eq', html:'Звук в воздухе на короткой дистанции' } + ], [ + { cat:'eq', label:'Равномерное' }, + { cat:'neq', label:'Неравномерное' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p18-iv4', 'ТРН', 'Тренажёр §18', '', + '
' + + quizQuestion('p18-tr', 0, 'Тело прошло $60$ м за $4$ с и ещё $80$ м за $6$ с. $\\langle v\\rangle$?', ['10 м/с','12 м/с','14 м/с','15 м/с'], 2, '$\\langle v\\rangle = (60+80)/(4+6) = 140/10 = 14$ м/с.') + + quizQuestion('p18-tr', 1, 'Машина $1$ ч ехала $60$ км/ч, потом $2$ ч — $90$ км/ч. $\\langle v\\rangle$ в км/ч?', ['70','75','80','85'], 2, '$(60 \\cdot 1 + 90 \\cdot 2)/(1+2) = 240/3 = 80$ км/ч.') + + quizQuestion('p18-tr', 2, 'Поезд проехал $300$ км за $5$ ч, при этом $1$ ч стоял на станции. Средняя скорость движения?', ['50 км/ч','60 км/ч','75 км/ч','100 км/ч'], 2, '«Средняя скорость движения» — без учёта стоянки: $300 / (5-1) = 75$ км/ч.') + + quizQuestion('p18-tr', 3, 'Велосипедист первые $5$ км ехал $20$ мин, ещё $5$ км — $40$ мин. $\\langle v\\rangle$?', ['7,5 км/ч','10 км/ч','12 км/ч','15 км/ч'], 1, '$s = 10$ км, $t = 1$ ч. $\\langle v\\rangle = 10$ км/ч.') + + '
'); + + h += readButton('p18'); + body.innerHTML = h; + + // §18 IV-1 + const upd18 = () => { + const v1 = +document.getElementById('p18-v1-r').value; + const t1 = +document.getElementById('p18-t1-r').value; + const v2 = +document.getElementById('p18-v2-r').value; + const t2 = +document.getElementById('p18-t2-r').value; + document.getElementById('p18-v1').textContent = v1; + document.getElementById('p18-t1').textContent = t1; + document.getElementById('p18-v2').textContent = v2; + document.getElementById('p18-t2').textContent = t2; + const vavg = (v1*t1 + v2*t2)/(t1+t2); + const arith = (v1+v2)/2; + document.getElementById('p18-vavg').textContent = vavg.toFixed(2); + document.getElementById('p18-trap').textContent = arith.toFixed(2); + const same = Math.abs(vavg - arith) < 0.01; + document.getElementById('p18-trap-lbl').textContent = same ? 'СОВПАЛО (t₁ = t₂)' : 'НЕВЕРНО'; + document.getElementById('p18-trap-lbl').style.color = same ? '#10b981' : '#dc2626'; + }; + ['p18-v1-r','p18-t1-r','p18-v2-r','p18-t2-r'].forEach(id => document.getElementById(id).addEventListener('input', upd18)); + upd18(); + + wireDnd('p18-dnd', [ + { id:'a1', cat:'eq' },{ id:'a2', cat:'eq' },{ id:'a3', cat:'neq' }, + { id:'a4', cat:'neq' },{ id:'a5', cat:'neq' },{ id:'a6', cat:'eq' } + ]); + wireQuiz('p18-q-host', () => { if(window.addXp) window.addXp(10, 'q-p18'); }); + wireQuiz('p18-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p18'); }); + wireReadBtn('p18'); + renderMath(body); +} + +/* ========================================================== */ +/* §19 — Инерция */ +/* ========================================================== */ +function add_p19(){ + const body = document.getElementById('p19-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Закон инерции Галилея', '§ 19.1', + 'Тело сохраняет состояние покоя или равномерного прямолинейного движения, ' + + 'пока на него не действуют другие тела (или действия уравновешены).

' + + 'Это явление называется инерцией. Оно открыто Галилеем в начале XVII века.'); + + h += makeCard('rule', 'Что меняет скорость', '§ 19.2', + 'Чтобы изменить скорость тела (величину или направление), нужно воздействие другого тела:' + + '
    ' + + '
  • Толкнули — мяч полетел.
  • ' + + '
  • Поймали — мяч остановился.
  • ' + + '
  • Если на тело ничего не действует, оно само собой двигаться/останавливаться не может.
  • ' + + '
' + + 'Тело сопротивляется изменению скорости. Мера этой инертности — масса: тяжёлое тело сложнее разогнать и сложнее остановить.'); + + h += makeCard('example', 'Пассажиры в автобусе', '§ 19.3', + 'Автобус резко тормозит. Пассажиры (которые ещё не получили воздействие от спинки сиденья) ' + + 'по инерции продолжают двигаться вперёд — поэтому их «бросает» вперёд.
' + + 'Автобус резко трогается. Пассажиры по инерции пока остаются на месте, а автобус «уезжает из-под них» — их откидывает назад.
' + + 'Поэтому в транспорте важно держаться или пристёгиваться.'); + + /* IV-1 СИМ: шарик на гладком столе с переключателем «удар»/«трение» */ + h += wgWrap('p19-iv1', 'СИМ', 'Шарик: с трением и без', 'Запусти шарик и сравни: с трением он остановится, без трения — будет двигаться вечно.', + '
' + + '' + + '' + + '
' + + '' + + '
'); + + /* IV-2 КВИЗ */ + h += wgWrap('p19-iv2', 'КВИЗ', 'Инерция в жизни', '', + '
' + + quizQuestion('p19-q', 0, 'Автобус резко тормозит. Куда «летят» пассажиры?', ['Вверх','Вниз','Вперёд','Назад'], 2, 'По инерции тело сохраняет движение вперёд.') + + quizQuestion('p19-q', 1, 'Без действия других тел тело будет…', ['Останавливаться','Сохранять скорость или покой','Самопроизвольно ускоряться','Разваливаться'], 1) + + quizQuestion('p19-q', 2, 'Что является мерой инертности тела?', ['Размер','Цвет','Масса','Объём'], 2) + + quizQuestion('p19-q', 3, 'Кто сформулировал закон инерции?', ['Архимед','Галилей','Ньютон','Эйнштейн'], 1) + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p19-iv3', 'DnD', 'Кого тяжелее остановить?', '', + dndPool('p19-dnd', [ + { id:'a1', cat:'easy', html:'Пушинка' }, + { id:'a2', cat:'easy', html:'Теннисный мячик' }, + { id:'a3', cat:'mid', html:'Велосипедист' }, + { id:'a4', cat:'mid', html:'Школьник на роликах' }, + { id:'a5', cat:'hard', html:'Грузовик с песком' }, + { id:'a6', cat:'hard', html:'Корабль' } + ], [ + { cat:'easy', label:'Легко (малая масса)' }, + { cat:'mid', label:'Средне' }, + { cat:'hard', label:'Тяжело (большая масса)' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p19-iv4', 'ТРН', 'Тренажёр §19', '', + '
' + + quizQuestion('p19-tr', 0, 'На тело не действуют другие тела. Что произойдёт?', ['Оно остановится','Оно ускорится','Оно сохранит скорость и направление','Невозможно сказать'], 2) + + quizQuestion('p19-tr', 1, 'Почему машина после выключения мотора всё-таки тормозит?', ['Из-за инерции','Из-за силы трения о дорогу и сопротивления воздуха','Сама по себе','Из-за гравитации'], 1) + + quizQuestion('p19-tr', 2, 'У какого тела инертность больше: у $1$ кг или $10$ кг?', ['1 кг','10 кг','Одинакова','Зависит от формы'], 1) + + quizQuestion('p19-tr', 3, 'Зачем нужны ремни безопасности в машине?', ['Чтобы держать форму сиденья','Чтобы при резком торможении не «улететь» по инерции вперёд','Для красоты','Чтобы не сидеть прямо'], 1) + + '
'); + + h += readButton('p19'); + body.innerHTML = h; + + // §19 IV-1 sim + let p19 = { x: 30, v: 0, friction: true, raf: 0 }; + function draw19(){ + const svg = document.getElementById('p19-svg'); + if(!svg){ cancelAnimationFrame(p19.raf); return; } + if(p19.friction && p19.v > 0){ + p19.v -= 0.04; + if(p19.v < 0) p19.v = 0; + } + p19.x += p19.v; + if(p19.x > 350){ p19.x = 350; p19.v = 0; } + let s = ''; + s += ''; + s += ''; + if(!p19.friction){ + s += 'идеально гладкая поверхность'; + } else { + // Зубчатая текстура трения + for(let i = 0; i < 18; i++) s += ''; + } + s += ''; + svg.innerHTML = s; + document.getElementById('p19-info').innerHTML = 'Скорость шарика: ' + p19.v.toFixed(2) + ' у. е. ' + (p19.friction ? '(с трением — тормозит)' : '(без трения — будет двигаться вечно)'); + if(p19.v > 0 || !p19.friction) p19.raf = requestAnimationFrame(draw19); + } + document.getElementById('p19-launch').addEventListener('click', () => { p19.x = 30; p19.v = 3.5; if(p19.raf) cancelAnimationFrame(p19.raf); draw19(); }); + document.getElementById('p19-toggle').addEventListener('click', () => { + p19.friction = !p19.friction; + const btn = document.getElementById('p19-toggle'); + btn.textContent = 'Трение: ' + (p19.friction ? 'ВКЛ' : 'ВЫКЛ'); + btn.style.background = p19.friction ? '#fff' : '#10b981'; + btn.style.color = p19.friction ? '#dc2626' : '#fff'; + btn.style.borderColor = p19.friction ? '#dc2626' : '#10b981'; + if(!p19.friction && p19.v === 0){ p19.v = 1.5; if(p19.raf) cancelAnimationFrame(p19.raf); draw19(); } + }); + draw19(); + + wireDnd('p19-dnd', [ + { id:'a1', cat:'easy' },{ id:'a2', cat:'easy' },{ id:'a3', cat:'mid' }, + { id:'a4', cat:'mid' },{ id:'a5', cat:'hard' },{ id:'a6', cat:'hard' } + ]); + wireQuiz('p19-q-host', () => { if(window.addXp) window.addXp(10, 'q-p19'); }); + wireQuiz('p19-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p19'); }); + wireReadBtn('p19'); + renderMath(body); +} + +/* ========================================================== */ +/* §20 — Масса тела. Плотность вещества */ +/* ========================================================== */ +function add_p20(){ + const body = document.getElementById('p20-body'); + if(!body) return; + let h = ''; + + h += makeCard('theory', 'Что такое масса', '§ 20.1', + 'Масса $m$ — физическая величина, характеризующая количество вещества в теле ' + + 'и инертность (то, как трудно изменить скорость тела).

' + + '$[m] = $ кг (килограмм) — основная единица СИ. Кратные: $1$ т = $1000$ кг; ' + + 'дольные: $1$ г = $0{,}001$ кг.'); + + h += makeCard('rule', 'Плотность вещества', '§ 20.2', + 'Плотность $\\rho$ показывает, какая масса вещества содержится в единице объёма:
' + + '$$\\rho = \\dfrac{m}{V}$$
' + + '$[\\rho] = $ кг/м³. Также используют г/см³: $1$ г/см³ $= 1000$ кг/м³.

' + + 'Из формулы $\\rho = m/V$ можно выразить и другие: $m = \\rho V$, $V = m/\\rho$.'); + + h += makeCard('example', 'Таблица плотностей', '§ 20.3', + '' + + '' + + [['Воздух',1.29,0.00129],['Пенопласт',40,0.04],['Сосна',520,0.52],['Лёд',900,0.9],['Вода',1000,1.0],['Алюминий',2700,2.7],['Железо',7800,7.8],['Медь',8900,8.9],['Свинец',11300,11.3],['Ртуть',13600,13.6],['Золото',19300,19.3]].map(r => + '').join('') + + '
Веществокг/м³г/см³
' + r[0] + '' + r[1].toLocaleString('ru-RU') + '' + r[2] + '
'); + + /* IV-1 КАЛЬК: rho = m/V */ + h += wgWrap('p20-iv1', 'КАЛЬК', 'Калькулятор $\\rho = m/V$', 'Меняй массу и объём — увидь плотность и узнай вещество.', + '
' + + '' + + '' + + '
' + + '
' + + '$\\rho = m/V = $ 2.70 г/см³ $= $ 2700 кг/м³' + + '
' + + '
'); + + /* IV-2 СИМ: куб 1 дм³ из разных материалов */ + h += wgWrap('p20-iv2', 'СИМ', 'Куб 1 дм³: какой массы?', 'Выбери вещество — увидь массу для куба объёмом $1$ дм³ $= 1$ литр.', + '
' + + [['Пенопласт',40,'#fde68a'],['Сосна',520,'#92400e'],['Вода',1000,'#0284c7'],['Алюминий',2700,'#94a3b8'],['Железо',7800,'#374151'],['Свинец',11300,'#1f2937'],['Ртуть',13600,'#475569'],['Золото',19300,'#fbbf24']].map(([nm, rho, col]) => + '').join('') + + '
' + + '
' + + '' + + '
' + + 'Вода
' + + 'Объём: $V = 1$ дм³ $= 1$ л $= 1000$ см³
' + + '$m = \\rho V = $ 1 кг' + + '
' + + '
'); + + /* IV-3 DnD */ + h += wgWrap('p20-iv3', 'DnD', 'Какое вещество?', '', + dndPool('p20-dnd', [ + { id:'a1', cat:'light', html:'$\\rho = 0{,}5$ г/см³' }, + { id:'a2', cat:'light', html:'$\\rho = 0{,}9$ г/см³' }, + { id:'a3', cat:'mid', html:'$\\rho = 2{,}7$ г/см³' }, + { id:'a4', cat:'mid', html:'$\\rho = 7{,}8$ г/см³' }, + { id:'a5', cat:'heavy', html:'$\\rho = 11{,}3$ г/см³' }, + { id:'a6', cat:'heavy', html:'$\\rho = 19{,}3$ г/см³' } + ], [ + { cat:'light', label:'Лёгкий: дерево / лёд' }, + { cat:'mid', label:'Средний: алюминий / железо' }, + { cat:'heavy', label:'Тяжёлый: свинец / золото' } + ])); + + /* IV-4 ТРН */ + h += wgWrap('p20-iv4', 'ТРН', 'Тренажёр §20', '', + '
' + + quizQuestion('p20-tr', 0, 'Брусок $m = 540$ г, $V = 200$ см³. $\\rho$?', ['2,7 г/см³','3,5 г/см³','5,4 г/см³','27 г/см³'], 0, '$\\rho = 540/200 = 2{,}7$ — алюминий.') + + quizQuestion('p20-tr', 1, 'Какой объём занимает $7{,}8$ кг железа? ($\\rho = 7800$ кг/м³)', ['10 см³','100 см³','1000 см³','10 л'], 2, '$V = m/\\rho = 7{,}8/7800 = 0{,}001$ м³ $= 1000$ см³.') + + quizQuestion('p20-tr', 2, 'Масса куба $V = 1$ м³ воды равна:', ['100 кг','500 кг','1000 кг','1 т'], 2, '$m = \\rho V = 1000 \\cdot 1 = 1000$ кг $= 1$ т. Оба ответа верны, но «1000 кг» — самый точный.') + + quizQuestion('p20-tr', 3, '$\\rho = 13{,}6$ г/см³. Какое это вещество?', ['Железо','Свинец','Ртуть','Золото'], 2) + + quizQuestion('p20-tr', 4, 'Из бруска $\\rho_1 = 1000$ кг/м³ и $\\rho_2 = 2000$ кг/м³ при одинаковом объёме легче будет:', ['Первый','Второй','Одинаково','Зависит от формы'], 0, 'При $V = $ const, $m \\sim \\rho$. Меньшая плотность → меньшая масса.') + + '
'); + + h += readButton('p20'); + body.innerHTML = h; + + // §20 IV-1 + const matName = (rho) => { + if(rho < 0.2) return 'газ / лёгкий пористый материал'; + if(rho < 0.6) return 'пенопласт / лёгкое дерево'; + if(rho < 0.95) return 'дерево / лёд'; + if(rho < 1.1) return 'вода'; + if(rho < 3) return 'алюминий / стекло'; + if(rho < 9) return 'железо / медь'; + if(rho < 14) return 'свинец / ртуть'; + if(rho < 22) return 'золото / платина'; + return 'плотнее любого металла на Земле'; + }; + const upd20 = () => { + const m = +document.getElementById('p20-m-r').value; + const V = +document.getElementById('p20-V-r').value; + document.getElementById('p20-m').textContent = m; + document.getElementById('p20-V').textContent = V; + const rho = m / V; + document.getElementById('p20-rho').textContent = rho.toFixed(2); + document.getElementById('p20-rho-si').textContent = (rho * 1000).toFixed(0); + document.getElementById('p20-mat').textContent = 'Похоже на: ' + matName(rho); + }; + ['p20-m-r','p20-V-r'].forEach(id => document.getElementById(id).addEventListener('input', upd20)); + upd20(); + + // §20 IV-2 cube + body.querySelectorAll('.p20-mat').forEach(btn => btn.addEventListener('click', () => { + body.querySelectorAll('.p20-mat').forEach(b => { b.style.background = '#fff'; b.style.color = '#0f172a'; }); + btn.style.background = btn.dataset.col; btn.style.color = '#fff'; + const rho = +btn.dataset.rho; // кг/м³ + const m = rho * 0.001; // V = 1 дм³ = 0.001 м³ + document.getElementById('p20-mat-nm').textContent = btn.dataset.nm; + document.getElementById('p20-mat-m').textContent = m.toFixed(2); + document.getElementById('p20-cube').querySelector('polygon').setAttribute('fill', btn.dataset.col); + })); + // Default selected — water + const waterBtn = body.querySelector('.p20-mat[data-nm="Вода"]'); + if(waterBtn){ waterBtn.style.background = waterBtn.dataset.col; waterBtn.style.color = '#fff'; } + + wireDnd('p20-dnd', [ + { id:'a1', cat:'light' },{ id:'a2', cat:'light' },{ id:'a3', cat:'mid' }, + { id:'a4', cat:'mid' },{ id:'a5', cat:'heavy' },{ id:'a6', cat:'heavy' } + ]); + wireQuiz('p20-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p20'); }); + wireReadBtn('p20'); + renderMath(body); +} + +window.PHYS7_CH3_WIDGETS = { + p14: add_p14, + p15: add_p15, + p16: add_p16, + p17: add_p17, + p18: add_p18, + p19: add_p19, + p20: add_p20 + // p21..p27 + final3 — в Phase 4 (силы) +}; + +})();