fix(alg10 ch1): формульные плакаты §10-§12 — KaTeX вместо моноширинного SVG

Заменены 3 SVG-плакаты (формул сложения, двойного аргумента,
сумма→произведение) на HTML-карточки с настоящим KaTeX-рендерингом.

Добавлен CSS-компонент .formula-plate с подкомпонентами:
- .formula-plate-head + цветовые варианты (teal/cyan/violet/green/amber)
  → плашка-заголовок с градиентом
- .formula-plate-title + .formula-plate-sub
  → крупный заголовок + курсивный подзаголовок
- .formula-plate-body + .formula-row + альтернативные цвета
  → строки формул с подсветкой
- .formula-section (янтарная вставка для tg)
- .formula-mnem (фиолетовая плашка с мнемоникой)

§10: 8 формул в HTML-плакате с teal-плашкой + янтарный блок 'Тангенсы'
§11: 3 формулы двойного аргумента отдельным плакатом ПЕРЕД SVG
     с окружностью (которая теперь короче — без встроенного
     формульного блока)
§12: 4 формулы в violet-плакате + фиолетовая плашка 'Мнемоника' со
     списком правил

Все формулы теперь рендерятся настоящим KaTeX с дробями \dfrac,
правильными операторами \tg \sin \cos, греческими буквами
\alpha \beta, и индексами/степенями.
This commit is contained in:
Maxim Dolgolyov
2026-05-29 11:25:03 +03:00
parent 0903ef640a
commit 18fadcba9f
+83 -41
View File
@@ -174,6 +174,35 @@ a{color:inherit;text-decoration:none}
.stub-soon{padding:30px 22px;text-align:center;background:linear-gradient(135deg,var(--pri-soft),var(--acc-soft));border:1.5px dashed var(--pri);border-radius:14px;color:var(--text)}
.stub-soon h3{font-family:'Unbounded',sans-serif;font-size:1.15rem;color:var(--pri2);margin-bottom:8px}
.stub-soon p{font-size:.92rem;color:var(--muted);max-width:520px;margin:0 auto}
/* Formula plates — стильные плакаты с формулами + KaTeX внутри */
.formula-plate{margin:16px 0;border-radius:14px;overflow:hidden;border:1.5px solid var(--border);box-shadow:0 4px 16px rgba(0,0,0,.04);background:var(--card)}
.formula-plate-head{padding:14px 18px;text-align:center;border-bottom:1px solid var(--border)}
.formula-plate-head.teal {background:linear-gradient(180deg,rgba(13,148,136,.12),rgba(13,148,136,.06))}
.formula-plate-head.cyan {background:linear-gradient(180deg,rgba(8,145,178,.12),rgba(8,145,178,.06))}
.formula-plate-head.violet {background:linear-gradient(180deg,rgba(124,58,237,.12),rgba(124,58,237,.06))}
.formula-plate-head.green {background:linear-gradient(180deg,rgba(22,163,74,.12),rgba(22,163,74,.06))}
.formula-plate-head.amber {background:linear-gradient(180deg,rgba(245,158,11,.14),rgba(245,158,11,.06))}
.formula-plate-title{font-family:'Unbounded',sans-serif;font-size:1.02rem;font-weight:800;letter-spacing:.04em;margin-bottom:4px;text-transform:uppercase}
.formula-plate-head.teal .formula-plate-title{color:#0f766e}
.formula-plate-head.cyan .formula-plate-title{color:#0e7490}
.formula-plate-head.violet .formula-plate-title{color:#6d28d9}
.formula-plate-head.green .formula-plate-title{color:#15803d}
.formula-plate-head.amber .formula-plate-title{color:#92400e}
.formula-plate-sub{font-size:.84rem;font-style:italic;color:var(--muted);line-height:1.4}
.formula-plate-body{padding:14px 22px}
.formula-row{padding:9px 4px;font-size:1.08rem;text-align:center;line-height:1.5;border-bottom:1px dashed rgba(0,0,0,.05)}
.formula-row:last-child{border-bottom:0}
.formula-row.alt{color:#7c3aed}
.formula-row.alt2{color:#0891b2}
.formula-row.danger{color:#dc2626}
.formula-section{margin:0 16px 16px;padding:12px 16px;border-radius:10px;background:rgba(245,158,11,.10);border:1.5px solid rgba(245,158,11,.6)}
.formula-section-title{font-family:'Unbounded',sans-serif;font-size:.74rem;font-weight:800;text-align:center;letter-spacing:.08em;color:#92400e;margin-bottom:8px;text-transform:uppercase}
.formula-section .formula-row{color:#92400e;border-bottom:1px dashed rgba(146,64,14,.18)}
.formula-mnem{margin:0 16px 16px;padding:12px 18px;border-radius:10px;background:rgba(124,58,237,.08);border:1.5px solid rgba(124,58,237,.4)}
.formula-mnem-title{font-family:'Unbounded',sans-serif;font-size:.74rem;font-weight:800;text-align:center;letter-spacing:.08em;color:#6d28d9;margin-bottom:8px;text-transform:uppercase}
.formula-mnem ul{margin:0;padding-left:18px;line-height:1.75;font-size:.93rem;color:var(--text)}
.formula-mnem li{margin-bottom:4px}
</style>
</head>
<body>
@@ -2460,23 +2489,24 @@ function buildP10(){
const box = document.getElementById('p10-body');
let html = '';
/* === SVG: красивая плашка с 8 формулами === */
const svgFormulas =
'<svg viewBox="0 0 580 280" preserveAspectRatio="xMidYMid meet" style="width:100%;height:auto;display:block;margin:0 auto;background:#fff;border-radius:10px;border:1px solid #e2e8f0">'
+ '<rect x="0" y="0" width="580" height="44" fill="rgba(13,148,136,.08)"/>'
+ '<text x="290" y="22" text-anchor="middle" font-size="14" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#0d9488">8 ФОРМУЛ СЛОЖЕНИЯ И ВЫЧИТАНИЯ УГЛОВ</text>'
+ '<text x="290" y="38" text-anchor="middle" font-size="10" font-family="Inter,sans-serif" font-style="italic" fill="#64748b">учат наизусть — это база для всей старшей тригонометрии</text>'
/* Колонка 1: sin/cos */
+ '<text x="40" y="78" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#0d9488">sin(α + β) = sinα·cosβ + cosα·sinβ</text>'
+ '<text x="40" y="108" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#7c3aed">sin(α β) = sinα·cosβ cosα·sinβ</text>'
+ '<text x="40" y="138" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#0d9488">cos(α + β) = cosα·cosβ sinα·sinβ</text>'
+ '<text x="40" y="168" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#7c3aed">cos(α β) = cosα·cosβ + sinα·sinβ</text>'
/* tg отдельно */
+ '<rect x="20" y="190" width="540" height="76" rx="10" fill="rgba(245,158,11,.10)" stroke="#f59e0b" stroke-width="1.5"/>'
+ '<text x="290" y="208" text-anchor="middle" font-size="11" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#92400e">ТАНГЕНСЫ</text>'
+ '<text x="40" y="232" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#92400e">tg(α + β) = (tgα + tgβ) / (1 tgα·tgβ)</text>'
+ '<text x="40" y="256" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#92400e">tg(α β) = (tgα tgβ) / (1 + tgα·tgβ)</text>'
+ '</svg>';
/* === Плакат: 8 формул сложения и вычитания (HTML + KaTeX) === */
const svgFormulas = '<div class="formula-plate">'
+ '<div class="formula-plate-head teal">'
+ '<div class="formula-plate-title">8 формул сложения и вычитания углов</div>'
+ '<div class="formula-plate-sub">учат наизусть — это база для всей старшей тригонометрии</div>'
+ '</div>'
+ '<div class="formula-plate-body">'
+ '<div class="formula-row">$\\sin(\\alpha + \\beta) = \\sin\\alpha\\cos\\beta + \\cos\\alpha\\sin\\beta$</div>'
+ '<div class="formula-row alt">$\\sin(\\alpha - \\beta) = \\sin\\alpha\\cos\\beta - \\cos\\alpha\\sin\\beta$</div>'
+ '<div class="formula-row">$\\cos(\\alpha + \\beta) = \\cos\\alpha\\cos\\beta - \\sin\\alpha\\sin\\beta$</div>'
+ '<div class="formula-row alt">$\\cos(\\alpha - \\beta) = \\cos\\alpha\\cos\\beta + \\sin\\alpha\\sin\\beta$</div>'
+ '</div>'
+ '<div class="formula-section">'
+ '<div class="formula-section-title">Тангенсы</div>'
+ '<div class="formula-row">$\\tg(\\alpha + \\beta) = \\dfrac{\\tg\\alpha + \\tg\\beta}{1 - \\tg\\alpha \\, \\tg\\beta}$</div>'
+ '<div class="formula-row">$\\tg(\\alpha - \\beta) = \\dfrac{\\tg\\alpha - \\tg\\beta}{1 + \\tg\\alpha \\, \\tg\\beta}$</div>'
+ '</div>'
+ '</div>';
html += makeCard('rule', 'Формулы синуса и косинуса суммы/разности', '10.1', `
<p>Сложение углов в тригонометрии — это четыре формулы. Их нужно знать наизусть.</p>
@@ -2587,10 +2617,10 @@ function buildP11(){
const A = window.ALG10;
let html = '';
/* === SVG: α и 2α на единичной окружности === */
/* === SVG: α и 2α на единичной окружности (только геометрия) === */
let svgDouble = '';
if(A){
const c = A.tri.canvas({id:'p11-d', W:360, H:380, R:120});
const c = A.tri.canvas({id:'p11-d', W:360, H:340, R:120});
const ang = 35 * Math.PI / 180; /* α = 35° */
const ang2 = 2 * ang; /* 2α = 70° */
let s = c.open
@@ -2609,20 +2639,27 @@ function buildP11(){
+ c.radius(ang2, {color:'#7c3aed', width:2.5})
+ c.point(ang, {color:'#0d9488', label:'P_α', labelOffset:20, fontSize:12, labelColor:'#0f766e'})
+ c.point(ang2, {color:'#7c3aed', label:'P_{2α}', labelOffset:20, fontSize:12, labelColor:'#6d28d9'})
+ '<rect x="22" y="320" width="316" height="50" rx="10" fill="rgba(13,148,136,.10)" stroke="#0d9488" stroke-width="2"/>'
+ '<text x="'+(c.W/2)+'" y="338" text-anchor="middle" font-size="11" font-family="JetBrains Mono,monospace" font-weight="700" fill="#0f766e">sin 2α = 2 sin α · cos α</text>'
+ '<text x="'+(c.W/2)+'" y="358" text-anchor="middle" font-size="11" font-family="JetBrains Mono,monospace" font-weight="700" fill="#0f766e">cos 2α = cos²α sin²α = 1 2sin²α = 2cos²α 1</text>'
+ c.close;
svgDouble = s;
}
/* === Плакат: 3 формулы двойного аргумента (HTML + KaTeX) === */
const plateDouble = '<div class="formula-plate">'
+ '<div class="formula-plate-head teal">'
+ '<div class="formula-plate-title">3 формулы двойного аргумента</div>'
+ '<div class="formula-plate-sub">это частный случай формул сложения при $\\beta = \\alpha$</div>'
+ '</div>'
+ '<div class="formula-plate-body">'
+ '<div class="formula-row">$\\sin 2\\alpha = 2\\sin\\alpha \\cos\\alpha$</div>'
+ '<div class="formula-row alt">$\\cos 2\\alpha = \\cos^2\\alpha - \\sin^2\\alpha = 1 - 2\\sin^2\\alpha = 2\\cos^2\\alpha - 1$</div>'
+ '<div class="formula-row alt2">$\\tg 2\\alpha = \\dfrac{2\\tg\\alpha}{1 - \\tg^2\\alpha}$</div>'
+ '</div>'
+ '</div>';
html += makeCard('rule', 'Формулы двойного аргумента', '11.1', `
<p>Это частный случай формул сложения при $\\beta = \\alpha$:</p>
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px;font-size:1.1rem;text-align:center"><b>$\\sin 2\\alpha = 2\\sin\\alpha\\cos\\alpha$</b></p>
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px;font-size:1.1rem;text-align:center"><b>$\\cos 2\\alpha = \\cos^2\\alpha - \\sin^2\\alpha$</b></p>
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px;font-size:1.1rem;text-align:center"><b>$\\tg 2\\alpha = \\dfrac{2\\tg\\alpha}{1 - \\tg^2\\alpha}$</b></p>
${plateDouble}
<div class="svg-host">${svgDouble}</div>
<p><b>Вывод.</b> $\\sin 2\\alpha = \\sin(\\alpha + \\alpha) = \\sin\\alpha\\cos\\alpha + \\cos\\alpha\\sin\\alpha = 2\\sin\\alpha\\cos\\alpha$.</p>`);
<p><b>Вывод.</b> $\\sin 2\\alpha = \\sin(\\alpha + \\alpha) = \\sin\\alpha\\cos\\alpha + \\cos\\alpha\\sin\\alpha = 2\\sin\\alpha\\cos\\alpha$. Аналогично для $\\cos 2\\alpha$ и $\\tg 2\\alpha$.</p>`);
html += makeCard('rule', 'Три формы для cos 2α', '11.2', `
<p>Используя $\\sin^2\\alpha + \\cos^2\\alpha = 1$, переписываем по-разному:</p>
@@ -2720,20 +2757,25 @@ function buildP12(){
const box = document.getElementById('p12-body');
let html = '';
const svgFormulas =
'<svg viewBox="0 0 580 280" preserveAspectRatio="xMidYMid meet" style="width:100%;height:auto;display:block;margin:0 auto;background:#fff;border-radius:10px;border:1px solid #e2e8f0">'
+ '<rect x="0" y="0" width="580" height="44" fill="rgba(124,58,237,.08)"/>'
+ '<text x="290" y="22" text-anchor="middle" font-size="14" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#7c3aed">4 ФОРМУЛЫ: СУММА → ПРОИЗВЕДЕНИЕ</text>'
+ '<text x="290" y="38" text-anchor="middle" font-size="10" font-family="Inter,sans-serif" font-style="italic" fill="#64748b">структура: 2 · функция полусуммы · функция полуразности</text>'
+ '<text x="40" y="82" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#0d9488">sin α + sin β = 2 · sin((α+β)/2) · cos((α−β)/2)</text>'
+ '<text x="40" y="112" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#0d9488">sin α sin β = 2 · sin((α−β)/2) · cos((α+β)/2)</text>'
+ '<text x="40" y="142" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#0891b2">cos α + cos β = 2 · cos((α+β)/2) · cos((α−β)/2)</text>'
+ '<text x="40" y="172" font-size="13" font-family="JetBrains Mono,monospace" font-weight="700" fill="#dc2626">cos α cos β = 2 · sin((α+β)/2) · sin((α−β)/2)</text>'
+ '<rect x="20" y="200" width="540" height="64" rx="10" fill="rgba(124,58,237,.08)" stroke="#7c3aed" stroke-width="1.5"/>'
+ '<text x="290" y="218" text-anchor="middle" font-size="10" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#6d28d9" letter-spacing="1px">МНЕМОНИКА</text>'
+ '<text x="40" y="240" font-size="11" font-family="Inter,sans-serif" font-weight="600" fill="#1e293b">• sin±sin → sin·cos (порядок «полусуммы / полуразности» зависит от знака)</text>'
+ '<text x="40" y="258" font-size="11" font-family="Inter,sans-serif" font-weight="600" fill="#1e293b">• cos+cos → cos·cos, coscos → sin·sin (минус снаружи!)</text>'
+ '</svg>';
const svgFormulas = '<div class="formula-plate">'
+ '<div class="formula-plate-head violet">'
+ '<div class="formula-plate-title">4 формулы: сумма → произведение</div>'
+ '<div class="formula-plate-sub">структура: 2 · функция полусуммы · функция полуразности</div>'
+ '</div>'
+ '<div class="formula-plate-body">'
+ '<div class="formula-row">$\\sin\\alpha + \\sin\\beta = 2 \\sin\\dfrac{\\alpha+\\beta}{2} \\cos\\dfrac{\\alpha-\\beta}{2}$</div>'
+ '<div class="formula-row">$\\sin\\alpha - \\sin\\beta = 2 \\sin\\dfrac{\\alpha-\\beta}{2} \\cos\\dfrac{\\alpha+\\beta}{2}$</div>'
+ '<div class="formula-row alt2">$\\cos\\alpha + \\cos\\beta = 2 \\cos\\dfrac{\\alpha+\\beta}{2} \\cos\\dfrac{\\alpha-\\beta}{2}$</div>'
+ '<div class="formula-row danger">$\\cos\\alpha - \\cos\\beta = -2 \\sin\\dfrac{\\alpha+\\beta}{2} \\sin\\dfrac{\\alpha-\\beta}{2}$</div>'
+ '</div>'
+ '<div class="formula-mnem">'
+ '<div class="formula-mnem-title">Мнемоника</div>'
+ '<ul>'
+ '<li><b>$\\sin \\pm \\sin \\to \\sin \\cdot \\cos$</b> (порядок «полусуммы/полуразности» зависит от знака)</li>'
+ '<li><b>$\\cos + \\cos \\to \\cos \\cdot \\cos$</b>, &nbsp; <b>$\\cos - \\cos \\to -\\sin \\cdot \\sin$</b> (минус снаружи!)</li>'
+ '</ul>'
+ '</div>'
+ '</div>';
html += makeCard('rule', '4 формулы преобразования', '12.1', `
<p>Эти формулы превращают <b>сумму</b> (или разность) тригонометрических функций в <b>произведение</b>.</p>