docs: remove originals after the move to docs/reviews and legacy

Issue: #142
User-Visible: no
This commit is contained in:
Matysh
2026-08-14 11:41:05 +03:00
parent b989c84b71
commit 782ff54e0f
-301
View File
@@ -1,301 +0,0 @@
# #89 — Опциональный объёмный 2.5D/изометрический вид плана
**Статус:** исследование завершено; черновик продуктового и технического решения
**Дата:** 2026-08-11
**Приоритет:** P1 — высокая продуктовая ценность, высокая стоимость реализации
**Область:** режим просмотра и киоск; редакторы в первую версию не входят
**Исходные референсы:** предоставленные владельцем проекта `isometric-plan-demo.zip` и изображение `photo_2026-08-11_18-30-38.jpg`
## 1. Краткое решение
Добавить в Houseplan опциональный **«Объёмный вид»** — стилизованное 2.5D-представление существующего плана с приподнятыми стенами, видимыми боковыми гранями, мягкой тенью и изометрической камерой.
Это не отдельный редактор и не новая модель плана. Комнаты, стены, проёмы, перегородки, колонны, устройства, Glow и все состояния продолжают использовать текущие данные. Меняется только способ их проекции и визуализации.
Рекомендуемая первая пользовательская версия:
- переключаемый плоский/объёмный вид;
- только режим просмотра и киоск;
- фиксированный проверенный ракурс без свободного вращения камеры;
- редакторы всегда открываются в обычном плоском виде;
- без WebGL/Three.js и без 32 копий всего SVG;
- стены строятся из канонической геометрии Houseplan, проёмы действительно вырезаются из объёма;
- Glow, солнечные лучи, заливки и hover остаются функционально теми же эффектами на плоскости пола;
- диалоги и tooltips остаются обычным экранным UI и не наклоняются вместе с планом.
## 2. Пользовательская ценность
Ценность оценивается как **очень высокая**:
- план превращается из утилитарной схемы в визуально сильный центр dashboard;
- различия стен, комнат, проёмов и внешних зон считываются быстрее;
- скриншоты и демонстрации продукта становятся существенно убедительнее;
- Houseplan получает заметное визуальное отличие от обычных floorplan-карточек;
- существующая модель данных уже содержит большую часть необходимой геометрии — пользователь не строит второй план.
При этом объёмный вид не должен становиться обязательным. Плоский вид точнее для редактирования, плотных планов и слабых устройств и остаётся полностью поддерживаемым.
## 3. Что показало исследование демо
Переданный demo — удачный визуальный proof of concept, но не готовая архитектура для Houseplan.
Он использует:
- один SVG с вручную заданной геометрией;
- CSS `perspective`, `rotateX`, `rotateZ` и `preserve-3d`;
- 32 копии одного контура стен, поднятые последовательными `translateZ`, чтобы имитировать толщину по высоте;
- отдельный верхний контур стен;
- статические подписи и устройства внутри наклонённой плоскости;
- drag для вращения и wheel для масштаба.
Для маленькой статической сцены это работает и хорошо показывает продуктовый эффект. Прямой перенос подхода в Houseplan не подходит, потому что:
1. Геометрия Houseplan динамическая: смешанная толщина, T/X-стыки, перегородки, круглые и квадратные колонны, двери, окна и ворота.
2. В карточке есть тяжёлые динамические слои: Glow, spill через проёмы, солнечные лучи, hover, vacuum overlays и HTML-маркеры.
3. 20–32 копии сложных wall paths заметно увеличат DOM, raster/compositing cost и вероятность швов.
4. CSS 3D-контекст разрушается или уплощается рядом свойств, уже используемых карточкой: `filter`, opacity на предках, `clip-path`, mask и часть blend/compositing-сценариев.
5. Сейчас day/night использует `filter: brightness(...)` на `.zoomwrap`, а Glow — `mix-blend-mode: screen`; слепое помещение существующего дерева в CSS 3D создаёт высокий риск регрессий.
6. Координаты устройств и room labels сейчас считаются для плоского `viewBox` и выводятся HTML-слоем. Их нужно проецировать тем же каноническим преобразованием, иначе они разойдутся с планом.
Вывод: demo подтверждает **реализуемость и ценность визуального направления**, но production-рендерер нужно строить на геометрии Houseplan.
## 4. Рекомендуемая архитектура
### 4.1. Не полноценный 3D, а детерминированная 2.5D-проекция
Для первой версии рекомендуется обычный SVG с явной 2D-проекцией, а не CSS-стопка и не WebGL:
- floor/decor/room/glow-слои помещаются в SVG-группу с одной аффинной изометрической матрицей;
- верх стены — каноническое объединённое тело стены, спроецированное и сдвинутое на визуальную высоту;
- боковые грани — четырёхугольники, построенные из граничных рёбер wall body и вектора высоты;
- видимые боковые грани фильтруются по направлению камеры и сортируются по глубине;
- HTML-маркеры получают экранные координаты через ту же чистую функцию проекции;
- tooltips, dialogs и системные controls остаются вне проецируемой сцены.
Это позволяет сохранить обычный SVG compositor, mask/blend-поведение Glow и предсказуемую деградацию, а число элементов растёт по числу реальных граней, а не умножается на 20–32 слоя.
### 4.2. Канонические источники геометрии
Нельзя создавать вторую независимую модель стен. Рендерер обязан использовать:
- `wallBodiesGeometry()` / объединённые wall bodies из `src/wall-thickness.ts`;
- текущие opening cuts/tunnel geometry;
- существующую модель перегородок и колонн;
- текущие room polygons и decor geometry;
- текущий канонический light resolver и описанную в `docs/LIGHT.md` семантику.
Возможные новые модули:
- `src/render/isometric-projection.ts` — чистая математика проекции и обратного hit mapping;
- `src/render/isometric-walls.ts` — top/side faces и depth ordering;
- `src/render/isometric-scene.ts` — композиция слоёв;
- детерминированные fixtures/golden matrix отдельно от основной карточки.
Кэш геометрии строится по содержательному fingerprint геометрии, а не только по `_cfgEpoch`.
### 4.3. Высота стен
В модели сейчас нет полноценной высоты помещений/стен. В первой версии высота — **визуальный параметр представления**, а не архитектурный размер:
- единое безопасное значение по умолчанию;
- один общий параметр для карточки/пространства, если настройка вообще выводится пользователю;
- одинаковая высота у обычных стен, перегородок и колонн;
- виртуальные стены остаются линиями пола и не получают объём.
Не следует выводить высоту в сантиметрах: это создаст ложное обещание настоящей 3D-модели.
## 5. UX первой версии
### 5.1. Переключение
- В режиме просмотра появляется компактная кнопка с `mdi:cube-outline` и accessible name «Объёмный вид».
- Повторное нажатие возвращает «Плоский вид».
- Переключение не изменяет геометрию и не создаёт запись в command stack.
- Предпочтение вида хранится отдельно от модели плана; оно не должно создавать конфликтов совместного редактирования.
- В киоске используется настроенный вид по умолчанию; скрытая панель не должна делать возврат в плоский вид невозможным из настроек.
- Вход в любой редактор временно показывает плоский вид. После выхода восстанавливается предыдущий режим просмотра.
Плоский вид остаётся значением по умолчанию для существующих установок и fallback при ошибке/неподдерживаемом окружении.
### 5.2. Камера и навигация
MVP использует один тщательно подобранный ракурс либо 2–3 пресета. Свободное вращение и изменение tilt не входят в первую версию.
Причины:
- свободное вращение конфликтует с pan, pinch zoom, long press и кликами устройств;
- оно требует динамической сортировки граней на каждом кадре;
- маркетинговый эффект достигается фиксированным хорошим ракурсом;
- фиксированный ракурс детерминирован для golden image и поддержки.
Обычный zoom/pan сохраняется. Изменение масштаба должно быть совместимо с #82 и не менять фокус плана скачком при переключении вида.
### 5.3. Устройства и подписи
Для первой версии рекомендуется:
- позиция marker/room label проецируется вместе с планом;
- сама интерактивная карточка устройства остаётся достаточно читаемой и получает мягкую объёмную тень;
- tooltip/dialog всегда экранные и не наклоняются;
- touch target не уменьшается из-за визуального наклона;
- tab order и accessible name совпадают с плоским режимом.
Полностью «лежащие на полу» подписи красивее, но хуже читаются. Допустим компромисс: лёгкое согласование с ракурсом для подложки и screen-facing содержимое. Точный вариант выбирается по прототипу и a11y-проверке.
## 6. Поведение слоёв
| Слой/объект | Поведение в объёмном виде |
|---|---|
| Пол/заливка комнаты | Лежит на нижней плоскости, текущая семантика цвета сохраняется |
| Room hover | Затемняет заливку и подсвечивает внутренние границы без вспышки Glow |
| Физические стены | Верхняя поверхность + видимые боковые грани |
| Перегородки | Как физические стены; комнату автоматически не делят |
| Квадратные/круглые колонны | Экструдируются из своей текущей геометрии |
| Виртуальные стены | Пунктир на плоскости пола, без высоты |
| Дверь | Проём реально разрывает стену; символ состояния сохраняется. Вертикальная створка — polish-этап |
| Окно | Разрыв объёма с отдельным стилизованным оконным элементом; без моделирования реальной высоты подоконника |
| Ворота | Разрыв объёма; две наружные створки сохраняются |
| Opening tunnel fill | Цвет комнаты на полу, без швов; семантика Glow не меняется |
| Glow и spill | На плоскости пола, стеновые барьеры и проёмы работают по `docs/LIGHT.md` |
| Солнечные лучи | На плоскости пола, геометрия и настройки остаются текущими |
| Decor/backdrop | Лежит на floor plane; не создаёт объём автоматически |
| Vacuum path/outline | На floor plane; robot marker остаётся интерактивным |
| Device markers | Проецированная позиция, безопасный z-order и неизменная логика состояний |
| Tooltips/dialogs | Экранный overlay поверх сцены |
| `show_borders: false` | Невидимые стены остаются невидимыми, но продолжают влиять на площадь и свет |
## 7. Обязательные edge cases
Реализация и fixtures должны покрыть:
1. Выпуклые и вогнутые комнаты, отверстия и несколько несвязанных контуров.
2. Смешанную толщину стен, короткие сегменты, T/X-стыки и сложные объединения.
3. Проём у угла, несколько соседних проёмов, дверь/окно/ворота шире толщины стены.
4. Перегородку, примыкающую к стене без визуального шва.
5. Квадратную повёрнутую и круглую колонну.
6. Виртуальную стену между двумя толстыми стенами.
7. Комнату без физических стен и старую конфигурацию без thickness.
8. Glow с несколькими источниками, spill через открытые проёмы и hover комнаты.
9. Day/night brightness, непрозрачные/полупрозрачные заливки и additive blending.
10. Большую подложку, decor, текст, пунктирные линии и мебель.
11. Скрытые/удалённые/недоступные устройства и все режимы device presentation.
12. Touch: pinch не вызывает click, long press не оставляет phantom pan.
13. Возврат на вкладку: сцена не мигает и не пересобирается из пустого состояния.
14. Очень широкий/высокий план, detached terrace/porch и несколько пространств.
15. Светлая/тёмная тема, kiosk, reduced motion и high zoom.
## 8. Производительность и технические ограничения
- Не клонировать весь SVG или wall body десятки раз.
- Число side faces должно быть O(числу граничных рёбер), а не O(рёбра × визуальная высота).
- Pan/zoom не пересчитывает модельную геометрию; меняется только transform/viewBox.
- Геометрия стен пересчитывается только при изменении содержательного fingerprint.
- Цель на детерминированном большом fixture: плавный pan/zoom на desktop и не более 20% регрессии frame time относительно плоского вида.
- Переключение вида не должно показывать пустой/чёрный промежуточный кадр.
- При нехватке возможностей или исключении renderer карточка безопасно возвращается в плоский вид и сообщает диагностируемую причину в dev log.
- Новая тяжёлая runtime-зависимость и WebGL не допускаются без отдельного архитектурного решения.
## 9. Доступность
- «Объёмный вид» — визуальная альтернатива, не отдельный набор функций.
- Все устройства, комнаты и действия доступны с клавиатуры так же, как в плоском виде.
- Focus ring виден и не обрезается стеной/контейнером.
- Screen reader получает те же имена и состояния.
- `prefers-reduced-motion` отключает переход между проекциями, но не сам режим.
- Минимальные touch targets сохраняются в экранных координатах.
- Плоский вид остаётся fallback для пользователей, которым перспектива мешает чтению.
## 10. План реализации
### Этап 0 — технический spike, 2–4 рабочих дня
- детерминированный fixture со стенами, mixed thickness, проёмами, колонной, Glow и устройствами;
- два прототипа: CSS wall slices и явные side faces;
- замеры Chrome/Edge, Firefox и Safari/WebKit;
- проверка Glow/mask/blend, day/night и HTML overlays;
- ADR с окончательным выбором renderer.
Spike не включается пользователям и не считается завершением issue.
### Этап 1 — ship-ready фиксированный объёмный вид, 8–15 рабочих дней
- чистая математика проекции;
- floor plane, wall top и side faces;
- проёмы, перегородки и колонны;
- проекция markers/labels и pointer mapping;
- переключение view/editor/kiosk;
- кэш, fallback, unit/integration/golden/performance gates;
- RU/EN документация и changelog.
### Этап 2 — визуальный polish уровня референса, ещё 8–15 рабочих дней
- улучшенные двери, окна и ворота;
- мягкие тени/ambient depth без дорогого dynamic lighting;
- аккуратные floor/platform edges;
- доводка markers/labels и occlusion;
- дополнительные пресеты камеры и качества.
### Отдельный будущий этап — свободная камера, ещё 5–10+ рабочих дней
Свободное вращение/tilt, gesture arbitration и динамический depth sort не входят в базовый scope. Их ценность ниже, а риск заметно выше.
## 11. Оценка сложности
| Вариант | Срок | Риск | Оценка |
|---|---:|---:|---|
| Демонстрационный CSS stack на одном fixture | 2–4 дня | Средний | Хорош для spike, не для релиза |
| Production MVP с фиксированным ракурсом | 8–15 дней | Высокий | Рекомендуемый первый релиз |
| Визуально отполированный вариант уровня референса | 16–30 дней суммарно | Высокий | Реалистичная конечная цель |
| Свободная камера поверх polished renderer | +5–10 дней | Высокий | Позже, только по подтверждённой ценности |
| Настоящий WebGL/Three.js 3D renderer | 1–2+ месяца | Очень высокий | Не рекомендуется для этой цели |
Общая оценка: **L/XL, высокий архитектурный и визуальный риск, но очень высокая продуктовая отдача**. Сам эффект дешёв в статичном demo; дорого стоит сохранение всей существующей интерактивности и световой модели без регрессий.
## 12. Риски и меры
| Риск | Вероятность/влияние | Мера |
|---|---|---|
| Glow/blend/filter ломает CSS 3D | Высокие | Обычная SVG 2.5D-проекция вместо вложенного `preserve-3d` |
| Неверные T/X-стыки и проёмы | Высокие | Только канонические union bodies + geometry fixtures |
| Маркеры расходятся с планом | Высокие | Одна pure projection для SVG и HTML overlays |
| Падение FPS на больших планах | Средние/высокие | Side faces вместо десятков slices, кэш и perf gate |
| Нечитаемые подписи | Средние | Screen-facing/гибридный marker prototype и a11y review |
| Touch misclick при навигации | Средние/высокие | В MVP нет свободной камеры; существующие pan/pinch правила сохраняются |
| Режим превращается в второй renderer со своей логикой | Высокие | Общие resolvers/geometry; новый слой отвечает только за projection/presentation |
| Референс обещает больше, чем модель умеет | Средние | Называть «Объёмный вид», не «полноценный 3D»; явно ограничить высоту и окна |
## 13. Не входит в первую версию
- редактирование геометрии в перспективе;
- пользовательская высота каждой стены/комнаты;
- 3D-мебель и импорт моделей;
- настоящая физика света и динамические тени;
- свободный orbit camera;
- WebGL/Three.js;
- автоматическое превращение растровой подложки в 3D;
- изменение формата существующих room/wall/opening данных.
## 14. Acceptance criteria пользовательской версии
1. Пользователь может переключить текущий план между плоским и объёмным видом без изменения данных.
2. Существующие планы открываются плоскими и не требуют миграции.
3. В объёмном виде физические стены, перегородки и колонны имеют непрерывные top/side faces; виртуальные стены не экструдируются.
4. Двери, окна и ворота образуют реальные разрывы объёма, без тонких швов и торцов внутри проёма.
5. Glow, spill, sunlight, room fill и hover сохраняют текущую семантику и не мигают.
6. Device markers, room controls, tooltips и dialogs остаются кликабельными, читаемыми и доступными с клавиатуры.
7. Открытие редактора показывает плоский вид; выход восстанавливает предыдущий просмотр.
8. Zoom/pan/fit работают без скачка, phantom click и изменения сохранённой геометрии.
9. При ошибке объёмного renderer доступен безопасный плоский fallback.
10. Пройдены unit tests проекции/side faces, smoke interactions, golden matrix и performance comparison на детерминированных fixtures.
11. Обновлены `README.md`, `docs/USER-GUIDE.ru.md`, RU/EN changelog и release screenshots.
## 15. Рекомендуемая поставка
Фичу лучше вести отдельным релизным циклом:
1. внутренняя beta/spike без публичного toggle;
2. beta с фиксированным объёмным видом и полным fallback;
3. beta с doors/windows/markers polish и performance fixes;
4. stable только после golden review на реальных больших планах и проверки мобильного просмотра.
Главный критерий успеха — не максимальная «трёхмерность», а визуально сильный вид без потери надёжности Houseplan как интерактивной HA-карточки.