mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-03 21:28:59 +00:00
fix: make plan visuals grid-scale invariant
Issue: #239 User-Visible: yes
This commit is contained in:
+13
-3
@@ -280,8 +280,17 @@ so secure confirmation and Device-editor routing cannot drift.
|
||||
`size` (icon multiplier via the
|
||||
`--dev-size` CSS var — value badges scale along) and `angle` rotate/scale a single icon.
|
||||
Room drawing shows a live **ruler** (`segmentCm` +
|
||||
`formatLength`, metres or feet+inches by `hass.config.unit_system`); the scale is per-space
|
||||
`cell_cm` (default 5 cm per grid cell).
|
||||
`formatLength`, metres or feet+inches by `hass.config.unit_system`); the scale is
|
||||
per-space canonical `cell_cm`. New spaces default to 1 cm in metric HA or
|
||||
2.54 cm (shown as 1 inch) in imperial HA. Missing legacy data still reads as
|
||||
5 cm and is not migrated.
|
||||
|
||||
Legacy raw SVG constants are classified as visual units relative to the old
|
||||
5 cm renderer and pass through `gridVisualScale()` / `gridVisualUnits()`.
|
||||
Physical cm paths, screen-fixed chrome, plan-relative marker/label sizes and
|
||||
grid geometry are deliberately excluded from that factor. Full/static roots
|
||||
expose the same `--hp-cell-visual-scale`; hidden isometric heights and
|
||||
user-space shadows include the factor in their structural cache inputs.
|
||||
|
||||
|
||||
`config.markers[]`: `{id, binding:'device:<id>'|'entity:<eid>'|'virtual', space?, area?, hidden?, removed?,
|
||||
@@ -522,7 +531,8 @@ transaction through an accessible `hp-dialog`, never native `confirm()`.
|
||||
|
||||
While drawing, the length of the current segment follows the cursor (`_fmtLen` → `segmentCm`/
|
||||
`formatLength`): metres, or feet+inches when `hass.config.unit_system` is imperial. The scale is
|
||||
per-space `cell_cm` — cm represented by one grid cell (default 5, so 240 cells ≈ 12 m).
|
||||
per-space `cell_cm` — canonical centimetres represented by one grid cell; new
|
||||
spaces use 1 cm or 2.54 cm/1 inch, while missing legacy values fall back to 5 cm.
|
||||
|
||||
## Editor chrome and contextual controls
|
||||
|
||||
|
||||
+17
-2
@@ -30,6 +30,21 @@ coordinate system.
|
||||
4. **What is stored is only where something is drawn.** There is no
|
||||
stored extent to keep in sync.
|
||||
|
||||
### Grid precision and visual units
|
||||
|
||||
`cell_cm` is canonical centimetres per grid cell. New metric spaces use 1 cm;
|
||||
new imperial spaces store 2.54 cm and present it as 1 inch. The historical
|
||||
5 cm value remains the read fallback for missing or invalid legacy data, not a
|
||||
creation default, and existing spaces are never migrated merely by opening
|
||||
settings.
|
||||
|
||||
A finer grid changes precision only. Raw SVG constants inherited from the
|
||||
historical 5 cm renderer are **visual units** and use
|
||||
`gridVisualScale(cell_cm) = 5 / cell_cm`. Physical sizes already converted from
|
||||
centimetres, screen-fixed strokes/handles, plan-relative icon sizes and the
|
||||
grid pitch must not receive that factor again. Full, static and hidden
|
||||
isometric renderers share this classification.
|
||||
|
||||
## Model
|
||||
|
||||
| Concept | Before | Now |
|
||||
@@ -75,8 +90,8 @@ the exact target atomically without exposing a default-fit frame.
|
||||
| `_NORM` (decor x/y/w/h) | `-1 .. 2` | `-5000 .. 5000` | coordinate |
|
||||
| opening `length` | `0.001 .. 1` | `0.001 .. 5000` | size — strictly positive |
|
||||
|
||||
`+/-5000` is **garbage insurance, not a frame**. At the product's own
|
||||
scale (`cell_cm` = 5 by default, 240 grid cells across the unit width)
|
||||
`+/-5000` is **garbage insurance, not a frame**. At the historical compatibility
|
||||
scale (`cell_cm` = 5, 240 grid cells across the unit width)
|
||||
one canvas width is ~12 m, so `5000` is ~60 km of plan — unreachable
|
||||
in a home, while still stopping a stored `1e100` from making the plan
|
||||
invisible for every client (the failure HP-1500-03 / HP-1501-01
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Grid precision no longer changes the appearance of the same physical plan.
|
||||
Room and wall outlines, openings and their hit areas, Plan hints, the static
|
||||
card and hidden isometric geometry now retain the `cell_cm: 5` visual size at
|
||||
every supported cell size, while physical objects and screen-fixed controls
|
||||
are not scaled twice. New metric spaces start at 1 cm per cell; imperial HA
|
||||
starts at 1 inch per cell and shows inches in the field. Existing values are
|
||||
neither migrated nor rounded when settings are opened and saved
|
||||
([#239](https://github.com/Matysh/houseplan-card/issues/239)).
|
||||
|
||||
- While placing a door, window, gate or open passage, Plan now shows the usable
|
||||
distances from both jambs to the physical inner ends of the wall, with thin
|
||||
dimension lines and endpoint ticks. A shared wall shows four measurements —
|
||||
|
||||
@@ -8,6 +8,16 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- Точность сетки больше не меняет внешний вид одного и того же физического
|
||||
плана. Контуры комнат и стен, проёмы и их зоны попадания, подсказки редактора,
|
||||
статическая карточка и скрытая изометрия сохраняют эталонный вид
|
||||
`cell_cm: 5` при любом допустимом размере клетки; физические объекты и
|
||||
экранные элементы повторно не масштабируются. Новое метрическое пространство
|
||||
начинается с 1 см на клетку, а в имперской системе HA — с 1 дюйма и поле
|
||||
показывает дюймы. Существующие значения не мигрируют и не округляются при
|
||||
обычном открытии и сохранении настроек
|
||||
([#239](https://github.com/Matysh/houseplan-card/issues/239)).
|
||||
|
||||
- При размещении двери, окна, ворот или открытого проёма Редактор плана теперь
|
||||
показывает полезные расстояния от обоих косяков до физических внутренних
|
||||
концов стены — с тонкими размерными линиями и засечками. На общей стене видны
|
||||
|
||||
+15
-2
@@ -612,7 +612,19 @@ separately promised workflows:
|
||||
- [ ] Average room temperature counts ONLY thermometer/air-monitor devices — fridges, TRV heads,
|
||||
smart-plug chip temperatures (`*_device_temperature`) and diagnostic-category temps are excluded [manual]
|
||||
- [ ] Space dialog is 500 px wide; the comfort-bounds inputs are compact (56 px)
|
||||
- [ ] The scale (cm per cell) input is compact (72 px), not full-width [manual]
|
||||
- [ ] The scale input is compact (72 px), not full-width; it shows cm in metric
|
||||
HA and inches in imperial HA [manual; auto: smoke_space_scale_defaults]
|
||||
- [ ] A new manual space and every floor-import draft start at 1 cm in metric HA
|
||||
or exactly 1 inch/2.54 canonical cm in imperial HA. Opening and saving an
|
||||
existing 5 cm, fractional or missing legacy value without editing the
|
||||
field is lossless; changing language does not rewrite the canonical draft
|
||||
[auto: smoke_space_scale_defaults]
|
||||
- [ ] Physically equivalent rich fixtures at 1 cm and 5 cm have equal View,
|
||||
Plan-with-grid-masked and static-card pixels/critical bounds. The grid has
|
||||
five times the intervals only; openings retain their edge hit target, and
|
||||
physical/screen-fixed layers are not double-scaled
|
||||
[auto: smoke_grid_scale_invariance; unit: grid-scale.test.mjs,
|
||||
opening-symbol.test.mjs, canvas.test.mjs]
|
||||
- [ ] General settings (⚙ in the header): fill colors grouped by mode (lights on/off/none,
|
||||
temp cold/comfy/hot, LQI weak/strong), each with its own opacity slider [manual];
|
||||
Reset restores defaults; saving defaults stores nothing [manual]
|
||||
@@ -632,7 +644,8 @@ separately promised workflows:
|
||||
smoke_unified_wall_tool + unified-wall-tool-source.test]
|
||||
- [ ] Grid appears; dots snap; the wall chain draws pair-by-pair; shared walls reused
|
||||
- [ ] Ruler: while drawing, the length of the current segment follows the cursor
|
||||
(metres, or feet+inches on an imperial HA); scale = space "cm per cell" (default 5)
|
||||
(metres, or feet+inches on an imperial HA); scale = canonical per-space
|
||||
`cell_cm` (new-space default 1 cm or 1 inch; missing legacy fallback 5 cm)
|
||||
- [ ] Every completed segment is crash-safe in `room_drafts`. Changing tool,
|
||||
editor or floor finishes an open chain as ordinary partitions in one
|
||||
history/config transaction; the finished chain is not resumed as a draft
|
||||
|
||||
@@ -235,6 +235,19 @@ The plan image keeps its proportions initially. Background can later move,
|
||||
scale or rotate it. Detaching a plan never deletes its server file; deletion
|
||||
requires an explicit user action.
|
||||
|
||||
### Grid scale
|
||||
|
||||
The scale field is the real size of one grid cell. A new metric space starts at
|
||||
**1 cm per cell**; with an imperial Home Assistant unit system it starts at
|
||||
**1 in per cell** and the field is shown in inches. Floor import uses the same
|
||||
default for every new space.
|
||||
|
||||
Choose a finer cell when you need more precise snap points. It changes only the
|
||||
number of grid points per metre, not how the finished plan looks: physically
|
||||
equal rooms, walls, openings, labels and markers retain the same appearance.
|
||||
Existing spaces keep their stored scale. A legacy space without a scale still
|
||||
uses the 5 cm compatibility fallback and is not silently migrated.
|
||||
|
||||
### Tab order
|
||||
|
||||
Space tabs follow the order in which the spaces were created, and that order can
|
||||
|
||||
@@ -293,7 +293,7 @@ desktop: для точного рисования, Resize, модификато
|
||||
|
||||
| Раздел | Настройка | Результат |
|
||||
|---|---|---|
|
||||
| Масштаб | Сантиметров на клетку | Переводит сетку в реальные размеры и площади; начальное значение 5 см |
|
||||
| Масштаб | См или дюймов на клетку | Переводит сетку в реальные размеры и площади; новое пространство начинается с 1 см или 1 дюйма по системе единиц HA |
|
||||
| Отображение | Всегда показывать границы | Рисует контуры комнат в просмотре |
|
||||
| Отображение | Показывать названия | Рисует карточки комнат в Просмотре, киоске и статической карточке; при выключении не оставляет упрощённых подписей |
|
||||
| Отображение | Показывать LQI | Переопределяет базовую настройку карточки для этого пространства |
|
||||
@@ -316,6 +316,13 @@ desktop: для точного рисования, Resize, модификато
|
||||
| Заливка | Свой цвет/LQI/свет/температура | Выбирает постоянный цвет либо данные для заливки комнат пространства; свой цвет является обычным режимом по умолчанию |
|
||||
| Свечение источников света | Вкл/выкл | Добавляет световые пятна; базовое затемнение используется только без другой видимой заливки |
|
||||
|
||||
Более мелкая клетка даёт больше точек привязки на метр и повышает точность, но
|
||||
не меняет внешний вид готового плана. Физически одинаковые комнаты, стены,
|
||||
проёмы, подписи и маркеры выглядят одинаково при 1 и 5 см на клетку.
|
||||
Существующие пространства сохраняют записанный масштаб; для старого
|
||||
пространства без `cell_cm` остаётся compatibility fallback 5 см, без скрытой
|
||||
миграции.
|
||||
|
||||
Удаление пространства удаляет его комнаты и разметку после подтверждения. Файл подложки при этом автоматически не удаляется: им можно управлять через список уже загруженных планов.
|
||||
|
||||
<!-- docs-section: plan-tools -->
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 44 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"fixture": "synthetic-only",
|
||||
"sourceFingerprint": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceFingerprint": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"captureScriptSha256": "34f2219790d46efd8250e7a1bd829cb8fc0b0547e1260635fefa52407551b41b",
|
||||
"command": "npm run build && node demo/docs/capture.mjs",
|
||||
"scenarios": {
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "2885f96e348b15ab7c696e56e99bddcd9bb2ee94218a883e5a2155f45f5042aa"
|
||||
},
|
||||
"view-touch": {
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "f62d8af3617c00a5e99511bd765980d2e27badf25047a1be34046b64195abe6c"
|
||||
},
|
||||
"space-create": {
|
||||
@@ -35,8 +35,8 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"imageSha256": "c53db2e5c642a5549c13f3c93a5b359fed69bdb2621bf71a243a877ffcb95e6b"
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "c33a7279165a4cec6fa6fadb6fd08cd967e082a17fe101ef442d27d36ae59b6b"
|
||||
},
|
||||
"room-contour-close": {
|
||||
"file": "04-room-contour-close.png",
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "4d63670c7bcca33da21a6cf17275786bed12e8422a50d02d4dabe59645f2cd82"
|
||||
},
|
||||
"plan-context-tray": {
|
||||
@@ -57,7 +57,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "a6c526fede11bc3503fd2384bd4a3f6afa008f481c5c47578f06cae6c81c6f9b"
|
||||
},
|
||||
"device-editor": {
|
||||
@@ -68,7 +68,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "9585b59add4d35b5a6f028ce5b720ef1b77a3f8b19436d192cd1a0e6fc637264"
|
||||
},
|
||||
"device-display-preview": {
|
||||
@@ -79,7 +79,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "cfc317da4628d079a116ff71311fbf06b1eb3b181928a5ea7ba888ab936a5e8b"
|
||||
},
|
||||
"background-editor": {
|
||||
@@ -90,7 +90,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "d7cfe70551d9260169df8efd832e32ed7df99c7f60b55d1fd4a8322bd4c47175"
|
||||
},
|
||||
"room-card": {
|
||||
@@ -101,7 +101,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "029a3e69ec647a8a370d99e6bb7f9225833c526739076022f6b52ba54bff30ea"
|
||||
},
|
||||
"device-info": {
|
||||
@@ -112,7 +112,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "2b9f91ca744ed0429aae113b6e6f94ceada2c0fc3b2138559cf59b145b3e6b1c",
|
||||
"sourceSha256": "ed33e779c76b7373c152ecf13e82064a09fe62608af1c75cea96c48369cfec11",
|
||||
"imageSha256": "a06cbf83f09e2f67b3566d7c0b10e973db060c3d20786f26f74ada6a21937c3e"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user