mirror of
https://github.com/Matysh/houseplan-card
synced 2026-07-31 16:38:31 +00:00
ux v1.33.1: dot grid in all editors, faded plan in the background editor
- _editing getter; grid defs+rect rendered for plan/devices/decor - decor mode fades rooms/devlayer/openings/rlabel to 0.35, decor stays opaque - smoke_grid_fade.mjs (9 checks, transition-aware); docs same-commit
This commit is contained in:
@@ -11,7 +11,7 @@ PLANS_DIR = "houseplan/plans" # relative to the HA configuration directory
|
|||||||
FILES_URL = "/houseplan_files/files"
|
FILES_URL = "/houseplan_files/files"
|
||||||
FILES_DIR = "houseplan/files"
|
FILES_DIR = "houseplan/files"
|
||||||
CONF_ADMIN_ONLY = "admin_only"
|
CONF_ADMIN_ONLY = "admin_only"
|
||||||
VERSION = "1.33.0"
|
VERSION = "1.33.1"
|
||||||
|
|
||||||
DEFAULT_CONFIG: dict = {
|
DEFAULT_CONFIG: dict = {
|
||||||
"spaces": [],
|
"spaces": [],
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -16,5 +16,5 @@
|
|||||||
"issue_tracker": "https://github.com/Matysh/houseplan-card/issues",
|
"issue_tracker": "https://github.com/Matysh/houseplan-card/issues",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
"single_config_entry": true,
|
"single_config_entry": true,
|
||||||
"version": "1.33.0"
|
"version": "1.33.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { launch } from './serve.mjs';
|
||||||
|
const { page, browser } = await launch();
|
||||||
|
const res = await page.evaluate(async () => {
|
||||||
|
const out = {};
|
||||||
|
const c = window.__card;
|
||||||
|
const sr = () => c.shadowRoot || c.renderRoot;
|
||||||
|
const grid = () => !!sr().querySelector('rect[fill="url(#hp-grid)"]');
|
||||||
|
// Просмотр: сетки нет
|
||||||
|
out.noGridInView = !grid();
|
||||||
|
// все три редактора: сетка есть
|
||||||
|
c._setMode('plan'); await c.updateComplete; out.gridInPlan = grid();
|
||||||
|
c._setMode('devices'); await c.updateComplete; out.gridInDevices = grid();
|
||||||
|
c._setMode('decor'); await c.updateComplete; out.gridInDecor = grid();
|
||||||
|
await new Promise((r) => setTimeout(r, 250)); // transition .room 0.12s
|
||||||
|
// decor: комнаты и устройства полупрозрачны
|
||||||
|
const room = sr().querySelector('.room');
|
||||||
|
out.roomFaded = room ? Number(getComputedStyle(room).opacity) < 0.5 : null;
|
||||||
|
const dl = sr().querySelector('.devlayer');
|
||||||
|
out.devsFaded = dl ? Number(getComputedStyle(dl).opacity) < 0.5 : null;
|
||||||
|
// а декор-слой — нет
|
||||||
|
c._curSpaceCfg.decor = [{ id: 'd1', kind: 'line', x1: 0.1, y1: 0.1, x2: 0.3, y2: 0.1, color: '#ff0000', width: 3 }];
|
||||||
|
c.requestUpdate(); await c.updateComplete;
|
||||||
|
const shp = sr().querySelector('.decorlayer .dshape');
|
||||||
|
out.decorNotFaded = shp ? Number(getComputedStyle(shp).opacity) > 0.9 : null;
|
||||||
|
// в других редакторах прозрачности нет
|
||||||
|
c._setMode('devices'); await c.updateComplete;
|
||||||
|
await new Promise((r) => setTimeout(r, 250));
|
||||||
|
const room2 = sr().querySelector('.room');
|
||||||
|
out.notFadedInDevices = room2 ? Number(getComputedStyle(room2).opacity) > 0.9 : null;
|
||||||
|
c._setMode('view'); await c.updateComplete;
|
||||||
|
await new Promise((r) => setTimeout(r, 250));
|
||||||
|
const room3 = sr().querySelector('.room');
|
||||||
|
out.notFadedInView = room3 ? Number(getComputedStyle(room3).opacity) > 0.9 : null;
|
||||||
|
return out;
|
||||||
|
});
|
||||||
|
console.log(JSON.stringify(res, null, 1));
|
||||||
|
await browser.close();
|
||||||
File diff suppressed because one or more lines are too long
Vendored
+11
-3
File diff suppressed because one or more lines are too long
@@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.33.1 — 2026-07-22
|
||||||
|
- The dot grid is now shown in **every editor** (Plan, Devices, Background),
|
||||||
|
not just Plan — an instant visual cue that you are editing.
|
||||||
|
- In the Background editor, rooms, devices, openings and labels fade to 35%
|
||||||
|
opacity so the decor you are drawing stands out; decor itself stays fully
|
||||||
|
opaque. Other modes are unaffected.
|
||||||
|
|
||||||
## v1.33.0 — 2026-07-22 (background editor)
|
## v1.33.0 — 2026-07-22 (background editor)
|
||||||
- New third mode: **Background editor**. Draw purely visual decor on the plan —
|
- New third mode: **Background editor**. Draw purely visual decor on the plan —
|
||||||
lines, rectangles, ovals and text labels that never interact with rooms,
|
lines, rectangles, ovals and text labels that never interact with rooms,
|
||||||
|
|||||||
@@ -140,6 +140,10 @@ Run the *core flows* (marked ★ below) in each environment at least once per mi
|
|||||||
(explicit ripple color still wins); off/white lights unchanged [auto]
|
(explicit ripple color still wins); off/white lights unchanged [auto]
|
||||||
- [ ] Alarm pulse (v1.27.0): leak/smoke/gas/CO/siren in 'on' pulse a red ring over any
|
- [ ] Alarm pulse (v1.27.0): leak/smoke/gas/CO/siren in 'on' pulse a red ring over any
|
||||||
display mode; clears on 'off'; unavailable never alarms [auto]; reduced-motion static
|
display mode; clears on 'off'; unavailable never alarms [auto]; reduced-motion static
|
||||||
|
- [ ] Grid in all editors + decor fade (v1.33.1): the dot grid shows in the
|
||||||
|
Device and Background editors too (instant "I'm editing" cue), not in
|
||||||
|
View; in the Background editor rooms/devices/openings/labels fade to 35%
|
||||||
|
while decor shapes stay fully opaque; no fade in the other editors [auto]
|
||||||
- [ ] Background editor (v1.33.0): third tab with its own toolbar (select /
|
- [ ] Background editor (v1.33.0): third tab with its own toolbar (select /
|
||||||
line / rect / oval / text / erase + color, width, fill, X); shapes drag-
|
line / rect / oval / text / erase + color, width, fill, X); shapes drag-
|
||||||
drawn with grid snap and live preview; degenerate shapes dropped; text
|
drawn with grid snap and live preview; degenerate shapes dropped; text
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "houseplan-card",
|
"name": "houseplan-card",
|
||||||
"version": "1.33.0",
|
"version": "1.33.1",
|
||||||
"description": "Interactive house plan Lovelace card for Home Assistant",
|
"description": "Interactive house plan Lovelace card for Home Assistant",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
+10
-2
@@ -32,7 +32,7 @@ import './space-card';
|
|||||||
import { cardStyles } from './styles';
|
import { cardStyles } from './styles';
|
||||||
import { langOf, t, type I18nKey } from './i18n';
|
import { langOf, t, type I18nKey } from './i18n';
|
||||||
|
|
||||||
const CARD_VERSION = '1.33.0';
|
const CARD_VERSION = '1.33.1';
|
||||||
const LS_KEY = 'houseplan_card_layout_v1';
|
const LS_KEY = 'houseplan_card_layout_v1';
|
||||||
const LS_CFG = 'houseplan_card_cfg_v1'; // cache of the server config+layout for instant rendering
|
const LS_CFG = 'houseplan_card_cfg_v1'; // cache of the server config+layout for instant rendering
|
||||||
const LS_ZOOM = 'houseplan_card_zoom_v1';
|
const LS_ZOOM = 'houseplan_card_zoom_v1';
|
||||||
@@ -101,6 +101,11 @@ class HouseplanCard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Legacy alias: markup machinery is active exactly in plan mode. */
|
/** Legacy alias: markup machinery is active exactly in plan mode. */
|
||||||
|
/** Any edit mode is active (plan / devices / decor). */
|
||||||
|
private get _editing(): boolean {
|
||||||
|
return this._mode === 'plan' || this._mode === 'devices' || this._mode === 'decor';
|
||||||
|
}
|
||||||
|
|
||||||
private get _markup(): boolean {
|
private get _markup(): boolean {
|
||||||
return this._mode === 'plan';
|
return this._mode === 'plan';
|
||||||
}
|
}
|
||||||
@@ -2854,7 +2859,10 @@ class HouseplanCard extends LitElement {
|
|||||||
@pointercancel=${(e: PointerEvent) => this._stagePointerUp(e)}>
|
@pointercancel=${(e: PointerEvent) => this._stagePointerUp(e)}>
|
||||||
<div class="zoomwrap">
|
<div class="zoomwrap">
|
||||||
<svg viewBox="${view.x} ${view.y} ${view.w} ${view.h}" preserveAspectRatio="xMidYMid meet">
|
<svg viewBox="${view.x} ${view.y} ${view.w} ${view.h}" preserveAspectRatio="xMidYMid meet">
|
||||||
${this._markup ? this._renderMarkupDefs(vb) : nothing}
|
${this._editing ? this._renderMarkupDefs(vb) : nothing}
|
||||||
|
${this._editing && !this._markup
|
||||||
|
? svg`<rect x="${vb[0]}" y="${vb[1]}" width="${vb[2]}" height="${vb[3]}" fill="url(#hp-grid)" pointer-events="none"></rect>`
|
||||||
|
: nothing}
|
||||||
${space.bg
|
${space.bg
|
||||||
? svg`<image href="${space.bg.href}" x="${space.bg.x}" y="${space.bg.y}" width="${space.bg.w}" height="${space.bg.h}" preserveAspectRatio="none" />`
|
? svg`<image href="${space.bg.href}" x="${space.bg.x}" y="${space.bg.y}" width="${space.bg.w}" height="${space.bg.h}" preserveAspectRatio="none" />`
|
||||||
: nothing}
|
: nothing}
|
||||||
|
|||||||
@@ -463,6 +463,13 @@ export const cardStyles = css`
|
|||||||
}
|
}
|
||||||
.stage.mode-decor .room, .stage.mode-decor .devlayer { pointer-events: none; }
|
.stage.mode-decor .room, .stage.mode-decor .devlayer { pointer-events: none; }
|
||||||
.stage.mode-decor .oplock { pointer-events: none; }
|
.stage.mode-decor .oplock { pointer-events: none; }
|
||||||
|
/* decor mode: everything but the decor itself fades back */
|
||||||
|
.stage.mode-decor .room,
|
||||||
|
.stage.mode-decor .devlayer,
|
||||||
|
.stage.mode-decor .opening,
|
||||||
|
.stage.mode-decor .rlabel {
|
||||||
|
opacity: 0.35;
|
||||||
|
}
|
||||||
.decorbar .dcolor {
|
.decorbar .dcolor {
|
||||||
width: 30px; height: 26px; padding: 0; border: none; background: none; cursor: pointer;
|
width: 30px; height: 26px; padding: 0; border: none; background: none; cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user