mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
Волна 2 эпика #674 — у каждого правила один дом, остальные места ссылаются. DECOR-EDITOR.md ← BACKDROP.md + LIVE-TEXT.md: один документ с нумерованными разделами (§3 подложка, §5 текст с живыми значениями), на которые теперь указывают комментарии кода вместо несуществовавших «BACKDROP §2/§3»; исправлено утверждение, что space-card не рисует декор (он рисует подложку и картинки декора, но не фигуры, мебель и текст). LIGHT.md ← матрица настроек света (перевод, тест назван явно: test/devices.test.mjs «issues 84/88»). DEVICE-PRESENTATION.md ← правила «что показывает маркер» из FILTERING.md (порядок cover → light sources → device role, шторы, медиаплееры); «в одном pull request» → «в одном коммите». CANVAS.md: §9.5 «Оптимизировать планы» → CONFIG-COMPATIBILITY.md, overlay и планарные грани Walls → WALL-THICKNESS.md §10–11, таблицы «было/стало» сняты. TESTING-DEMO.md → demo/stand/README.md: карта демо-дома и «чего на стенде нет», ручной чек-лист снят (ручной фазы в процессе нет). ISOMETRIC.md — только текущее; история Stage 2/4 — docs/adr/570-isometric-stage4-visual-handoff.md. SUN.md: удалённый контракт фона снят, правило бумаги — в текущем разделе. UX-MODES.md: декор над заливками, а не «под комнатами»; «hidden isometric»; follow-up из #3 — все выпущены. Шапки VACUUM, WARM-REMOUNT («Выровнять всё по сетке» → «Оптимизировать планы»), WALL-THICKNESS, STYLING-HOOKS, CONFIG-COMPATIBILITY (#33), PDF-EXPORT — без устаревших статусов и планов. README EN/RU: абзац про пересъёмку скриншотов → CONTRIBUTING.md, RADAR и PDF-EXPORT в списке документации, RU догнал EN (2.5D, повторное использование загруженного изображения, STAIRS). Один список канонических документов подсистем в AGENTS.md и промпте ревьюера (_process.yml). WALL-THICKNESS.md ссылается на ADR 282. Правки src/** и validation.py — только пути документов в комментариях. Issue: #679 User-Visible: no Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
68 lines
2.8 KiB
JavaScript
68 lines
2.8 KiB
JavaScript
// Backdrop image (docs/DECOR-EDITOR.md §3) — two shots for the owner:
|
||
// backdrop_frame — the transform frame mid-gesture: dashed outline, four
|
||
// finger-sized corner handles, and the live "W × H" badge
|
||
// stating the picture's real size through cell_cm;
|
||
// backdrop_paper — the new paper rule on an image plan: the opaque sheet is
|
||
// the ROOM CONTOURS, so the scene colour is visible around
|
||
// them and under the parts of the picture nobody has drawn
|
||
// over. The picture is scaled down here so both are obvious.
|
||
// Usage: node demo/shot_backdrop.mjs <outdir>
|
||
import { launch } from './serve.mjs';
|
||
const outDir = process.argv[2] || '/tmp';
|
||
const { page, browser } = await launch({ width: 900, height: 820 }, 2);
|
||
await page.emulateMedia({ reducedMotion: 'reduce' });
|
||
|
||
const settle = () => page.waitForTimeout(260);
|
||
|
||
// ---- 1) the frame, mid-drag ---------------------------------------------
|
||
await page.evaluate(async () => {
|
||
const c = window.__card;
|
||
c._setMode('decor');
|
||
c._decorTool = 'backdrop';
|
||
c.requestUpdate();
|
||
await c.updateComplete;
|
||
});
|
||
await settle();
|
||
const screenPt = (x, y) => page.evaluate(([x, y]) => {
|
||
const stage = window.__card.renderRoot.querySelector('.stage');
|
||
const r = stage.getBoundingClientRect();
|
||
const [vx, vy, vw, vh] = stage.querySelector('svg').getAttribute('viewBox').split(' ').map(Number);
|
||
return [r.left + ((x - vx) / vw) * r.width, r.top + ((y - vy) / vh) * r.height];
|
||
}, [x, y]);
|
||
{
|
||
// grab the bottom-right handle and hold it mid-gesture, so the shot carries
|
||
// the frame AND the live badge at once
|
||
const [ax, ay] = await screenPt(1000, 900);
|
||
const [bx, by] = await screenPt(820, 760);
|
||
await page.mouse.move(ax, ay);
|
||
await page.mouse.down();
|
||
await page.mouse.move((ax + bx) / 2, (ay + by) / 2, { steps: 4 });
|
||
await settle();
|
||
await page.screenshot({ path: `${outDir}/backdrop_frame.png` });
|
||
await page.mouse.up();
|
||
}
|
||
await settle();
|
||
|
||
// ---- 2) the paper is the rooms ------------------------------------------
|
||
await page.evaluate(async () => {
|
||
const c = window.__card;
|
||
const sp = c._serverCfg.spaces.find((s) => s.id === 'f1');
|
||
// a picture pulled well inside the plan and an acid scene colour: what shows
|
||
// through around the rooms is the SCENE, which is the whole new rule
|
||
sp.plan_x = 0.16; sp.plan_y = 0.10; sp.plan_scale = 0.62;
|
||
c._serverCfg.settings = { ...(c._serverCfg.settings || {}), bg_color: '#7bd389' };
|
||
c._cfgEpoch++; c._frame = null;
|
||
c._setMode('view');
|
||
c.requestUpdate();
|
||
await c.updateComplete;
|
||
c._fitAll();
|
||
c.requestUpdate();
|
||
await c.updateComplete;
|
||
});
|
||
await settle();
|
||
await settle();
|
||
await page.screenshot({ path: `${outDir}/backdrop_paper.png` });
|
||
|
||
await browser.close();
|
||
console.log('shots written to ' + outDir + '/backdrop_frame.png, ' + outDir + '/backdrop_paper.png');
|