Files
houseplan-card/demo/shot_backdrop.mjs
Claudeandclaude[bot] 5a258f3128 docs(hygiene): свести дубли документов подсистем и снять устаревшее (#679)
Волна 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
2026-09-27 18:07:37 +00:00

68 lines
2.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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');