feat(sim-builder): улучшение P4 — UI билдера: color-пикеры, контролы стиля, редактор кривых, z-order/дубль/видимость

This commit is contained in:
Maxim Dolgolyov
2026-06-13 14:46:14 +03:00
parent 69e219ae8c
commit b6f854fc77
5 changed files with 602 additions and 59 deletions
+38
View File
@@ -1,6 +1,39 @@
# Feature Context: Конструктор симуляций (SimForge)
## Current State
- **РАУНД УЛУЧШЕНИЙ (IMPROVEMENTS.md) — P4 «UI билдера + контролы стиля» РЕАЛИЗОВАН** (рабочее дерево, не
закоммичено; ветка `feature/sim-builder`). Файлы: только `frontend/sim-builder.html` + `frontend/js/sim-builder.js`.
`_sim_engine.js`/`js/api.js`/lab.* НЕ тронуты — билдер лишь генерит спеку, которую движок (P2/P3) уже умеет рисовать.
- **Контролы стиля объекта** (блок «Стиль», `STYLE_FOR[type]`): слайдер непрозр.(`opacity` 0..1),
select `lineStyle`(solid/dashed/dotted), `pointStyle`(только point), тумблер `glow`, тумблер градиент-
заливки(circle/rect → `gradient:[c0,c1]`). Цвета — `colorCtl`: нативный `<input type=color>` + текст
(источник истины, держит rgba/named) + очистка для fill/trailColor. Синхрон — `wireColorControls`,
`toHexColor``#rrggbb`. Per-объект уже были width/color в OBJ_FIELDS — переведены на color-пикеры.
- **Редактор кривых plot** (`plotEditor`/`curveEditor`): UI-модель `{var,range_a/b,samples,trace,legend,
plotFill,plotMarker,curves:[{expr,color,label,width,lineStyle,opacity,fill,fillColor,marker}]}`. Список
кривых (add/del, минимум 1), на кривую все P3-поля + fx-палитра, plot-уровневые fill/marker/легенда.
`loadPlot` (spec→UI: curves[]→exprs[]→legacy expr; легаси plot-level width/lineStyle/opacity → в кривую),
`normalizePlotForSpec`+`stripCurve` (UI→spec). Одиночная простая кривая → легаси `{expr,color}`, иначе
`curves:[...]`. `legend:false` эмитится только при выкл.
- **Список объектов/графиков**: z-order вверх/вниз (порядок массива = порядок отрисовки), видимость
(`hidden:true` — чисто билдерский флаг, фильтруется в `buildSpec`, движок не знает), дублировать
(deep-clone+новый `_uid`, `id+'_copy'`), удалить. Иконки — новые inline SVG `.ic` (up/down/copy/eye/eyeOff/clearX).
- **Минимизация спеки + стабильный round-trip**: `stripObj.isDefaultStyle` выбрасывает дефолты
(glow:false, lineStyle:'solid', pointStyle:'filled', opacity:1, trail/closed:false) и `hidden`. Save→load→
save идемпотентен (loadFromSim восстанавливает дефолты из контролов).
- **Дизайн/мобайл**: новые CSS-классы в ls.css-стиле (`.sbu-obj-style`/`.sbu-style-row`/`.sbu-color-*`/
`.sbu-range`/`.sbu-curve(s)`/`.is-hidden`/`.sbu-grad-row`); заголовок объекта flex-wrap + 26px-кнопки;
медиа ≤920px (раскладка) + новый ≤560px (поля/стили в один столбец). Пустые состояния дополнены.
- **Безопасность**: выражения только через `SimExpr.compile`; цвета попадают лишь в спеку (canvas-стоки
движка), DOM-style с польз.цветом не используется; eval/new Function — нет.
- Верификация: `node --check` sim-builder.js + извлечённого инлайна html — OK; эмодзи нет (скан кодпойнтов
обоих файлов — 0); eval/new Function — 0; headless vm-смоук (DOM/SimExpr-стаб) 27+12 PASS: стили объекта в
спеке, round-trip объектов идемпотентен ×2, plot с 2 кривыми (label/marker/lineStyle/opacity/fill-цвет/
range/samples) + round-trip ×2, легаси-одиночная кривая → легаси-форма + round-trip, hidden исключает из
спеки, z-order=порядок массива, дефолты-стрип; +шаблонные легаси-plot save→load→save стабильны (2 PASS).
Temp удалены. git status: тронуты только sim-builder.html и sim-builder.js.
- **Следующее (P5):** прямое манипулирование на сцене (drag всех типов + snap-к-сетке + выравнивание) и
undo/redo. Потребуются правки `_sim_engine.js` (хит-тесты/ручки) + `sim-builder.js` (стек снапшотов `this.st`).
- **РАУНД УЛУЧШЕНИЙ (IMPROVEMENTS.md) — P3 «Графики/диаграммы» РЕАЛИЗОВАН** (рабочее дерево, не
закоммичено; ветка `feature/sim-builder`). Файл: только `frontend/js/labs/_sim_engine.js`. Расширен
`_drawPlot` + ветка `type==='plot'` в `_prepareObjects`. Оси/сетка/подписи уже из P1 — не дублировались.
@@ -235,6 +268,11 @@
- Reuse > переписывание: сначала смотреть `_fx_motion`, `_graph_panel`, `graph.js`.
## RESUME STATE
- **РАУНД УЛУЧШЕНИЙ (IMPROVEMENTS.md):** P1+P2+P3 закоммичены; **P4 «UI билдера + контролы стиля»
РЕАЛИЗОВАН** (рабочее дерево, не закоммичено — ждёт ревьюера/оркестратора). Файлы: только
`frontend/sim-builder.html` + `frontend/js/sim-builder.js`. Дальше — независимый ревью P4, затем P5
(прямое манипулирование на сцене для всех типов + snap/выравнивание + undo/redo; правки `_sim_engine.js`
+ `sim-builder.js`). Контракт стилей/кривых из P2/P3-handoff полностью покрыт контролами билдера.
- Последний коммит фичи: — (Ф0..Ф7 ВСЕ реализованы, ещё не закоммичены — ждут оркестратора)
- Текущая фаза: Phase 7 — Доска онлайн-урока (✅ Implemented, pending commit) — ФИНАЛЬНАЯ.
Дальше: Final Review (final-reviewer + security review) → коммит всех фаз → merge в master.
+32 -2
View File
@@ -93,9 +93,39 @@
- **На P4 (билдер):** дать этим полям контролы — список кривых (добавить/удалить, expr + color-picker +
label + width + lineStyle + opacity + fill toggle/color + marker select), plot-уровневые fill/marker,
тумблер легенды. Хелпер `_markerStyle`/`_fillAlpha` — модульного уровня, рядом с `_dashFor`/`_opacity`.
- [ ] **P4 — UI билдера + контролы стиля.** Дизайн-полировка панелей/тулбара (ls.css), нативные color-
- [x] **P4 — UI билдера + контролы стиля.** Дизайн-полировка панелей/тулбара (ls.css), нативные color-
пикеры + opacity/width/dash/линестиль на объект, z-order/дублирование/видимость объектов, пустые
состояния, мобайл. Файлы: `frontend/sim-builder.html`, `frontend/js/sim-builder.js`.
**Handoff (P4 → P5):**
- **Контролы стиля объекта** (блок «Стиль» в каждом редакторе, `STYLE_FOR[type]` решает набор):
`rangeCtl` непрозр. (слайдер 0..1 → `opacity`), `selectCtl` линия (`lineStyle` solid/dashed/dotted),
стиль точки (`pointStyle`, только point), тумблер `glow`, тумблер «Градиент-заливка» (circle/rect →
`gradient:[c0,c1]`, две пары color-инпутов). Цвета — новый `colorCtl`: нативный `<input type=color>`
+ текстовое поле (источник истины, поддерживает rgba/named) + кнопка очистки для fill/trailColor
(«нет заливки»). Синхрон пикер↔текст — `Builder.wireColorControls(row)` (текст диспатчит `input`,
основной `data-of`/`data-cvf` обработчик ловит). `toHexColor` приводит к `#rrggbb` для нативного пикера.
- **Редактор кривых plot** (`plotEditor`/`curveEditor`): UI-модель plot = `{var, range_a/b, samples,
trace, legend, plotFill, plotMarker, curves:[...]}`. Кривая = `{_uid, expr, color, label, width,
lineStyle, opacity, fill(bool), fillColor, marker}`. Список кривых (добавить `[data-curveadd]` /
удалить `[data-curvedel]`, минимум 1), на кривую — expr+fx, color, label, width, lineStyle, marker,
opacity, fill+цвет. Plot-уровневые `plotFill`/`plotMarker`/легенда. `loadPlot` нормализует
spec→UI (curves[]→exprs[]→legacy expr; легаси plot-level width/lineStyle/opacity наследуются кривой),
`normalizePlotForSpec`+`stripCurve` собирают обратно: **одиночная «простая» кривая (только expr+color,
нет plot-fill/marker) → легаси-форма** `{expr,color}`; иначе `curves:[...]`. `legend:false` эмитится
только при выключенной легенде.
- **Список объектов**: в шапке каждого — z-order вверх/вниз (`[data-oup]`/`[data-odown]`, порядок в
массиве = порядок отрисовки; крайние disabled), видимость (`[data-ohide]` → `o.hidden=true`),
дублировать (`[data-odup]`, deep-clone + новый `_uid`, `id+'_copy'`), удалить. Аналогично у plot.
- **hidden — чисто на стороне билдера** (движок не трогали): `buildSpec` фильтрует объекты/plot с
`hidden`; `stripObj.isDefaultStyle` гарантирует, что `hidden`/дефолты стиля (glow:false, lineStyle:
'solid', pointStyle:'filled', opacity:1, trail/closed:false) НЕ попадают в спеку → спека минимальна,
round-trip save→load→save идемпотентен (проверено vm-смоуком 27+12+2 PASS).
- **На P5 (прямое манипулирование + история):** в билдере сейчас есть только drag x/y point/circle/label/
readout/rect и конца segment/vector (`bindPreviewDrag` через `inst._toWorld`). Расширять до всех типов
+ snap-к-сетке + выравнивание (нужны правки `_sim_engine.js` — хит-тесты/ручки). Undo/redo: состояние
= `this.st` (сериализуемо JSON); снимать снапшот при `onAdd`/удалении/правке (debounce) — стек в
Builder, перерисовка `renderPanels`+`scheduleRemount`. Идентичность спеки между билдами уже гарантирована.
- [ ] **P5 — Прямое манипулирование на сцене + история.** Drag всех типов (не только point/circle),
snap-к-сетке, выравнивание; undo/redo в билдере. Файлы: `_sim_engine.js`, `frontend/js/sim-builder.js`.
@@ -105,5 +135,5 @@
| P1 Working field | Done | ✅ PASS | ✅ |
| P2 Object graphics | Done | ✅ PASS | ✅ |
| P3 Charts | Done | ✅ PASS | ✅ |
| P4 Builder UI | ⬜ | ⬜ | |
| P4 Builder UI | Done | ✅ PASS | |
| P5 Direct manip + history | ⬜ | ⬜ | ⬜ |