fix: preserve isometric fallback rendering

Issue: #122
User-Visible: no
This commit is contained in:
Sergey Matyunin
2026-08-14 01:13:11 +03:00
parent e13215c02f
commit ef3cc98d1c
7 changed files with 1009 additions and 633 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+328 -209
View File
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -157,7 +157,8 @@ actions remain the only interactive opening surface.
- `hide_openings: true`: panels and leaf shadows disappear, while masonry
cuts, Glow/sun and contact/lock meaning remain;
- `show_borders: false`: Stage 2 roots are absent and the established floor
symbols return (subject to `hide_openings`), avoiding floating panels;
symbols and Stage 1 projected frame return (subject to `hide_openings`),
avoiding floating panels or an invisible Stage 2 bound that reframes them;
- Flat, editors and `houseplan-space-card` retain their old symbols and DOM.
Stage 2 adds no window beam, Glow source, sun renderer, material config,
+5 -1
View File
@@ -73,7 +73,11 @@ exception enters the established `space|fingerprint` Flat fallback latch.
These are presentation constants, not persisted fields. With visible borders,
vertical panels replace the old floor symbols. `hide_openings` hides panels and
leaf shadows. With borders disabled, every Stage 2 root is absent and the
existing floor symbols return, so there are no floating vertical leaves.
existing floor symbols return, so there are no floating vertical leaves. The
no-borders branch also keeps the accepted Stage 1 projected frame (floor plus
the fixed wall-height allowance): absent Stage 2 floor/opening geometry cannot
contribute invisible bounds and reframe the live floor. With borders visible,
fit includes every Stage 2 structural bound; blur capability never changes it.
## Consequences
+13 -4
View File
@@ -4557,6 +4557,14 @@ class HouseplanCard extends LitElement {
private _baseVb(): number[] {
if (this._effectiveProjection() === 'iso') {
// No-borders is the accepted Stage 1 no-volume scene. Stage 2 structure
// is absent there, so its opening/floor-edge bounds must be absent too;
// otherwise merely hiding volume reframes every live floor pixel.
if (!this._spaceDisplayForRender().showBorders) {
const flat = this._frameOf().rect;
const frame = projectedFrame({ rect: flat, wallHeight: ISO_WALL_HEIGHT });
return [frame.x, frame.y, frame.w, frame.h];
}
const frame = this._isoScene().frame;
return [frame.x, frame.y, frame.w, frame.h];
}
@@ -14170,12 +14178,13 @@ class HouseplanCard extends LitElement {
preserveAspectRatio="xMidYMid meet" aria-hidden="true" pointer-events="none">
${this._renderIsoUnderlay(isoLayers)}
</svg>` : nothing}
<svg class="plan-svg" viewBox=${iso
<svg class=${isoLayers?.structural ? 'plan-svg' : nothing}
viewBox=${isoLayers?.structural
? `${view.x} ${view.y} ${view.w} ${view.h}`
: `${floorView.x} ${floorView.y} ${floorView.w} ${floorView.h}`}
preserveAspectRatio="xMidYMid meet">
<g class=${iso ? 'iso-floor-scene' : nothing}
transform=${iso ? isoFloorMatrixCss() : nothing}>
preserveAspectRatio=${isoLayers?.structural || !iso ? 'xMidYMid meet' : 'none'}>
<g class=${isoLayers?.structural ? 'iso-floor-scene' : nothing}
transform=${isoLayers?.structural ? isoFloorMatrixCss() : nothing}>
${''/* THE PAPER IS THE ROOMS (docs/BACKDROP.md §3, owner
2026-08-04). Opaque shapes stop the scene background —
bg_color or the 'daynight' sky — from bleeding through the
+5
View File
@@ -46,6 +46,11 @@ test('structural cache includes opening flips and excludes live HA amount', () =
assert.doesNotMatch(source, /_openingAmt|openingAmount|\.hass|matchMedia|CSS\.supports|theme|hover/);
assert.match(card, /projectIsoOpening\(basis, this\._openingAmt\(opening\)\)/);
assert.match(card, /isoLayers && !isoLayers\.floorSymbols/);
assert.match(card, /if \(!this\._spaceDisplayForRender\(\)\.showBorders\)/);
assert.match(card, /projectedFrame\(\{ rect: flat, wallHeight: ISO_WALL_HEIGHT \}\)/);
assert.match(card, /viewBox=\$\{isoLayers\?\.structural[\s\S]*?: `\$\{floorView\.x\}/);
assert.match(card, /preserveAspectRatio=\$\{isoLayers\?\.structural \|\| !iso \? 'xMidYMid meet' : 'none'\}/);
assert.match(card, /transform=\$\{isoLayers\?\.structural \? isoFloorMatrixCss\(\) : nothing\}/);
});
test('Stage 2 adds no schema, dependency, storage, network or HA action surface', () => {