mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-03 13:18:58 +00:00
+14
-2
@@ -249,7 +249,8 @@ import {
|
||||
type OpeningFaceOffset, type OpeningVisibleSpec,
|
||||
} from './render/opening-symbol';
|
||||
import {
|
||||
openingDefaultLengthCm, openingPlacementPreset, resolveOpeningPlacement, sameOpeningPlacementInput,
|
||||
openingDefaultLengthCm, openingPlacementPreset, passagePlacementPreviewGeometry,
|
||||
resolveOpeningPlacement, sameOpeningPlacementInput,
|
||||
type OpeningPlacementCore, type OpeningPlacementPreset, type OpeningPlacementType,
|
||||
} from './opening-placement';
|
||||
import { safeStoredColor } from './color';
|
||||
@@ -17363,10 +17364,21 @@ class HouseplanCard extends LitElement {
|
||||
gridPitch: this._gridPitch,
|
||||
face: candidate.face,
|
||||
};
|
||||
const passageGeometry = candidate.type === 'passage'
|
||||
? passagePlacementPreviewGeometry(candidate, this._gridPitch)
|
||||
: null;
|
||||
return svg`<g class="opening-preview" data-kind=${candidate.type}
|
||||
aria-hidden="true" pointer-events="none"
|
||||
transform="translate(${candidate.x} ${candidate.y}) rotate(${candidate.angle})">
|
||||
${renderOpeningVisibleGeometry(visibleSpec)}
|
||||
${passageGeometry ? svg`
|
||||
<rect class="passage-preview-cut" pointer-events="none"
|
||||
x=${passageGeometry.rect.x} y=${passageGeometry.rect.y}
|
||||
width=${passageGeometry.rect.width} height=${passageGeometry.rect.height}></rect>
|
||||
${passageGeometry.boundaries.map((boundary) => svg`
|
||||
<line class="passage-preview-boundary" pointer-events="none"
|
||||
x1=${boundary.x1} y1=${boundary.y1}
|
||||
x2=${boundary.x2} y2=${boundary.y2}></line>`)}
|
||||
` : renderOpeningVisibleGeometry(visibleSpec)}
|
||||
</g>
|
||||
<circle class="opening-preview-dot opghost-dot" aria-hidden="true" pointer-events="none"
|
||||
cx=${candidate.x} cy=${candidate.y} r=${this._gridPitch * 0.18}></circle>` as unknown as TemplateResult;
|
||||
|
||||
@@ -47,6 +47,14 @@ export interface OpeningPlacementCore {
|
||||
measure: OpeningPlacementMeasureGeometry;
|
||||
}
|
||||
|
||||
export interface PassagePlacementPreviewGeometry {
|
||||
rect: { x: number; y: number; width: number; height: number };
|
||||
boundaries: readonly [
|
||||
{ x1: number; y1: number; x2: number; y2: number },
|
||||
{ x1: number; y1: number; x2: number; y2: number },
|
||||
];
|
||||
}
|
||||
|
||||
export interface ResolveOpeningPlacementInput {
|
||||
pointer: readonly [number, number];
|
||||
preset: OpeningPlacementPreset;
|
||||
@@ -77,6 +85,29 @@ export function openingPlacementPreset(
|
||||
return { type, lengthCm: openingDefaultLengthCm(type), flipH: false, flipV: false, revision };
|
||||
}
|
||||
|
||||
/** Local SVG geometry for the passage-only placement overlay. The candidate
|
||||
* remains the authority for both the future wall cut and the preview. */
|
||||
export function passagePlacementPreviewGeometry(
|
||||
candidate: Pick<OpeningPlacementCore, 'renderedLength' | 'target'>,
|
||||
gridPitch: number,
|
||||
): PassagePlacementPreviewGeometry {
|
||||
const halfLength = Math.max(0, candidate.renderedLength) / 2;
|
||||
const halfDepth = Math.max(0, candidate.target.physicalHalfWidth);
|
||||
const boundaryHalfLength = halfDepth + Math.max(0, gridPitch) * 0.18;
|
||||
const boundary = (x: number) => ({
|
||||
x1: x, y1: -boundaryHalfLength, x2: x, y2: boundaryHalfLength,
|
||||
});
|
||||
return {
|
||||
rect: {
|
||||
x: -halfLength,
|
||||
y: halfDepth ? -halfDepth : 0,
|
||||
width: halfLength * 2,
|
||||
height: halfDepth * 2,
|
||||
},
|
||||
boundaries: [boundary(-halfLength), boundary(halfLength)],
|
||||
};
|
||||
}
|
||||
|
||||
function pointOrder(a: readonly number[], b: readonly number[]): number {
|
||||
return a[0] - b[0] || a[1] - b[1];
|
||||
}
|
||||
|
||||
@@ -1373,6 +1373,20 @@ export const cardStyles = css`
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
.opening-preview[data-kind="passage"] {
|
||||
opacity: 1;
|
||||
}
|
||||
.passage-preview-cut {
|
||||
fill: var(--wall-fill, #ffffff);
|
||||
fill-opacity: 0.35;
|
||||
stroke: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
.passage-preview-boundary {
|
||||
stroke: var(--hp-open, #ff9800);
|
||||
stroke-width: 2.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
.opening-preview .op-leaf,
|
||||
.opening-preview .op-arc {
|
||||
transition: none;
|
||||
|
||||
Reference in New Issue
Block a user