feat(alg7 ux): Wave 5 — UX-буст для всех 4 глав (комбо + анимации + 2 viz)

Сделано:
1. /css/alg7-fx.css — универсальные эффекты:
   - shake (тряска) при неправильном ответе
   - pulse (зелёное свечение) при правильном
   - combo-badge (огненный шильдик ×3, ×5, ×10) при сериях
   - streak-индикатор в углу с пульсацией
   - sparkles (искры) при успехе
   - стили для двух новых визуализаторов

2. /js/alg7-fx.js — система комбо + визуализаторы:
   - MutationObserver автоматически отслеживает .feedback по всем
     четырём главам без правки feedback() в каждой
   - комбо-милестоны: 3 → +5 XP, 5 → +15, 10 → +50, 15 → +75, 20 → +100
   - бонус автоматически уходит через window.addXp(), который
     уже есть на window благодаря top-level function declarations
   - ALG7.buildQuadSumViz() — большой квадрат (a+b)² с 4 цветными
     областями (a², ab, ab, b²); слайдеры a, b; режим (a+b)/(a-b);
     клик по области → подсветка в формуле; живые числа
   - ALG7.buildDiffSquaresViz() — 3-этапная анимация a²-b²=(a-b)(a+b):
     1) большой квадрат с вырезанной угловой b²
     2) пунктирная линия разреза в L-форме
     3) перестроенный прямоугольник со сторонами (a-b)×(a+b)

3. Подключено во всех 4 главах одной строкой <link>/<script>.

4. Ch2 §12: добавлен 4-й интерактив — геометрическая визуализация
   квадрата суммы/разности. Школьник видит ПОЧЕМУ (a+b)²=a²+2ab+b².

5. Ch2 §13: добавлен 3-й интерактив — анимированное геометрическое
   доказательство разности квадратов. Жмёшь «Шаг» → L-форма
   расклеивается и собирается в прямоугольник.

Эффекты работают везде где есть .feedback — все боссы, все
тренажёры, все викторины. Не требует правки логики каждой главы.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-05-28 23:25:02 +03:00
parent e1c05da294
commit 790c2e9445
6 changed files with 745 additions and 0 deletions
+33
View File
@@ -13,6 +13,8 @@
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<link rel="stylesheet" href="/css/alg7-fx.css">
<script src="/js/alg7-fx.js" defer></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800;900&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
@@ -1470,6 +1472,13 @@ function buildP12(){
+trainerHTML('p12-iv3', 4, 'результат')
+'</div>';
/* INTERACTIVE 4: Геометрическая визуализация квадрата суммы */
html += '<div class="wg" id="p12-iv4-viz">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Геометрическая визуализация $(a \\pm b)^2$</div></div>'
+'<div class="wg-help">Большой квадрат со стороной $(a+b)$ разделён на 4 цветные области. Подвигай $a, b$ — увидишь живое доказательство формулы! Кликни цвет → подсветка в формуле.</div>'
+'<div id="p12-iv4-viz-host"></div>'
+'</div>';
html += secNav('p11', 'p13') + readButton('p12');
box.innerHTML = html; renderMath(box);
@@ -1510,6 +1519,15 @@ function buildP12(){
onComplete:(s,n)=>{ if(s===n){ addXp(12,'p12-iv3'); bumpProgress('p12',20); } else if(s>=2){ addXp(5,'p12-iv3'); bumpProgress('p12',10); } }
});
/* Init quadrat suммы viz from alg7-fx.js */
if(window.ALG7 && window.ALG7.buildQuadSumViz){
window.ALG7.buildQuadSumViz(document.getElementById('p12-iv4-viz-host'));
} else {
/* defer if not loaded yet */
const _try = ()=>{ if(window.ALG7 && window.ALG7.buildQuadSumViz){ window.ALG7.buildQuadSumViz(document.getElementById('p12-iv4-viz-host')); } else setTimeout(_try, 100); };
_try();
}
wireReadBtn('p12');
}
function buildP13(){
@@ -1548,6 +1566,13 @@ function buildP13(){
+trainerHTML('p13-iv2', 5, 'результат')
+'</div>';
/* INTERACTIVE 3: Анимированная визуализация $a^2 - b^2 = (a-b)(a+b)$ */
html += '<div class="wg" id="p13-iv3-viz">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Анимация: $a^2 - b^2 = (a-b)(a+b)$</div></div>'
+'<div class="wg-help">Из квадрата $a^2$ вырезали малый квадрат $b^2$. Жми кнопку <b>«Шаг»</b> — L-форма «расклеится» и соберётся в прямоугольник со сторонами $(a-b)$ и $(a+b)$. Это геометрическое доказательство формулы!</div>'
+'<div id="p13-iv3-viz-host"></div>'
+'</div>';
html += secNav('p12', 'p14') + readButton('p13');
box.innerHTML = html; renderMath(box);
@@ -1576,6 +1601,14 @@ function buildP13(){
onComplete:(s,n)=>{ if(s===n){ addXp(12,'p13-iv2'); bumpProgress('p13',22); } else if(s>=3){ addXp(6,'p13-iv2'); bumpProgress('p13',12); } }
});
/* Init diff-squares viz from alg7-fx.js */
if(window.ALG7 && window.ALG7.buildDiffSquaresViz){
window.ALG7.buildDiffSquaresViz(document.getElementById('p13-iv3-viz-host'));
} else {
const _try = ()=>{ if(window.ALG7 && window.ALG7.buildDiffSquaresViz){ window.ALG7.buildDiffSquaresViz(document.getElementById('p13-iv3-viz-host')); } else setTimeout(_try, 100); };
_try();
}
wireReadBtn('p13');
}
function buildP14(){