// Физика 7 · Глава 1 · виджеты §§1–7 (Wave 1: §1, §2). // Экспорт: window.PHYS7_CH1_WIDGETS = { p1: fn, p2: fn, ... }. // Каждая функция вставляет в pN-body: 3 теоретические карточки + 4 виджета + кнопку «Прочитал». (function(){ 'use strict'; /* === Общие хелперы (вдохновлено phys9_ch1_widgets.js, но независимо) === */ 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){ // kind: 'theory' | 'rule' | 'example' const colorByKind = { theory:'#0284c7', rule:'#dc2626', example:'#10b981' }; const labelByKind = { theory:'Теория', rule:'Правило', example:'Пример' }; const c = colorByKind[kind] || '#0284c7'; 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('.phys7-read-btn[data-pid="' + pid + '"]'); if(!btn) return; const KEY = 'physics7_ch1_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'; }); } /* DnD на 4 корзины — общий движок */ function wireDnd(host, items, cats){ const root = document.getElementById(host); if(!root) return; const checkBtn = root.querySelector('.dnd-check'); const fb = root.querySelector('.dnd-fb'); let placed = {}; // itemId -> catKey let armed = null; // Pool clicks root.querySelectorAll('.dnd-chip').forEach(chip => { chip.addEventListener('click', () => { if(armed === chip){ armed.classList.remove('armed'); armed = null; return; } if(armed) armed.classList.remove('armed'); armed = chip; chip.classList.add('armed'); }); }); // Drop boxes 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 inner = box.querySelector('.drop-items'); const clone = armed.cloneNode(true); clone.classList.remove('armed'); clone.classList.add('placed'); 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 = ''; }); inner.appendChild(clone); armed.style.display = 'none'; armed.classList.remove('armed'); armed = null; }); }); // Check if(checkBtn) checkBtn.addEventListener('click', () => { const total = items.length; let correct = 0; items.forEach(it => { if(placed[it.id] === it.cat) correct++; }); const pct = Math.round(correct * 100 / total); fb.style.display = 'block'; if(correct === total){ fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981'; fb.innerHTML = '✓ Идеально! Все ' + total + ' карточек на своих местах.'; if(typeof window.bumpProgress === 'function') window.bumpProgress(host.split('-')[0].replace('p','p') === host ? host : null, 0); 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 + ' (' + pct + '%). Попробуй ещё раз.'; } }); } function dndPool(host, items, cats){ const chips = items.map(it => '').join(''); const boxes = cats.map(c => '
' + c.label + '
').join(''); return '
' + '
Нажми на карточку, потом на нужный ящик. Чтобы вернуть карточку — кликни по ней в ящике.
' + '
' + chips + '
' + '
' + boxes + '
' + '
' + '' + '
'; } /* Quiz одиночного выбора — карточка вопроса */ 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); } // Renable click-через-кнопки запрещён, но повторное прохождение через reset: })); }); } /* ========================================================== */ /* §1 — Физика — наука о природе. Связь с другими науками */ /* ========================================================== */ function add_p1(){ const body = document.getElementById('p1-body'); if(!body) return; let h = ''; /* 3 теоретические карточки */ h += makeCard('theory', 'Что изучает физика', '§ 1.1', 'Физика — это наука о природе. Она изучает физические явления: ' + 'падение тел, движение машин, нагрев и охлаждение, свет, звук, электрический ток, магниты. ' + 'Слово «физика» произошло от греческого фюзис — «природа».'); h += makeCard('rule', 'Связь с другими науками', '§ 1.2', ''); h += makeCard('example', 'Примеры физических явлений', '§ 1.3', '
' + '
Радуга
световое явление
' + '
Гром
звуковое явление
' + '
Северное сияние
электрическое
' + '
Падение яблока
механическое
' + '
Кипение чайника
тепловое
' + '
Тающий лёд
фазовое
' + '
'); /* IV-1: галерея явлений (визуализатор) */ h += wgWrap('p1-iv1', 'СИМ', 'Явления вокруг нас', 'Наведи курсор на иконку, чтобы увидеть, какую сторону природы изучает физика.', '
' + ['Свет','Звук','Тепло','Движение','Электричество','Магнетизм','Жидкости','Газы'].map((nm,i) => '
' + '
' + ['☀','♪','♨','→','⚡','⌘','≈','○'][i] + '
' + '
' + nm + '
' + '
').join('') + '
'); /* IV-2: квикфайр-понимание */ h += wgWrap('p1-iv2', 'КВИЗ', 'Понятия физики', 'Отметь верное утверждение.', '
' + quizQuestion('p1-q', 0, 'Что НЕ изучает физика?', ['Падение тел','Образование облаков','Историю Древнего Рима','Электрический ток'], 2, 'История — это гуманитарная наука; физика изучает явления природы.') + quizQuestion('p1-q', 1, 'От какого греческого слова произошло название «физика»?', ['Фюзис (природа)','Космос (мир)','Логос (учение)','Софос (мудрость)'], 0, 'Греческое фюзис = «природа», поэтому физика — наука о природе.') + quizQuestion('p1-q', 2, 'Какая наука изучает планеты и звёзды и опирается на физику?', ['Биология','Астрономия','География','Химия'], 1, 'Астрономия — наука о небесных телах.') + '
'); /* IV-3: DnD соответствие наука↔область */ h += wgWrap('p1-iv3', 'DnD', 'Связь наук', 'Соедини науку с её областью изучения.', dndPool('p1-dnd', [ { id:'i1', cat:'astro', html:'Звёзды и планеты' }, { id:'i2', cat:'chem', html:'Кислоты и щёлочи' }, { id:'i3', cat:'bio', html:'Клетка и ДНК' }, { id:'i4', cat:'phys', html:'Падение мяча' }, { id:'i5', cat:'astro', html:'Затмение Солнца' }, { id:'i6', cat:'chem', html:'Реакция железа с кислородом' }, { id:'i7', cat:'bio', html:'Работа сердца' }, { id:'i8', cat:'phys', html:'Электрический ток' } ], [ { cat:'astro', label:'Астрономия' }, { cat:'chem', label:'Химия' }, { cat:'bio', label:'Биология' }, { cat:'phys', label:'Физика' } ])); /* IV-4: тренажёр (5 вопросов) */ h += wgWrap('p1-iv4', 'ТРН', 'Тренажёр §1', 'Ответь на 5 вопросов подряд — получишь +10 XP.', '
' + quizQuestion('p1-tr', 0, 'Что изучает физика?', ['Только живую природу','Природные явления (свет, звук, тепло, движение, …)','Только звёзды','Только химические реакции'], 1) + quizQuestion('p1-tr', 1, 'Какое из явлений — НЕ физическое?', ['Кипение воды','Дыхание человека','Падение мяча','Работа лампочки'], 1, 'Дыхание — биологический процесс.') + quizQuestion('p1-tr', 2, 'Электромобиль — пример…', ['Биологического объекта','Технического устройства, основанного на физике','Химического вещества','Астрономического тела'], 1) + quizQuestion('p1-tr', 3, 'Какая пара тесно связана?', ['Физика — литература','Физика — техника','Физика — история','Физика — музыка'], 1, 'Без физики нет техники.') + quizQuestion('p1-tr', 4, 'Слово «физика» означает…', ['Мудрость','Природу','Знание','Закон'], 1) + '
'); h += readButton('p1'); body.innerHTML = h; // Wire interactivity wireDnd('p1-dnd', [ { id:'i1', cat:'astro' },{ id:'i2', cat:'chem' },{ id:'i3', cat:'bio' },{ id:'i4', cat:'phys' }, { id:'i5', cat:'astro' },{ id:'i6', cat:'chem' },{ id:'i7', cat:'bio' },{ id:'i8', cat:'phys' } ], []); wireQuiz('p1-q-host', () => { if(window.addXp) window.addXp(10, 'quiz-p1'); }); wireQuiz('p1-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p1'); }); wireReadBtn('p1'); renderMath(body); } /* ========================================================== */ /* §2 — Физическое тело, физическое явление, физическая величина */ /* ========================================================== */ function add_p2(){ const body = document.getElementById('p2-body'); if(!body) return; let h = ''; /* 3 теоретические карточки */ h += makeCard('theory', 'Четыре главных понятия', '§ 2.1', '' + '' + '' + '' + '' + '' + '
ПонятиеЧто этоПример
Телоконкретный объектмяч, книга, дом
Веществоиз чего сделано телодерево, железо, вода
Явлениеизменение в природепадение, кипение, гроза
Величинато, что можно измеритьмасса, скорость, температура
'); h += makeCard('rule', 'Как отличать?', '§ 2.2', 'Тело — отвечает на вопрос «что это?» — конкретный предмет.
' + 'Вещество — отвечает «из чего?» — материал.
' + 'Явление — отвечает «что происходит?» — изменение, процесс.
' + 'Величина — отвечает «сколько? в каких единицах?» — у неё всегда есть число и единица: $m = 5$ кг, $v = 10$ м/с, $t = 20$ °C.'); h += makeCard('example', 'Один и тот же объект — разные роли', '§ 2.3', 'Рассмотрим стакан с водой:
' + ''); /* IV-1: главный DnD — 12 карточек по 4 корзинам */ h += wgWrap('p2-iv1', 'СИМ', 'Сортировщик: тело / вещество / явление / величина', 'Перетащи 12 карточек в правильные корзины. Это главный визуал §2 — потренируй интуицию.', dndPool('p2-dnd', [ { id:'a1', cat:'body', html:'Стол' }, { id:'a2', cat:'body', html:'Автомобиль' }, { id:'a3', cat:'body', html:'Капля росы' }, { id:'b1', cat:'subst', html:'Алюминий' }, { id:'b2', cat:'subst', html:'Кислород' }, { id:'b3', cat:'subst', html:'Сахар' }, { id:'c1', cat:'phen', html:'Молния' }, { id:'c2', cat:'phen', html:'Замерзание воды' }, { id:'c3', cat:'phen', html:'Движение поезда' }, { id:'d1', cat:'val', html:'$m = 5$ кг' }, { id:'d2', cat:'val', html:'$t = -10$ °C' }, { id:'d3', cat:'val', html:'$v = 30$ км/ч' } ], [ { cat:'body', label:'Тело' }, { cat:'subst', label:'Вещество' }, { cat:'phen', label:'Явление' }, { cat:'val', label:'Величина' } ])); /* IV-2: «найди величину» — выбрать из списка */ h += wgWrap('p2-iv2', 'КВИЗ', 'Найди величину', 'У величины всегда есть число и единица измерения.', '
' + quizQuestion('p2-q', 0, 'Что из списка — физическая величина?', ['Скорость','Скоростной поезд','Стрелка часов','Кипение'], 0, 'Скорость измеряется (м/с, км/ч) — это величина.') + quizQuestion('p2-q', 1, 'А что из этого — явление?', ['Лужа','Испарение воды','Лёд','Холодильник'], 1, 'Испарение — процесс, изменение состояния.') + quizQuestion('p2-q', 2, 'Какое слово обозначает вещество?', ['Гвоздь','Сталь','Молоток','Удар'], 1, 'Сталь — материал, из которого сделан гвоздь.') + '
'); /* IV-3: квикфайр да/нет по 8 утверждениям */ h += wgWrap('p2-iv3', 'ТЕСТ', 'Тело vs величина (быстрые ответы)', 'Прочитай и отметь верное.', '
' + quizQuestion('p2-tn', 0, '«Карандаш» — это…', ['Тело','Вещество','Явление','Величина'], 0) + quizQuestion('p2-tn', 1, '«Дерево» (из чего сделана линейка) — это…', ['Тело','Вещество','Явление','Величина'], 1) + quizQuestion('p2-tn', 2, '«Длина» — это…', ['Тело','Вещество','Явление','Величина'], 3) + quizQuestion('p2-tn', 3, '«Замерзание» — это…', ['Тело','Вещество','Явление','Величина'], 2) + quizQuestion('p2-tn', 4, '$10$ кг — это…', ['Тело','Вещество','Явление','Значение величины'], 3, 'Число + единица = величина.') + '
'); /* IV-4: тренажёр — 4 практических вопроса */ h += wgWrap('p2-iv4', 'ТРН', 'Тренажёр §2', 'Закрепи материал — 4 вопроса.', '
' + quizQuestion('p2-tr', 0, 'Что НЕ является телом?', ['Воздушный шар','Капля воды','Скорость','Кирпич'], 2, 'Скорость — величина, а не тело.') + quizQuestion('p2-tr', 1, 'Стакан с молоком: молоко в стакане — это…', ['Тело','Вещество','Явление','Величина'], 0, 'Молоко в этой ситуации — отдельное тело со своей формой (формой стакана).') + quizQuestion('p2-tr', 2, 'Парусник, плывущий в океане. Назови явление.', ['Парусник','Дерево (мачта)','Движение','Длина паруса'], 2) + quizQuestion('p2-tr', 3, 'Что нужно для записи величины?', ['Только число','Только единица','Число + единица','Только название'], 2, 'Например: $v = 20$ м/с — число 20 и единица м/с.') + '
'); h += readButton('p2'); body.innerHTML = h; wireDnd('p2-dnd', [ { id:'a1', cat:'body' },{ id:'a2', cat:'body' },{ id:'a3', cat:'body' }, { id:'b1', cat:'subst' },{ id:'b2', cat:'subst' },{ id:'b3', cat:'subst' }, { id:'c1', cat:'phen' },{ id:'c2', cat:'phen' },{ id:'c3', cat:'phen' }, { id:'d1', cat:'val' },{ id:'d2', cat:'val' },{ id:'d3', cat:'val' } ], []); wireQuiz('p2-q-host', () => { if(window.addXp) window.addXp(10, 'quiz-p2'); }); wireQuiz('p2-tn-host', () => { if(window.addXp) window.addXp(10, 'tn-p2'); }); wireQuiz('p2-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p2'); }); wireReadBtn('p2'); renderMath(body); } /* Экспорт — заглушки для остальных §, добавятся в следующих волнах */ window.PHYS7_CH1_WIDGETS = { p1: add_p1, p2: add_p2 // p3..p7, final1 — в Wave 2/3 }; })();