mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
docs: remove originals after the move to docs/reviews and legacy
Issue: #142 User-Visible: no
This commit is contained in:
@@ -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-карточки.
|
||||
Reference in New Issue
Block a user