feat(phys8 ch2): Phase 4 Wave 1 — §28 постоянные магниты + §29 магнитное поле
§28 Постоянные магниты: - 3 теории: что такое магнит, закон взаимод. полюсов, поле Земли - IV-1: интерактив 2 магнита, slider переворота второго — N–S притягиваются (зелёные стрелки), N–N отталкиваются (красные) - IV-2: 5 раундов «полюсы» - IV-3: DnD 8 утверждений правда/ложь - IV-4: 6 MCQ §29 Магнитное поле: - 3 теории: что такое B, линии индукции (замкнутые!), опилки - IV-1: ГЛАВНЫЙ ВИЗУАЛ — 7 эллиптических замкнутых линий поля полосового магнита N→S, со стрелками направления, прямые линии вблизи оси - IV-2: 5 утверждений правда/ложь - IV-3: DnD 8 свойств «электрическое vs магнитное поле» - IV-4: 6 MCQ Добавлен общий хелпер _drawMagnet. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -423,8 +423,19 @@ const SIDEBARS = {
|
||||
["ТБ","не голыми руками!"],
|
||||
["Заземление","для защиты"]
|
||||
]},
|
||||
p28:{title:"Шпаргалка § 28",rows:[["В разработке","Phase 4 Wave 1"]]},
|
||||
p29:{title:"Шпаргалка § 29",rows:[["В разработке","Phase 4 Wave 1"]]},
|
||||
p28:{title:"Шпаргалка § 28",rows:[
|
||||
["Полюсы","N (север), S (юг)"],
|
||||
["Одноим.","отталкиваются"],
|
||||
["Разноим.","притягиваются"],
|
||||
["Разрез магнита","2 новых магнита (нет монополя)"],
|
||||
["Магн. поле Земли","ось $\\approx$ географ."]
|
||||
]},
|
||||
p29:{title:"Шпаргалка § 29",rows:[
|
||||
["$\\vec B$","магнитная индукция, Тл"],
|
||||
["Линии $\\vec B$","выходят из N, входят в S"],
|
||||
["Линии замкнуты","нет источника / стока"],
|
||||
["Опилки","показывают линии $\\vec B$"]
|
||||
]},
|
||||
p30:{title:"Шпаргалка § 30",rows:[["В разработке","Phase 4 Wave 2"]]},
|
||||
p31:{title:"Шпаргалка § 31",rows:[["В разработке","Phase 4 Wave 2"]]},
|
||||
final2:{title:"Шпаргалка ★",rows:[["В разработке","Phase 4 Wave 2"]]}
|
||||
@@ -447,8 +458,8 @@ const TIPS=[
|
||||
{sec:'p25',html:"При параллельном соединении на каждой ветви одно и то же напряжение. Токи складываются. Сопротивление считается по особой формуле — в итоге $R_{общ}$ <b>меньше</b> любого из $R_1$, $R_2$."},
|
||||
{sec:'p26',html:"$A = UIt$ — энергия, которую ток отдаёт прибору. $P = UI$ — это мощность (Дж/с = Вт). В резисторе вся эта энергия превращается в тепло — это <b>закон Джоуля-Ленца</b>: $Q = I^2 R t$."},
|
||||
{sec:'p27',html:"Счётчик в квартире меряет энергию в <b>кВт·ч</b>: 1 кВт·ч — это работа за 1 час мощностью 1 кВт. Стоимость = энергия × тариф. ТБ: розетка под 220 В может ударить смертельным током."},
|
||||
{sec:'p28',html:"Параграф § 28 будет реализован в Phase 4 Wave 1. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."},
|
||||
{sec:'p29',html:"Параграф § 29 будет реализован в Phase 4 Wave 1. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."},
|
||||
{sec:'p28',html:"Два полюса магнита: N (север) и S (юг). Как и заряды: одноимённые отталкиваются, разноимённые притягиваются. Но в отличие от зарядов, разрезать магнит и получить «только N» нельзя — выскочат новые два полюса."},
|
||||
{sec:'p29',html:"Вокруг магнита есть магнитное поле — оно действует на железные предметы и магнитные стрелки. Линии поля выходят из N и входят в S, и они <b>замкнуты</b> (в отличие от линий эл. поля). Опилки на бумаге над магнитом красиво «рисуют» эти линии."},
|
||||
{sec:'p30',html:"Параграф § 30 будет реализован в Phase 4 Wave 2. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."},
|
||||
{sec:'p31',html:"Параграф § 31 будет реализован в Phase 4 Wave 2. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."},
|
||||
{sec:'final2',html:"Параграф ★ будет реализован в Phase 4 Wave 2. Используем хелперы из <code>phys.js</code> и <code>optics.js</code>."}
|
||||
@@ -471,8 +482,8 @@ const BUILDERS = {
|
||||
p25: ()=>{ build_p25(); },
|
||||
p26: ()=>{ build_p26(); },
|
||||
p27: ()=>{ build_p27(); },
|
||||
p28: ()=>{ const box=document.getElementById('p28-body'); box.innerHTML = buildStub('p28', 'Постоянные магниты', 'Phase 4 Wave 1') + secNavFor('p28') + readButton('p28'); renderMath(box); wireReadBtn('p28'); },
|
||||
p29: ()=>{ const box=document.getElementById('p29-body'); box.innerHTML = buildStub('p29', 'Магнитное поле', 'Phase 4 Wave 1') + secNavFor('p29') + readButton('p29'); renderMath(box); wireReadBtn('p29'); },
|
||||
p28: ()=>{ build_p28(); },
|
||||
p29: ()=>{ build_p29(); },
|
||||
p30: ()=>{ const box=document.getElementById('p30-body'); box.innerHTML = buildStub('p30', 'Магнитное поле тока', 'Phase 4 Wave 2') + secNavFor('p30') + readButton('p30'); renderMath(box); wireReadBtn('p30'); },
|
||||
p31: ()=>{ const box=document.getElementById('p31-body'); box.innerHTML = buildStub('p31', 'Магнитное поле прямого проводника и катушки с током. Электромагнит', 'Phase 4 Wave 2') + secNavFor('p31') + readButton('p31'); renderMath(box); wireReadBtn('p31'); },
|
||||
final2: ()=>{ const box=document.getElementById('final2-body'); box.innerHTML = buildStub('final2', 'Финал главы', 'Phase 4 Wave 2') + secNavFor('final2') + readButton('final2'); renderMath(box); wireReadBtn('final2'); }
|
||||
@@ -4337,6 +4348,429 @@ function _initP27_tasks(){
|
||||
render();
|
||||
}
|
||||
|
||||
/* ======================================================================
|
||||
PHASE 4 · WAVE 1 — §28, §29
|
||||
====================================================================== */
|
||||
|
||||
/* Хелпер: рисует магнитную полосу N-S */
|
||||
function _drawMagnet(x, y, w, hMag, flipped){
|
||||
const halfW = w/2;
|
||||
const nCol = '#dc2626', sCol = '#2563eb';
|
||||
const left = flipped ? sCol : nCol;
|
||||
const right = flipped ? nCol : sCol;
|
||||
const leftLab = flipped ? 'S' : 'N';
|
||||
const rightLab = flipped ? 'N' : 'S';
|
||||
let s = '';
|
||||
s += '<rect x="'+x+'" y="'+y+'" width="'+halfW+'" height="'+hMag+'" fill="'+left+'" stroke="#0f172a" stroke-width="1.6"/>';
|
||||
s += '<rect x="'+(x+halfW)+'" y="'+y+'" width="'+halfW+'" height="'+hMag+'" fill="'+right+'" stroke="#0f172a" stroke-width="1.6"/>';
|
||||
s += '<text x="'+(x+halfW/2)+'" y="'+(y+hMag/2+5)+'" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="14" font-weight="900" fill="#fff">'+leftLab+'</text>';
|
||||
s += '<text x="'+(x+halfW*1.5)+'" y="'+(y+hMag/2+5)+'" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="14" font-weight="900" fill="#fff">'+rightLab+'</text>';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* ======== §28 — Постоянные магниты ======== */
|
||||
function build_p28(){
|
||||
const box = document.getElementById('p28-body');
|
||||
let h = '';
|
||||
|
||||
h += makeCard('theory', 'Что такое магнит', '§ 28.1',
|
||||
'<p><b>Постоянный магнит</b> — тело, обладающее магнитными свойствами длительное время. Чаще всего из железа, никеля, кобальта или сплавов (например, «магнитное железо» — ферриты).</p>'
|
||||
+'<p>У любого магнита есть два <b>полюса</b>: <b>северный (N)</b> и <b>южный (S)</b>. Они расположены на противоположных концах.</p>'
|
||||
+'<p><b>Сила взаимодействия</b> сосредоточена у полюсов — там магнит «прилипает» к железу сильнее всего.</p>'
|
||||
);
|
||||
h += makeCard('rule', 'Закон взаимодействия полюсов', '§ 28.2',
|
||||
'<p>По аналогии с зарядами:</p>'
|
||||
+'<ul style="padding-left:20px;margin:6px 0">'
|
||||
+'<li><b>Одноимённые</b> полюсы (N-N или S-S) — <b>отталкиваются</b>.</li>'
|
||||
+'<li><b>Разноимённые</b> (N-S) — <b>притягиваются</b>.</li>'
|
||||
+'</ul>'
|
||||
+'<p>В отличие от электрических зарядов, <b>нельзя получить</b> магнит только с одним полюсом. Если разрезать магнит пополам — получатся <b>два новых</b> магнита, у каждого свои N и S.</p>'
|
||||
);
|
||||
h += makeCard('example', 'Магнитное поле Земли', '§ 28.3',
|
||||
'<p>Земля — гигантский магнит. Её магнитные полюсы расположены вблизи географических (но не точно на них).</p>'
|
||||
+'<p><b>Важно</b>: «северный географический» близок к <b>южному магнитному</b> полюсу Земли. Поэтому северный конец стрелки компаса (он же N) притягивается к географическому северу.</p>'
|
||||
+'<p>Магнитное поле Земли защищает нас от космических лучей и помогает ориентироваться компасу. Полюсы со временем «дрейфуют».</p>'
|
||||
);
|
||||
|
||||
/* IV1 — взаимодействие двух магнитов */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-1</span><div class="wg-title">Два магнита</div></div>'
|
||||
+'<div class="wg-help">Переворачивай второй магнит — наблюдай притяжение/отталкивание.</div>'
|
||||
+'<div class="sliders" style="margin-bottom:10px">'
|
||||
+'<label>Левый магнит: фиксированный N–S</label>'
|
||||
+'<label>Правый магнит: <select id="p28-flip" class="tinp" style="width:auto;padding:6px 10px"><option value="0">N–S (как левый)</option><option value="1">S–N (перевёрнут)</option></select></label>'
|
||||
+'</div>'
|
||||
+'<svg id="p28-sim" viewBox="0 0 460 200" style="width:100%;height:auto;background:#f8fafc;border-radius:9px;border:1px solid var(--border)"></svg>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Взаимодействие: <b id="p28-act">отталкиваются</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV2 — викторина «как поведут себя?» */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-2</span><div class="wg-title">Притягиваются или отталкиваются?</div></div>'
|
||||
+'<div class="wg-help">Соседствующие полюсы.</div>'
|
||||
+'<div id="p28-quiz"></div>'
|
||||
+'<div class="actions"><button class="btn" id="p28-quiz-next">Следующий</button></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Раунд: <b id="p28-quiz-r">1</b> / 5</span><span>Правильно: <b id="p28-quiz-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV3 — DnD «факт о магнитах» */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-3</span><div class="wg-title">Правда или ложь?</div></div>'
|
||||
+'<div id="p28-dnd-pool"></div>'
|
||||
+'<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px">'
|
||||
+'<div class="drop-box"><h5>Правда</h5><div class="drop-items" data-cat="t"></div></div>'
|
||||
+'<div class="drop-box"><h5>Ложь</h5><div class="drop-items" data-cat="f"></div></div>'
|
||||
+'</div>'
|
||||
+'<div class="actions"><button class="btn primary" id="p28-dnd-check">Проверить</button><button class="btn" id="p28-dnd-reset">Сброс</button></div>'
|
||||
+'<div class="feedback" id="p28-dnd-fb"></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV4 — MCQ */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-4</span><div class="wg-title">Тренажёр: 6 вопросов</div></div>'
|
||||
+'<div class="wg-help">4+ — +15 XP.</div>'
|
||||
+'<div id="p28-mcq"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p28-mcq-i">1</b> / 6</span><span>Правильно: <b id="p28-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p28') + readButton('p28');
|
||||
renderMath(box);
|
||||
wireReadBtn('p28');
|
||||
|
||||
_initP28_two();
|
||||
_initP28_quiz();
|
||||
_initP28_dnd();
|
||||
_initP28_mcq();
|
||||
}
|
||||
|
||||
function _initP28_two(){
|
||||
const svg = document.getElementById('p28-sim'); if(!svg) return;
|
||||
function draw(){
|
||||
const flipped = +document.getElementById('p28-flip').value === 1;
|
||||
let s = '';
|
||||
/* левый магнит — фиксирован */
|
||||
s += _drawMagnet(80, 70, 120, 60, false); /* N(left) S(right) */
|
||||
/* правый магнит */
|
||||
s += _drawMagnet(260, 70, 120, 60, flipped); /* зависит от флага */
|
||||
/* Между магнитами: соседствуют правая половина левого (S) и левая половина правого */
|
||||
/* левая половина правого: flipped ? N : S */
|
||||
const rightInner = flipped ? 'N' : 'S';
|
||||
/* левый внутр (правая половина левого) = S */
|
||||
const leftInner = 'S';
|
||||
const attract = leftInner !== rightInner;
|
||||
/* стрелки силы */
|
||||
if(attract){
|
||||
/* притяжение — стрелки идут навстречу */
|
||||
s += window.PHYS.drawArrow(190, 100, 230, 100, '#10b981', 2.5, 10);
|
||||
s += window.PHYS.drawArrow(270, 100, 230, 100, '#10b981', 2.5, 10);
|
||||
s += '<text x="230" y="155" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="14" font-weight="800" fill="#10b981">ПРИТЯГИВАЮТСЯ</text>';
|
||||
} else {
|
||||
/* отталкивание — стрелки расходятся */
|
||||
s += window.PHYS.drawArrow(220, 100, 190, 100, '#dc2626', 2.5, 10);
|
||||
s += window.PHYS.drawArrow(240, 100, 270, 100, '#dc2626', 2.5, 10);
|
||||
s += '<text x="230" y="155" text-anchor="middle" font-family="Unbounded,sans-serif" font-size="14" font-weight="800" fill="#dc2626">ОТТАЛКИВАЮТСЯ</text>';
|
||||
}
|
||||
svg.innerHTML = s;
|
||||
document.getElementById('p28-act').textContent = attract ? 'притягиваются' : 'отталкиваются';
|
||||
}
|
||||
document.getElementById('p28-flip').addEventListener('change', draw);
|
||||
draw();
|
||||
}
|
||||
|
||||
function _initP28_quiz(){
|
||||
const QS = [
|
||||
{sit:'N подносим к N', ans:'R', why:'Одноимённые → отталкивание.'},
|
||||
{sit:'N подносим к S', ans:'A', why:'Разноимённые → притяжение.'},
|
||||
{sit:'S подносим к S', ans:'R', why:'Одноимённые → отталкивание.'},
|
||||
{sit:'S подносим к N', ans:'A', why:'Разноимённые → притяжение.'},
|
||||
{sit:'Полосовой магнит к стрелке компаса (северный конец)', ans:'A', why:'Северный конец стрелки притягивается к S полюсу магнита, отталкивается от N.'}
|
||||
];
|
||||
let i = 0, ok = 0;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p28-quiz'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin:8px 0;line-height:1.5">'+q.sit+'</div>'
|
||||
+'<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px">'
|
||||
+'<button class="btn" data-pick="A" style="padding:14px"><b>Притягиваются</b></button>'
|
||||
+'<button class="btn" data-pick="R" style="padding:14px"><b>Отталкиваются</b></button>'
|
||||
+'</div>'
|
||||
+'<div class="feedback" id="p28-quiz-fb"></div>';
|
||||
document.getElementById('p28-quiz-r').textContent = (i+1);
|
||||
document.getElementById('p28-quiz-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-pick]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-pick]').forEach(b=>b.disabled=true);
|
||||
const fb = document.getElementById('p28-quiz-fb');
|
||||
if(btn.dataset.pick === q.ans){ ok++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(3,'p28-quiz'); bumpProgress('p28', 4); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p28-quiz-ok').textContent = ok;
|
||||
});
|
||||
});
|
||||
}
|
||||
document.getElementById('p28-quiz-next').addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP28_dnd(){
|
||||
const items = [
|
||||
{id:'a', cat:'t', html:'у магнита 2 полюса: N и S'},
|
||||
{id:'b', cat:'t', html:'N–S притягиваются'},
|
||||
{id:'c', cat:'t', html:'разрезать магнит → 2 магнита'},
|
||||
{id:'d', cat:'t', html:'Земля — гигантский магнит'},
|
||||
{id:'e', cat:'f', html:'можно получить один полюс'},
|
||||
{id:'f', cat:'f', html:'N–N притягиваются'},
|
||||
{id:'g', cat:'f', html:'магнит работает только при подключении'},
|
||||
{id:'h', cat:'f', html:'дерево — магнитный материал'}
|
||||
];
|
||||
const dnd = setupSorter({ poolId:'p28-dnd-pool', scopeSelector:'#sec-p28', cats:['t','f'], items, columnLayout:false });
|
||||
document.getElementById('p28-dnd-check').addEventListener('click', ()=>{
|
||||
const fb = document.getElementById('p28-dnd-fb');
|
||||
let wrong = 0; items.forEach(it=>{ if(dnd.placed[it.id] !== it.cat) wrong++; });
|
||||
if(wrong===0){ fb.className='feedback ok'; fb.innerHTML='✓ Идеально! +15 XP. Магниты — это про железо, никель, кобальт.'; addXp(15,'p28-dnd'); bumpProgress('p28', 20); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Ошибок: '+wrong+'.'; }
|
||||
});
|
||||
document.getElementById('p28-dnd-reset').addEventListener('click', ()=>{ dnd.reset(); const fb=document.getElementById('p28-dnd-fb'); fb.style.display='none'; });
|
||||
}
|
||||
|
||||
function _initP28_mcq(){
|
||||
const QS = [
|
||||
{q:'Сколько полюсов у магнита?', opts:['1','2','3','много'], ans:1, why:'У любого магнита всегда 2 полюса.'},
|
||||
{q:'Какие материалы притягиваются магнитом?', opts:['все','железо, никель, кобальт','медь','стекло'], ans:1, why:'Ферромагнетики.'},
|
||||
{q:'Что произойдёт при разрезании магнита?', opts:['станет 2 разных магнита N и S','станет ничего','станут 2 полноценных магнита','полюса исчезнут'], ans:2, why:'Каждый «огрызок» снова имеет 2 полюса.'},
|
||||
{q:'Северный географический полюс Земли — это магнитный…', opts:['северный','южный','никакой','нейтральный'], ans:1, why:'Север географический ≈ южный магнитный (так задумано в физике).'},
|
||||
{q:'Что показывает северный конец компаса?', opts:['на N магнита','на N полюс магнита','на географический север','куда хочешь'], ans:2, why:'Стрелка компаса север «как бы» указывает на северный географический полюс.'},
|
||||
{q:'Какая сила действует между магнитами?', opts:['гравитационная','электрическая','магнитная','ядерная'], ans:2, why:'Магнитная.'}
|
||||
];
|
||||
let i = 0, ok = 0, done = 0, awarded = false;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p28-mcq'); if(!wrap) return;
|
||||
let h = '<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.5"><b>Вопрос '+(i+1)+'.</b> '+q.q+'</div><div style="display:grid;grid-template-columns:1fr;gap:6px">';
|
||||
q.opts.forEach((opt,k)=>{ h += '<button class="btn" data-k="'+k+'" style="text-align:left;padding:10px 14px">'+String.fromCharCode(65+k)+'. '+opt+'</button>'; });
|
||||
h += '</div><div class="feedback" id="p28-mcq-fb"></div><div class="actions"><button class="btn" id="p28-mcq-next">Следующий</button></div>';
|
||||
wrap.innerHTML = h;
|
||||
document.getElementById('p28-mcq-i').textContent = (i+1);
|
||||
document.getElementById('p28-mcq-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-k]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-k]').forEach(b=>b.disabled=true);
|
||||
const k = +btn.dataset.k; const fb = document.getElementById('p28-mcq-fb');
|
||||
if(k===q.ans){ ok++; done++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(2,'p28-mcq'); bumpProgress('p28', 3); }
|
||||
else { done++; fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p28-mcq-ok').textContent = ok;
|
||||
if(done >= QS.length && !awarded && ok >= 4){ awarded = true; setTimeout(()=>{ const wf=document.getElementById('p28-mcq-fb'); wf.className='feedback ok'; wf.innerHTML='✓ +15 XP — тренажёр пройден.'; addXp(15,'p28-mcq-bonus'); bumpProgress('p28', 15); }, 600); }
|
||||
});
|
||||
});
|
||||
const nb = document.getElementById('p28-mcq-next'); if(nb) nb.addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
/* ======== §29 — Магнитное поле ======== */
|
||||
function build_p29(){
|
||||
const box = document.getElementById('p29-body');
|
||||
let h = '';
|
||||
|
||||
h += makeCard('theory', 'Что такое магнитное поле', '§ 29.1',
|
||||
'<p>Подобно тому как заряды создают электрическое поле, магниты создают вокруг себя <b>магнитное поле</b>.</p>'
|
||||
+'<p>Силовая характеристика поля — <b>магнитная индукция</b> $\\vec B$. Единица измерения — <b>Тесла (Тл)</b>, в честь Никола Тесла.</p>'
|
||||
+'<p>Магнитное поле обнаруживается по силе, действующей на:</p>'
|
||||
+'<ul style="padding-left:20px;margin:6px 0">'
|
||||
+'<li>другие магниты и магнитные стрелки;</li>'
|
||||
+'<li>железные предметы;</li>'
|
||||
+'<li>проводники с током;</li>'
|
||||
+'<li>движущиеся заряды.</li>'
|
||||
+'</ul>'
|
||||
);
|
||||
h += makeCard('rule', 'Линии магнитной индукции', '§ 29.2',
|
||||
'<p>Магнитное поле наглядно изображают <b>линиями магнитной индукции</b>:</p>'
|
||||
+'<ul style="padding-left:20px;margin:6px 0">'
|
||||
+'<li>выходят из <b>N</b> и входят в <b>S</b> полюс магнита снаружи;</li>'
|
||||
+'<li>внутри магнита идут от S к N — поэтому они <b>замкнуты</b>;</li>'
|
||||
+'<li>не пересекаются;</li>'
|
||||
+'<li>чем гуще линии, тем сильнее поле.</li>'
|
||||
+'</ul>'
|
||||
+'<p><b>Важное отличие от электрического поля:</b> линии магн. поля всегда замкнуты (нет «магнитных зарядов»).</p>'
|
||||
);
|
||||
h += makeCard('example', 'Опыт с железными опилками', '§ 29.3',
|
||||
'<p>Если на стекло над магнитом насыпать железные опилки, они выстраиваются вдоль линий магнитной индукции. Получается «фотография» магнитного поля.</p>'
|
||||
+'<p>Сейчас увидим, как это выглядит.</p>'
|
||||
);
|
||||
|
||||
/* IV1 — линии магн. индукции */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-1</span><div class="wg-title">Линии магнитного поля полосового магнита</div></div>'
|
||||
+'<div class="wg-help">Линии выходят из N и входят в S — снаружи. Внутри магнита идут от S к N, замыкая контур.</div>'
|
||||
+'<svg id="p29-sim" viewBox="0 0 460 280" style="width:100%;height:auto;background:#f8fafc;border-radius:9px;border:1px solid var(--border)"></svg>'
|
||||
+'</div>';
|
||||
|
||||
/* IV2 — викторина «где северный полюс» */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-2</span><div class="wg-title">Знаешь линии поля?</div></div>'
|
||||
+'<div class="wg-help">Правда или ложь о линиях $\\vec B$.</div>'
|
||||
+'<div id="p29-quiz"></div>'
|
||||
+'<div class="actions"><button class="btn" id="p29-quiz-next">Следующий</button></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Раунд: <b id="p29-quiz-r">1</b> / 5</span><span>Правильно: <b id="p29-quiz-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV3 — DnD сравнение полей */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-3</span><div class="wg-title">Электрическое vs магнитное поле</div></div>'
|
||||
+'<div class="wg-help">К какому полю относится свойство?</div>'
|
||||
+'<div id="p29-dnd-pool"></div>'
|
||||
+'<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px">'
|
||||
+'<div class="drop-box"><h5>Электрическое</h5><div class="drop-items" data-cat="e"></div></div>'
|
||||
+'<div class="drop-box"><h5>Магнитное</h5><div class="drop-items" data-cat="m"></div></div>'
|
||||
+'</div>'
|
||||
+'<div class="actions"><button class="btn primary" id="p29-dnd-check">Проверить</button><button class="btn" id="p29-dnd-reset">Сброс</button></div>'
|
||||
+'<div class="feedback" id="p29-dnd-fb"></div>'
|
||||
+'</div>';
|
||||
|
||||
/* IV4 — MCQ */
|
||||
h += '<div class="wg">'
|
||||
+'<div class="wg-header"><span class="wg-badge">IV-4</span><div class="wg-title">Тренажёр: 6 вопросов</div></div>'
|
||||
+'<div class="wg-help">4+ — +15 XP.</div>'
|
||||
+'<div id="p29-mcq"></div>'
|
||||
+'<div class="score-display" style="margin-top:10px"><span>Вопрос: <b id="p29-mcq-i">1</b> / 6</span><span>Правильно: <b id="p29-mcq-ok">0</b></span></div>'
|
||||
+'</div>';
|
||||
|
||||
box.innerHTML = h + secNavFor('p29') + readButton('p29');
|
||||
renderMath(box);
|
||||
wireReadBtn('p29');
|
||||
|
||||
_initP29_lines();
|
||||
_initP29_quiz();
|
||||
_initP29_dnd();
|
||||
_initP29_mcq();
|
||||
}
|
||||
|
||||
function _initP29_lines(){
|
||||
const svg = document.getElementById('p29-sim'); if(!svg) return;
|
||||
/* Полосовой магнит N(слева) S(справа), линии поля изгибаются.
|
||||
Параметрически: серия эллиптических дуг разного размера, выходящих из N. */
|
||||
const cx = 230, cy = 140;
|
||||
const magW = 160, magH = 40;
|
||||
let s = '';
|
||||
/* нарисуем магнит */
|
||||
s += _drawMagnet(cx - magW/2, cy - magH/2, magW, magH, false); /* N(left), S(right) */
|
||||
/* линии: эллипсы между N(150,140) и S(310,140), радиус растёт */
|
||||
for(let k = 0; k < 7; k++){
|
||||
const ry = 30 + k*25;
|
||||
/* нарисуем верхнюю и нижнюю половину эллипса как path */
|
||||
const xN = cx - magW/2;
|
||||
const xS = cx + magW/2;
|
||||
/* верхняя половина: дуга от xN,cy через (cx,cy-ry) до xS,cy */
|
||||
const cx1 = (xN+xS)/2;
|
||||
/* стрелка на верхушке */
|
||||
s += '<path d="M '+xN+' '+cy+' Q '+cx1+' '+(cy-ry)+' '+xS+' '+cy+'" fill="none" stroke="#7c3aed" stroke-width="1.4" opacity="0.7"/>';
|
||||
s += '<path d="M '+xN+' '+cy+' Q '+cx1+' '+(cy+ry)+' '+xS+' '+cy+'" fill="none" stroke="#7c3aed" stroke-width="1.4" opacity="0.7"/>';
|
||||
/* стрелка направления — посередине верхней дуги, направлена вправо */
|
||||
if(k < 5){
|
||||
s += window.PHYS.drawArrow(cx-6, cy - ry + 2, cx+6, cy - ry + 2, '#7c3aed', 1.5, 7);
|
||||
s += window.PHYS.drawArrow(cx-6, cy + ry - 2, cx+6, cy + ry - 2, '#7c3aed', 1.5, 7);
|
||||
}
|
||||
}
|
||||
/* пара прямых линий близко к оси (горизонтально между полюсами) */
|
||||
s += '<line x1="'+(cx-magW/2-30)+'" y1="'+cy+'" x2="'+(cx-magW/2-4)+'" y2="'+cy+'" stroke="#7c3aed" stroke-width="1.6"/>';
|
||||
s += '<line x1="'+(cx+magW/2+4)+'" y1="'+cy+'" x2="'+(cx+magW/2+30)+'" y2="'+cy+'" stroke="#7c3aed" stroke-width="1.6"/>';
|
||||
/* подписи */
|
||||
s += '<text x="230" y="40" text-anchor="middle" font-family="Inter,sans-serif" font-size="12" font-weight="700" fill="#7c3aed">линии магнитной индукции $\\vec B$</text>';
|
||||
s += '<text x="60" y="270" font-family="Inter,sans-serif" font-size="11" fill="#475569">снаружи: N → S</text>';
|
||||
s += '<text x="280" y="270" font-family="Inter,sans-serif" font-size="11" fill="#475569">внутри: S → N (замыкают)</text>';
|
||||
svg.innerHTML = s;
|
||||
}
|
||||
|
||||
function _initP29_quiz(){
|
||||
const QS = [
|
||||
{st:'Линии магнитного поля выходят из S и входят в N.', ans:'F', why:'Наоборот: из N в S.'},
|
||||
{st:'Линии магнитного поля замкнуты.', ans:'T', why:'Внутри магнита они идут от S к N, замыкая контур.'},
|
||||
{st:'Линии магнитного поля могут пересекаться.', ans:'F', why:'В каждой точке вектор $\\vec B$ имеет одно направление.'},
|
||||
{st:'Чем гуще линии, тем сильнее поле.', ans:'T', why:'Густота показывает $|B|$.'},
|
||||
{st:'Магнитное поле действует на неподвижный заряд.', ans:'F', why:'Только на движущийся заряд и на ток!'}
|
||||
];
|
||||
let i = 0, ok = 0;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p29-quiz'); if(!wrap) return;
|
||||
wrap.innerHTML =
|
||||
'<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin:8px 0;line-height:1.5">"'+q.st+'"</div>'
|
||||
+'<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px">'
|
||||
+'<button class="btn" data-pick="T" style="padding:14px"><b>Правда</b></button>'
|
||||
+'<button class="btn" data-pick="F" style="padding:14px"><b>Ложь</b></button>'
|
||||
+'</div>'
|
||||
+'<div class="feedback" id="p29-quiz-fb"></div>';
|
||||
document.getElementById('p29-quiz-r').textContent = (i+1);
|
||||
document.getElementById('p29-quiz-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-pick]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-pick]').forEach(b=>b.disabled=true);
|
||||
const fb = document.getElementById('p29-quiz-fb');
|
||||
if(btn.dataset.pick === q.ans){ ok++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(3,'p29-quiz'); bumpProgress('p29', 4); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p29-quiz-ok').textContent = ok;
|
||||
renderMath(wrap);
|
||||
});
|
||||
});
|
||||
renderMath(wrap);
|
||||
}
|
||||
document.getElementById('p29-quiz-next').addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
render();
|
||||
}
|
||||
|
||||
function _initP29_dnd(){
|
||||
const items = [
|
||||
{id:'a', cat:'e', html:'линии начинаются на +, кончаются на −'},
|
||||
{id:'b', cat:'e', html:'действует на любой заряд'},
|
||||
{id:'c', cat:'e', html:'источники — заряды'},
|
||||
{id:'d', cat:'e', html:'$U = A/q$'},
|
||||
{id:'e', cat:'m', html:'линии замкнуты (без начала и конца)'},
|
||||
{id:'f', cat:'m', html:'действует на движ. заряды и ток'},
|
||||
{id:'g', cat:'m', html:'источники — магниты и токи'},
|
||||
{id:'h', cat:'m', html:'$\\vec B$ — индукция, [Тл]'}
|
||||
];
|
||||
const dnd = setupSorter({ poolId:'p29-dnd-pool', scopeSelector:'#sec-p29', cats:['e','m'], items, columnLayout:false });
|
||||
document.getElementById('p29-dnd-check').addEventListener('click', ()=>{
|
||||
const fb = document.getElementById('p29-dnd-fb');
|
||||
let wrong = 0; items.forEach(it=>{ if(dnd.placed[it.id] !== it.cat) wrong++; });
|
||||
if(wrong===0){ fb.className='feedback ok'; fb.innerHTML='✓ Идеально! +15 XP. Эл. поле — открытые линии, магн. поле — замкнутые.'; addXp(15,'p29-dnd'); bumpProgress('p29', 20); renderMath(fb); }
|
||||
else { fb.className='feedback fail'; fb.innerHTML='✗ Ошибок: '+wrong+'.'; renderMath(fb); }
|
||||
});
|
||||
document.getElementById('p29-dnd-reset').addEventListener('click', ()=>{ dnd.reset(); const fb=document.getElementById('p29-dnd-fb'); fb.style.display='none'; });
|
||||
}
|
||||
|
||||
function _initP29_mcq(){
|
||||
const QS = [
|
||||
{q:'Что обозначают $\\vec B$?', opts:['напряжённость','индукцию','потенциал','работу'], ans:1, why:'Магнитная индукция.'},
|
||||
{q:'Единица измерения $|B|$?', opts:['Вольт','Ампер','Тесла','Ом'], ans:2, why:'Тесла (Тл).'},
|
||||
{q:'Куда направлены линии вне магнита?', opts:['от N к S','от S к N','внутри по кругу','хаос'], ans:0, why:'Снаружи — от N к S.'},
|
||||
{q:'Линии $\\vec B$ обладают свойством…', opts:['открытости','замкнутости','пересечения','исчезновения'], ans:1, why:'Магнитное поле — соленоидальное.'},
|
||||
{q:'Что отклоняет стрелку компаса?', opts:['заряд','свет','магнитное поле Земли','гравитация'], ans:2, why:'Земля — гигантский магнит.'},
|
||||
{q:'Как «увидеть» магнитное поле?', opts:['опилками','спиртом','краской','углём'], ans:0, why:'Железные опилки выстраиваются вдоль линий.'}
|
||||
];
|
||||
let i = 0, ok = 0, done = 0, awarded = false;
|
||||
function render(){
|
||||
const q = QS[i]; const wrap = document.getElementById('p29-mcq'); if(!wrap) return;
|
||||
let h = '<div style="padding:10px 14px;background:rgba(15,23,42,.04);border-radius:9px;margin-bottom:10px;font-size:.95rem;line-height:1.5"><b>Вопрос '+(i+1)+'.</b> '+q.q+'</div><div style="display:grid;grid-template-columns:1fr;gap:6px">';
|
||||
q.opts.forEach((opt,k)=>{ h += '<button class="btn" data-k="'+k+'" style="text-align:left;padding:10px 14px">'+String.fromCharCode(65+k)+'. '+opt+'</button>'; });
|
||||
h += '</div><div class="feedback" id="p29-mcq-fb"></div><div class="actions"><button class="btn" id="p29-mcq-next">Следующий</button></div>';
|
||||
wrap.innerHTML = h;
|
||||
document.getElementById('p29-mcq-i').textContent = (i+1);
|
||||
document.getElementById('p29-mcq-ok').textContent = ok;
|
||||
wrap.querySelectorAll('[data-k]').forEach(btn=>{
|
||||
btn.addEventListener('click', ()=>{
|
||||
if(btn.disabled) return; wrap.querySelectorAll('[data-k]').forEach(b=>b.disabled=true);
|
||||
const k = +btn.dataset.k; const fb = document.getElementById('p29-mcq-fb');
|
||||
if(k===q.ans){ ok++; done++; fb.className='feedback ok'; fb.innerHTML='✓ Верно. '+q.why; addXp(2,'p29-mcq'); bumpProgress('p29', 3); }
|
||||
else { done++; fb.className='feedback fail'; fb.innerHTML='✗ Не то. '+q.why; }
|
||||
document.getElementById('p29-mcq-ok').textContent = ok;
|
||||
renderMath(wrap);
|
||||
if(done >= QS.length && !awarded && ok >= 4){ awarded = true; setTimeout(()=>{ const wf=document.getElementById('p29-mcq-fb'); wf.className='feedback ok'; wf.innerHTML='✓ +15 XP — тренажёр пройден.'; addXp(15,'p29-mcq-bonus'); bumpProgress('p29', 15); }, 600); }
|
||||
});
|
||||
});
|
||||
const nb = document.getElementById('p29-mcq-next'); if(nb) nb.addEventListener('click', ()=>{ i=(i+1)%QS.length; render(); });
|
||||
renderMath(wrap);
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
function init(){
|
||||
loadProgress(); initTheme(); initSidebarToggle(); initSearch();
|
||||
buildParaSelector(); refreshProgressUI(); loadServerReadState(); goTo(PARAS[0].id);
|
||||
|
||||
Reference in New Issue
Block a user