docs(plans): план улучшения визуала и интерактивов Физики 9
This commit is contained in:
@@ -0,0 +1,230 @@
|
|||||||
|
# План: визуальное оформление и улучшение интерактивов — Физика 9
|
||||||
|
|
||||||
|
**Цель:** довести Физику 9 до качества Физики 8/10/11 — единый стиль, плавные анимации, читаемые подписи, тёмная тема, удалить Font Awesome, отрефакторить «голые» канвасы.
|
||||||
|
|
||||||
|
**Исходное состояние:** 5 глав (`physics_9_ch1..ch5.html`) + монолитный `phys9_legacy.js` (5952 строк) + 36 параграфов + 5 финалов + 12 ЛР. Legacy-код — это извлечённый монолит, всё внутри IIFE, симуляции на `<canvas>` без масштаба, цвета и подписи в стиле «школьная тетрадь».
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Аудит текущего состояния
|
||||||
|
|
||||||
|
### Что уже работает (после фиксов сегодня)
|
||||||
|
- Контент глав отображается, навигация по § работает.
|
||||||
|
- Подключён `phys9_legacy.js` во все 5 ch-файлов.
|
||||||
|
- Хуки `ensureBuilt` инжектят блок задач из POOLS[pN] под каждый §.
|
||||||
|
- Экспорт `window.POOLS`, `window.STATE`, `window.startAnim*`, `window.upd*`, `window.draw*`.
|
||||||
|
- Все 36 пулов `TASKS_P1..P36 + TASKS_HARD` доступны.
|
||||||
|
|
||||||
|
### Что не так визуально
|
||||||
|
| # | Проблема | Где | Влияние |
|
||||||
|
|---|----------|-----|---------|
|
||||||
|
| 1 | **Font Awesome** иконки (`fas fa-*`) — нарушение проектной политики «только inline SVG `.ic`» | `phys9_legacy.js` (8 мест) + ch1 (1) | Несогласованность с остальным каталогом |
|
||||||
|
| 2 | **30+ канвасов без масштаба** — `cv1..cv30` рисуются по px-координатам, не подписаны единицами, цвета случайные | `phys9_legacy.js` все `upd*` / `draw*` | Не читаются на мобильных, выглядят «школьно» |
|
||||||
|
| 3 | **Нет цветовой кодировки** по типу величины (масса, скорость, сила) | везде | Учащийся не отличает кинематические/динамические величины |
|
||||||
|
| 4 | **Тёмная тема не покрывает legacy-элементы** — стрелки, оси, текст всегда чёрные | canvas-рендер в legacy | На тёмной теме нечитаемо |
|
||||||
|
| 5 | **Подписи на канвасах**: `Arial 12px`, мелко, не масштабируется | `ctx.font = '12px sans-serif'` | Плохо на больших экранах и на мобильных |
|
||||||
|
| 6 | **Кнопки-управление симуляциями** разнородные: где `<button class="btn">`, где `<input type="range">` без подписей | разные параграфы | Нет единого UX |
|
||||||
|
| 7 | **Анимации без паузы / сброса** — startAnim1, startAnim15 запускаются автоматически, остановить нельзя | `phys9_legacy.js:start*` | Жжёт CPU на фоне |
|
||||||
|
| 8 | **Графики $T(t)$, $v(t)$ нарисованы вручную** через `lineTo` — без сетки, без подписей осей в СИ | `upd9`, `upd11`, `upd13` | Бесполезны для понимания |
|
||||||
|
| 9 | **Нет «3 видов задач»** — есть только пул задач из POOLS, нет калькуляторов и DnD-сортировок (как в Физике 8/10) | архитектура | Меньше вовлечения |
|
||||||
|
| 10 | **CSS-перегружен** — есть `.fcard`, `.formula-grid`, `.section-title`, `.para-hero`, `.ph-tag`, `.ph-tags`, `.ph-formula` — устаревшая визуальная стилистика | inline `<style>` в ch1..ch5 | Тяжело сопровождать |
|
||||||
|
| 11 | **Финалы** глав (`final1..final5`) — заглушки без интегрированных боссов и ачивок | builders в ch | Нет «магистра» главы |
|
||||||
|
| 12 | **ЛР 1-12 в ch5** — ссылаются на `cvLab11`, но `drawLab11` пишет напрямую координаты грузов в граммах с маленькими подписями | `phys9_legacy.js` | Не похоже на «лабораторный отчёт» |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 Целевой облик (как у Физики 8/10/11)
|
||||||
|
|
||||||
|
1. **SVG-канвасы вместо `<canvas>`** где можно — векторные, масштабируемые, темнее/светлее по теме.
|
||||||
|
2. **Цветовая кодировка:**
|
||||||
|
- Скорость $\vec v$ — голубой `#0891b2`
|
||||||
|
- Ускорение $\vec a$ — оранжевый `#ea580c`
|
||||||
|
- Сила $\vec F$ — зелёный `#10b981`
|
||||||
|
- Масса/тело — серый `#475569`
|
||||||
|
- Сила тяжести — синий `#2563eb`
|
||||||
|
- Сила трения — фиолетовый `#7c3aed`
|
||||||
|
3. **Хелперы** общие с другими физиками: `phys.js` (`drawArrow`, `axes2D`, `plotFunc`).
|
||||||
|
4. **Каждый интерактив:**
|
||||||
|
- Slider'ы с подписями единиц (м/с, м/с², Н)
|
||||||
|
- Кнопки **Пауза / Сброс**
|
||||||
|
- `cancelAnimationFrame` при unmount
|
||||||
|
- Текстовая «выкладка» текущих значений в `.score-display`
|
||||||
|
5. **Тёмная тема:** SVG использует `currentColor` или CSS-переменные, не хардкод `#000`.
|
||||||
|
6. **Финал главы:** шпаргалка + 5-10 интегрированных боссов + ачивка `master_chN`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Фазы реализации
|
||||||
|
|
||||||
|
### Phase 0 — Аудит и подготовка (1 коммит)
|
||||||
|
- [ ] Список всех 30+ канвасов с описанием: что симулирует, какие параметры, какой §
|
||||||
|
- [ ] Список всех `upd*` / `draw*` / `startAnim*` с их вход/выход
|
||||||
|
- [ ] Решение: какие canvas → SVG, какие оставить (большие частицы/тысячи точек)
|
||||||
|
- [ ] Перечислить все `fa-*` → план замены на inline SVG `.ic`
|
||||||
|
- [ ] Документ: `plans/textbooks-9/PHYS9_INTERACTIVES_INVENTORY.md`
|
||||||
|
|
||||||
|
### Phase 1 — Удаление Font Awesome из физики 9 (1 коммит)
|
||||||
|
- [ ] Заменить все 8 вхождений `<i class="fas fa-*">` в `phys9_legacy.js` на inline SVG
|
||||||
|
- [ ] Заменить 1 вхождение в `physics_9_ch1.html`
|
||||||
|
- [ ] Удалить `<link rel=stylesheet ... font-awesome>` из ch-страниц
|
||||||
|
- [ ] Smoke-test: открыть все 5 ch — иконки сохранились
|
||||||
|
|
||||||
|
### Phase 2 — Цветовая кодировка и легенда (1 коммит)
|
||||||
|
- [ ] Создать `frontend/js/phys9_palette.js` — единый объект `PHYS9_COLORS`
|
||||||
|
- [ ] Перенести жёстко закодированные цвета (`fillStyle = '#xxx'`) на ссылки `PHYS9_COLORS.velocity` и т.д.
|
||||||
|
- [ ] Создать `frontend/css/phys9-canvas.css` — переменные для тёмной темы
|
||||||
|
- [ ] Использовать `getComputedStyle` для текущего цвета (поддержка тёмной темы автоматом)
|
||||||
|
|
||||||
|
### Phase 3 — Стандарт SVG-визуализации (3-5 коммитов)
|
||||||
|
Большинство канвасов — это статические сцены: брусок + сила + стрелка. Их можно перевести на SVG.
|
||||||
|
|
||||||
|
**Канвасы-кандидаты на SVG:**
|
||||||
|
- §3 `drawArrow3` — вектор силы (просто SVG `<line>` + `<polygon>`)
|
||||||
|
- §10 `upd10` (касательная/нормальная скорость)
|
||||||
|
- §11 `upd11` (равноуск. движение, графики $v(t)$, $s(t)$)
|
||||||
|
- §19 `drawSpring19` (пружина)
|
||||||
|
- §20 `drawFriction20` (брусок + трение)
|
||||||
|
- §23 `drawGravity23` (сила тяжести)
|
||||||
|
- §24 `drawElevator24` (лифт + вес)
|
||||||
|
- §25 `drawSeesaw25` (рычаг)
|
||||||
|
- §26 `drawLever26` (рычаг 2-го рода)
|
||||||
|
- §28 `drawEquilibrium28` (рычаг + плечи)
|
||||||
|
- §29 `drawArchimedes29` (плавание тел)
|
||||||
|
- §30 `drawShip30` (корабль)
|
||||||
|
|
||||||
|
**Оставить на canvas (анимации с многими точками):**
|
||||||
|
- §1 `startAnim1` — Броуновское движение, 30+ частиц
|
||||||
|
- §15 `startAnim15` — гравитация / движение планет
|
||||||
|
- §17 `startAnim17` — равномерное движение по окружности
|
||||||
|
- §22 `drawAngularThrow22` — баллистика с траекторией
|
||||||
|
|
||||||
|
Каждый SVG-перенос:
|
||||||
|
- 1 коммит на 2-3 канваса
|
||||||
|
- Использовать `phys.js` хелперы (`drawArrow`, `axes2D`, `plotFunc`)
|
||||||
|
- Сохранить функцию-обёртку с тем же именем, чтобы legacy кнопки `onclick="upd23()"` продолжали работать
|
||||||
|
|
||||||
|
### Phase 4 — Графики $T(t)$, $v(t)$, $s(t)$ через `phys.js` (2 коммита)
|
||||||
|
- [ ] §9 — графики координаты от времени
|
||||||
|
- [ ] §11 — равноуск. движение, $v$-$t$, $s$-$t$
|
||||||
|
- [ ] §13 — графики ускорения
|
||||||
|
- [ ] §14 — графики $v$ при разных $a$
|
||||||
|
|
||||||
|
Унифицировать оси (СИ, шкала, надписи), цвета (`PHYS9_COLORS`), легенду.
|
||||||
|
|
||||||
|
### Phase 5 — Тёмная тема для всех визуализаций (1 коммит)
|
||||||
|
- [ ] Все SVG: использовать `currentColor` / CSS-переменные
|
||||||
|
- [ ] Canvas: проверять `document.documentElement.classList.contains('dark')` и менять `ctx.strokeStyle`
|
||||||
|
- [ ] Сетка + оси: `var(--border)` вместо `#ccc`
|
||||||
|
- [ ] Текстовые подписи: `var(--text)` вместо `#000`
|
||||||
|
|
||||||
|
### Phase 6 — Управление симуляциями (2 коммита)
|
||||||
|
- [ ] Все `startAnim*` получают кнопки **Пауза/Запуск/Сброс**
|
||||||
|
- [ ] При смене параграфа (`goTo`) — отменять текущие `requestAnimationFrame`
|
||||||
|
- [ ] Slider'ы — с подписями единиц (м/с, °, кг)
|
||||||
|
- [ ] Текстовая выкладка: `.score-display` с текущими значениями
|
||||||
|
|
||||||
|
### Phase 7 — Калькуляторы и DnD как в Физике 8/10 (3-5 коммитов)
|
||||||
|
В монолите Физики 9 нет калькуляторов и DnD-сортировок — только пулы задач. Это упущение.
|
||||||
|
|
||||||
|
**Добавить для каждой главы 1-2 калькулятора:**
|
||||||
|
- Глава 1: калькулятор $s = v_0 t + at^2/2$ + DnD «равномерное / равноуск.»
|
||||||
|
- Глава 2: калькулятор $F = ma$ + DnD «причина / следствие»
|
||||||
|
- Глава 3: калькулятор плечей рычага + DnD «выигрыш в силе / расстоянии»
|
||||||
|
- Глава 4: калькулятор Архимеда + DnD «плавает / тонет»
|
||||||
|
- Глава 5: калькулятор периода маятника + DnD «механ. / эл. колебания»
|
||||||
|
|
||||||
|
Каждый — отдельная `<div class="wg">` карточка под секцией §, как в Физике 8.
|
||||||
|
|
||||||
|
### Phase 8 — Финалы глав (5 коммитов, по 1 на главу)
|
||||||
|
Сейчас `final1..final5` — пустышки. Сделать как у Физики 8:
|
||||||
|
- Шпаргалка по главе (6-10 формул)
|
||||||
|
- 5-10 интегрированных боссов (числовые задачи с подсказками)
|
||||||
|
- Ачивка `physics9_chN_master` (+50 XP)
|
||||||
|
- Кнопка перехода к следующей главе
|
||||||
|
|
||||||
|
### Phase 9 — Лабораторный практикум ch5 (1-2 коммита)
|
||||||
|
12 ЛР сейчас — голые таблицы. Сделать как у Физики 8:
|
||||||
|
- Цель работы (карточка)
|
||||||
|
- Оборудование (список)
|
||||||
|
- Ход работы (нумерованный)
|
||||||
|
- Виртуальная установка (SVG-симуляция)
|
||||||
|
- Таблица измерений с автозаполнением
|
||||||
|
- Калькулятор результата
|
||||||
|
- Кнопка «Сдать работу (+30 XP)»
|
||||||
|
- Ачивка `physics9_lab_master` (+50 XP) после всех 12
|
||||||
|
|
||||||
|
### Phase 10 — Респонсивность и a11y (1 коммит)
|
||||||
|
- [ ] Все SVG/canvas с `width:100%;height:auto;max-width:600px`
|
||||||
|
- [ ] Шрифты подписей: `clamp(11px, 1vw, 14px)`
|
||||||
|
- [ ] `aria-label` на интерактивных SVG-элементах
|
||||||
|
- [ ] `role="img"` на статических SVG
|
||||||
|
|
||||||
|
### Phase 11 — Удаление legacy CSS (1 коммит)
|
||||||
|
- [ ] Перенести стили `.fcard`, `.formula-grid`, `.section-title`, `.para-hero`, `.ph-tag`, `.ph-tags`, `.ph-formula` в `frontend/css/phys9-theme.css`
|
||||||
|
- [ ] Удалить дублирование из 5 ch-файлов (CSS сейчас инлайн в каждом)
|
||||||
|
- [ ] Подключить общий файл
|
||||||
|
|
||||||
|
### Phase 12 — Полное ревью + KaTeX-аудит (1 коммит)
|
||||||
|
- [ ] Smoke-test всех 36 § в браузере (light + dark)
|
||||||
|
- [ ] KaTeX-аудит: `[^\\]\\[a-zA-Z]{2,}` в JS-блоках (одинарный backslash где не надо)
|
||||||
|
- [ ] JS parse-check всех 5 ch + legacy.js
|
||||||
|
- [ ] Проверка: ни одного `console.log/warn/error` debug-вызова в hot-path
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Оценка объёма
|
||||||
|
|
||||||
|
| Phase | Коммитов | LOC изм. | Приоритет |
|
||||||
|
|-------|----------|----------|-----------|
|
||||||
|
| 0 — Аудит | 1 | 300 (документ) | КРИТИЧНО |
|
||||||
|
| 1 — Удаление FA | 1 | ~30 | КРИТИЧНО |
|
||||||
|
| 2 — Цветовая кодировка | 1 | ~200 | ВЫСОКО |
|
||||||
|
| 3 — SVG визуализация | 5 | ~1500 | ВЫСОКО |
|
||||||
|
| 4 — Графики | 2 | ~400 | ВЫСОКО |
|
||||||
|
| 5 — Тёмная тема | 1 | ~200 | СРЕДНЕ |
|
||||||
|
| 6 — Управление симуляциями | 2 | ~300 | СРЕДНЕ |
|
||||||
|
| 7 — Калькуляторы / DnD | 5 | ~1500 | СРЕДНЕ |
|
||||||
|
| 8 — Финалы глав | 5 | ~1000 | ВЫСОКО |
|
||||||
|
| 9 — ЛР практикум | 2 | ~600 | СРЕДНЕ |
|
||||||
|
| 10 — Респонсив / a11y | 1 | ~200 | НИЗКО |
|
||||||
|
| 11 — Очистка CSS | 1 | ~100 (-) | НИЗКО |
|
||||||
|
| 12 — Финальное ревью | 1 | ~50 | КРИТИЧНО |
|
||||||
|
| **Итого** | **~28 коммитов** | **~6 400 LOC** | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ Архитектурное предупреждение
|
||||||
|
|
||||||
|
`phys9_legacy.js` **генерируется** скриптом [backend/scripts/extract_phys9_legacy.cjs](backend/scripts/extract_phys9_legacy.cjs) из монолита `physics_9.html`. **Все ручные правки исчезнут**, если кто-то запустит экстрактор повторно.
|
||||||
|
|
||||||
|
**Два пути:**
|
||||||
|
|
||||||
|
**Путь A (быстрый, hacky):** править `phys9_legacy.js` напрямую и заморозить экстрактор (переименовать с пометкой `DO_NOT_RUN_anymore.cjs`).
|
||||||
|
|
||||||
|
**Путь B (правильный, долгий):** переписать ch1..ch5 на конвенцию Физики 8/10:
|
||||||
|
- Каждый параграф — `build_pN()` в inline `<script>`, без legacy
|
||||||
|
- POOLS_PN перенести в каждую главу-файл как локальный объект
|
||||||
|
- Удалить `phys9_legacy.js` целиком
|
||||||
|
- Тогда хелперы из `phys.js` будут использоваться нативно
|
||||||
|
|
||||||
|
**Рекомендация:** для критичных фиксов (Phase 1, 2, 8, 12) — путь B, в новой архитектуре. Для остальных — путь A, с заморозкой экстрактора.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎬 Запуск
|
||||||
|
|
||||||
|
1. **Phase 0** — сделать инвентаризацию (`PHYS9_INTERACTIVES_INVENTORY.md`).
|
||||||
|
2. **Phase 1** — удалить Font Awesome (быстрая победа, заметна сразу).
|
||||||
|
3. Решить путь A или B.
|
||||||
|
4. Если B — начать с ch1 (большой объём — 14 §, можно как pilot).
|
||||||
|
5. Дальше по приоритету: финалы → SVG-визуализации → калькуляторы.
|
||||||
|
|
||||||
|
После Phase 1-3 курс уже будет выглядеть «как остальные учебники проекта». Phase 4-9 — углубление качества. Phase 10-12 — полировка.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 Связанные документы
|
||||||
|
|
||||||
|
- [PLAN_PHYSICS_9.md](PLAN_PHYSICS_9.md) — исходный план учебника
|
||||||
|
- [PLAN_PHYSICS_8.md](../textbooks-8/PLAN_PHYSICS_8.md) — образец архитектуры
|
||||||
|
- [PLAN_PHYSICS_10.md](../textbooks-10/PLAN_PHYSICS_10.md) — образец визуализации (canvas + SVG)
|
||||||
Reference in New Issue
Block a user