L/W-HUD in den Zeichenbefehlen (line/polyline/wall/rect/circle/arc)
Alle punktbasierten Zeichenbefehle setzen den Cursor-HUD jetzt einheitlich über den gemeinsamen segmentHud()-Helper statt eigener Text-Formatierung: - line/polyline/wall: L/W-Kästchen für das lebende Segment ab dem letzten Punkt. - rect: 2-Punkt/Zentrum-Methode zeigt die Diagonale als L/W; die 3-Punkt- Methode zeigt die Basiskante als L/W bzw. Basisbreite+Höhe im Rise-Schritt. - circle/arc (Radius-Schritt): Radius als „R: …m"-Label statt L/W (kein Winkel sinnvoll); arc zeigt im Spannwinkel-Schritt Radius als L und Spannwinkel als W. Alle Werte jetzt mit 3 Nachkommastellen (vorher 2 bzw. 0), konsistent mit der VW-Konvention der Statusleiste. Tests: line.test.ts/wall.test.ts prüfen hud.length/angleDeg im onMove-Draft (inkl. negativer Winkel im Bereich (−180,180] und Segment-Wechsel bei mehrteiligen Wandzügen).
This commit is contained in:
@@ -73,14 +73,14 @@ function circlePts(center: Vec2, r: number): Vec2[] {
|
|||||||
return pts;
|
return pts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Vorschau (offener Bogen) + HUD (Spanne in Grad). */
|
/** Vorschau (offener Bogen) + HUD (Radius als L, Spanne als W — L/W-Kästchen). */
|
||||||
function arcDraft(center: Vec2, r: number, a0: number, a1: number, at: Vec2 | null): ToolDraft {
|
function arcDraft(center: Vec2, r: number, a0: number, a1: number, at: Vec2 | null): ToolDraft {
|
||||||
if (r < EPS) return { preview: [], vertices: [center] };
|
if (r < EPS) return { preview: [], vertices: [center] };
|
||||||
const preview: DraftShape[] = [{ kind: "poly", pts: arcPts(center, r, a0, a1), closed: false }];
|
const preview: DraftShape[] = [{ kind: "poly", pts: arcPts(center, r, a0, a1), closed: false }];
|
||||||
const draft: ToolDraft = { preview, vertices: [center] };
|
const draft: ToolDraft = { preview, vertices: [center] };
|
||||||
if (at) {
|
if (at) {
|
||||||
const deg = (sweepOf(a0, a1) * 180) / Math.PI;
|
const deg = (sweepOf(a0, a1) * 180) / Math.PI;
|
||||||
draft.hud = { at, text: `${deg.toFixed(0)}°` };
|
draft.hud = { at, length: r, angleDeg: deg };
|
||||||
}
|
}
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ export const arcCommand: Command = {
|
|||||||
draft: {
|
draft: {
|
||||||
preview: [{ kind: "poly", pts: circlePts(s.center, r), closed: true }],
|
preview: [{ kind: "poly", pts: circlePts(s.center, r), closed: true }],
|
||||||
vertices: [s.center],
|
vertices: [s.center],
|
||||||
hud: { at: point, text: `r ${r.toFixed(2)} m` },
|
hud: { at: point, text: `R: ${r.toFixed(3)}m` },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ function circleDraft(center: Vec2, r: number, at: Vec2 | null): ToolDraft {
|
|||||||
if (r < EPS) return { preview: [], vertices: [center] };
|
if (r < EPS) return { preview: [], vertices: [center] };
|
||||||
const preview: DraftShape[] = [{ kind: "poly", pts: circlePts(center, r), closed: true }];
|
const preview: DraftShape[] = [{ kind: "poly", pts: circlePts(center, r), closed: true }];
|
||||||
const draft: ToolDraft = { preview, vertices: [center] };
|
const draft: ToolDraft = { preview, vertices: [center] };
|
||||||
if (at) draft.hud = { at, text: `r ${r.toFixed(2)} m` };
|
if (at) draft.hud = { at, text: `R: ${r.toFixed(3)}m` };
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* Unit-Tests für das Cursor-HUD (Länge/Winkel) des `line`-Befehls: nach dem
|
||||||
|
* Startpunkt muss `onMove` im Draft `hud.length`/`hud.angleDeg` mit den
|
||||||
|
* korrekten Werten liefern (VW-Stil L/W-Kästchen, PlanView rendert es).
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { lineCommand } from "./line";
|
||||||
|
import type { CommandContext, Project, Vec2 } from "../types";
|
||||||
|
|
||||||
|
/** Minimalprojekt — nur die Felder, die der Befehl/Context anfassen. */
|
||||||
|
function project(): Project {
|
||||||
|
return {
|
||||||
|
id: "t",
|
||||||
|
name: "T",
|
||||||
|
lineStyles: [],
|
||||||
|
hatches: [],
|
||||||
|
components: [],
|
||||||
|
wallTypes: [],
|
||||||
|
drawingLevels: [
|
||||||
|
{
|
||||||
|
id: "eg",
|
||||||
|
name: "EG",
|
||||||
|
kind: "floor",
|
||||||
|
visible: true,
|
||||||
|
locked: false,
|
||||||
|
floorHeight: 2.6,
|
||||||
|
cutHeight: 1.0,
|
||||||
|
baseElevation: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
layers: [{ code: "20", name: "Zeichnung", color: "#0a0a0a", lw: 0.5, visible: true, locked: false }],
|
||||||
|
walls: [],
|
||||||
|
doors: [],
|
||||||
|
openings: [],
|
||||||
|
ceilings: [],
|
||||||
|
stairs: [],
|
||||||
|
rooms: [],
|
||||||
|
drawings2d: [],
|
||||||
|
context: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeCtx(lastPoint: Vec2 | null): CommandContext {
|
||||||
|
const p = project();
|
||||||
|
return {
|
||||||
|
project: p,
|
||||||
|
level: p.drawingLevels[0],
|
||||||
|
defaultCategoryCode: "20",
|
||||||
|
activeLineStyleId: "solid",
|
||||||
|
activeWallTypeId: "aw",
|
||||||
|
lastPoint,
|
||||||
|
selection: { wallIds: [], drawingId: null },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("lineCommand — Cursor-HUD (Länge/Winkel)", () => {
|
||||||
|
it("liefert hud.length/angleDeg im onMove nach dem Startpunkt", () => {
|
||||||
|
const start: Vec2 = { x: 0, y: 0 };
|
||||||
|
const [afterStart] = lineCommand.onInput(
|
||||||
|
lineCommand.init(),
|
||||||
|
{ kind: "point", point: start },
|
||||||
|
makeCtx(null),
|
||||||
|
);
|
||||||
|
const [, res] = lineCommand.onMove(afterStart, { x: 3, y: 4 }, null, makeCtx(start));
|
||||||
|
expect(res.draft?.hud?.length).toBeCloseTo(5, 9);
|
||||||
|
expect(res.draft?.hud?.angleDeg).toBeCloseTo((Math.atan2(4, 3) * 180) / Math.PI, 9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("liefert einen negativen Winkel (Bereich (−180,180]) für Segmente nach unten-links", () => {
|
||||||
|
const start: Vec2 = { x: 0, y: 0 };
|
||||||
|
const [afterStart] = lineCommand.onInput(
|
||||||
|
lineCommand.init(),
|
||||||
|
{ kind: "point", point: start },
|
||||||
|
makeCtx(null),
|
||||||
|
);
|
||||||
|
// Richtung (-1,-1) → -135° (wie im VW-Screenshot).
|
||||||
|
const [, res] = lineCommand.onMove(afterStart, { x: -2, y: -2 }, null, makeCtx(start));
|
||||||
|
expect(res.draft?.hud?.angleDeg).toBeCloseTo(-135, 9);
|
||||||
|
expect(res.draft?.hud?.length).toBeCloseTo(Math.hypot(2, 2), 9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("zeigt KEIN HUD vor dem Startpunkt (phase=start)", () => {
|
||||||
|
const [, res] = lineCommand.onMove(lineCommand.init(), { x: 1, y: 1 }, null, makeCtx(null));
|
||||||
|
expect(res.draft).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
// Tool. Live-Vorschau + HUD (Länge/Winkel) wie die bestehenden Tools.
|
// Tool. Live-Vorschau + HUD (Länge/Winkel) wie die bestehenden Tools.
|
||||||
|
|
||||||
import type { Drawing2D } from "../../model/types";
|
import type { Drawing2D } from "../../model/types";
|
||||||
import { uniqueId } from "../../tools/types";
|
import { segmentHud, uniqueId } from "../../tools/types";
|
||||||
import type {
|
import type {
|
||||||
Command,
|
Command,
|
||||||
CommandContext,
|
CommandContext,
|
||||||
@@ -61,14 +61,7 @@ function lineDraft(a: Vec2, cursor: Vec2 | null): ToolDraft {
|
|||||||
const preview: DraftShape[] = [];
|
const preview: DraftShape[] = [];
|
||||||
if (cursor && segLen(a, cursor) >= EPS) preview.push({ kind: "line", a, b: cursor });
|
if (cursor && segLen(a, cursor) >= EPS) preview.push({ kind: "line", a, b: cursor });
|
||||||
const draft: ToolDraft = { preview, vertices: [a] };
|
const draft: ToolDraft = { preview, vertices: [a] };
|
||||||
if (cursor && segLen(a, cursor) >= EPS) {
|
if (cursor && segLen(a, cursor) >= EPS) draft.hud = segmentHud(a, cursor);
|
||||||
draft.hud = {
|
|
||||||
at: cursor,
|
|
||||||
text: `${segLen(a, cursor).toFixed(2)} m · ${Math.abs(
|
|
||||||
(segAngleDeg(a, cursor) + 360) % 360,
|
|
||||||
).toFixed(0)}°`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
// Akzeptiert je Punkt Maus-Picks UND getippte Koordinaten (0,0 · r3,0 · 5<45).
|
// Akzeptiert je Punkt Maus-Picks UND getippte Koordinaten (0,0 · r3,0 · 5<45).
|
||||||
|
|
||||||
import type { Drawing2D } from "../../model/types";
|
import type { Drawing2D } from "../../model/types";
|
||||||
import { uniqueId } from "../../tools/types";
|
import { segmentHud, uniqueId } from "../../tools/types";
|
||||||
import type {
|
import type {
|
||||||
Command,
|
Command,
|
||||||
CommandContext,
|
CommandContext,
|
||||||
@@ -74,14 +74,7 @@ function polyDraft(points: Vec2[], cursor: Vec2 | null, closed = false): ToolDra
|
|||||||
const preview: DraftShape[] = [{ kind: "poly", pts, closed: showClosed }];
|
const preview: DraftShape[] = [{ kind: "poly", pts, closed: showClosed }];
|
||||||
const draft: ToolDraft = { preview, vertices: points };
|
const draft: ToolDraft = { preview, vertices: points };
|
||||||
const last = points[points.length - 1];
|
const last = points[points.length - 1];
|
||||||
if (cursor && last && segLen(last, cursor) >= EPS) {
|
if (cursor && last && segLen(last, cursor) >= EPS) draft.hud = segmentHud(last, cursor);
|
||||||
draft.hud = {
|
|
||||||
at: cursor,
|
|
||||||
text: `${segLen(last, cursor).toFixed(2)} m · ${Math.abs(
|
|
||||||
(segAngleDeg(last, cursor) + 360) % 360,
|
|
||||||
).toFixed(0)}°`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-19
@@ -17,7 +17,7 @@
|
|||||||
// werden (die Engine löst `r…` relativ zu lastPoint auf).
|
// werden (die Engine löst `r…` relativ zu lastPoint auf).
|
||||||
|
|
||||||
import type { Drawing2D } from "../../model/types";
|
import type { Drawing2D } from "../../model/types";
|
||||||
import { uniqueId } from "../../tools/types";
|
import { segmentHud, uniqueId } from "../../tools/types";
|
||||||
import type {
|
import type {
|
||||||
Command,
|
Command,
|
||||||
CommandContext,
|
CommandContext,
|
||||||
@@ -196,51 +196,42 @@ function rectGeom(a: Vec2, b: Vec2): { min: Vec2; max: Vec2 } {
|
|||||||
|
|
||||||
// ── Vorschau ─────────────────────────────────────────────────────────────────
|
// ── Vorschau ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
function corners4Draft(pts: Vec2[], hudAt: Vec2 | null, hudText: string): ToolDraft {
|
function corners4Draft(pts: Vec2[], hud: ToolDraft["hud"] | null): ToolDraft {
|
||||||
const preview: DraftShape[] = [{ kind: "poly", pts, closed: true }];
|
const preview: DraftShape[] = [{ kind: "poly", pts, closed: true }];
|
||||||
const draft: ToolDraft = { preview, vertices: [pts[0]] };
|
const draft: ToolDraft = { preview, vertices: [pts[0]] };
|
||||||
if (hudAt) draft.hud = { at: hudAt, text: hudText };
|
if (hud) draft.hud = hud;
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Vorschau des 2-Punkt-Rechtecks (achsparallel). */
|
/** Vorschau des 2-Punkt-Rechtecks (achsparallel) — HUD zeigt die Diagonale a→cursor. */
|
||||||
function cornerDraft(a: Vec2, cursor: Vec2 | null): ToolDraft {
|
function cornerDraft(a: Vec2, cursor: Vec2 | null): ToolDraft {
|
||||||
if (!cursor) return { preview: [], vertices: [a] };
|
if (!cursor) return { preview: [], vertices: [a] };
|
||||||
const g = rectGeom(a, cursor);
|
const g = rectGeom(a, cursor);
|
||||||
const pts: Vec2[] = [g.min, { x: g.max.x, y: g.min.y }, g.max, { x: g.min.x, y: g.max.y }];
|
const pts: Vec2[] = [g.min, { x: g.max.x, y: g.min.y }, g.max, { x: g.min.x, y: g.max.y }];
|
||||||
const w = g.max.x - g.min.x;
|
return corners4Draft(pts, segLen(a, cursor) >= EPS ? segmentHud(a, cursor) : null);
|
||||||
const h = g.max.y - g.min.y;
|
|
||||||
return corners4Draft(pts, cursor, `${w.toFixed(2)} × ${h.toFixed(2)} m`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Vorschau des Zentrum-Rechtecks (achsparallel). */
|
/** Vorschau des Zentrum-Rechtecks (achsparallel) — HUD zeigt die Diagonale center→cursor. */
|
||||||
function centerDraft(center: Vec2, cursor: Vec2 | null): ToolDraft {
|
function centerDraft(center: Vec2, cursor: Vec2 | null): ToolDraft {
|
||||||
if (!cursor) return { preview: [], vertices: [center] };
|
if (!cursor) return { preview: [], vertices: [center] };
|
||||||
const g = centerGeom(center, cursor);
|
const g = centerGeom(center, cursor);
|
||||||
const pts: Vec2[] = [g.min, { x: g.max.x, y: g.min.y }, g.max, { x: g.min.x, y: g.max.y }];
|
const pts: Vec2[] = [g.min, { x: g.max.x, y: g.min.y }, g.max, { x: g.min.x, y: g.max.y }];
|
||||||
const w = g.max.x - g.min.x;
|
return corners4Draft(pts, segLen(center, cursor) >= EPS ? segmentHud(center, cursor) : null);
|
||||||
const h = g.max.y - g.min.y;
|
|
||||||
return corners4Draft(pts, cursor, `${w.toFixed(2)} × ${h.toFixed(2)} m`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Vorschau der Basiskante (3-Punkt, erster Teil). */
|
/** Vorschau der Basiskante (3-Punkt, erster Teil). */
|
||||||
function baseDraft(a: Vec2, cursor: Vec2 | null): ToolDraft {
|
function baseDraft(a: Vec2, cursor: Vec2 | null): ToolDraft {
|
||||||
if (!cursor || segLen(a, cursor) < EPS) return { preview: [{ kind: "line", a, b: a }], vertices: [a] };
|
if (!cursor || segLen(a, cursor) < EPS) return { preview: [{ kind: "line", a, b: a }], vertices: [a] };
|
||||||
const draft: ToolDraft = { preview: [{ kind: "line", a, b: cursor }], vertices: [a] };
|
return { preview: [{ kind: "line", a, b: cursor }], vertices: [a], hud: segmentHud(a, cursor) };
|
||||||
draft.hud = {
|
|
||||||
at: cursor,
|
|
||||||
text: `${segLen(a, cursor).toFixed(2)} m · ${Math.abs((segAngleDeg(a, cursor) + 360) % 360).toFixed(0)}°`,
|
|
||||||
};
|
|
||||||
return draft;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Vorschau des gedrehten Rechtecks (3-Punkt, zweiter Teil). */
|
/** Vorschau des gedrehten Rechtecks (3-Punkt, zweiter Teil) — HUD: Basisbreite + Höhe am Cursor. */
|
||||||
function riseDraft(a: Vec2, b: Vec2, cursor: Vec2 | null): ToolDraft {
|
function riseDraft(a: Vec2, b: Vec2, cursor: Vec2 | null): ToolDraft {
|
||||||
if (!cursor) return { preview: [{ kind: "line", a, b }], vertices: [a] };
|
if (!cursor) return { preview: [{ kind: "line", a, b }], vertices: [a] };
|
||||||
const pts = rotatedCorners(a, b, cursor);
|
const pts = rotatedCorners(a, b, cursor);
|
||||||
const w = segLen(a, b);
|
const w = segLen(a, b);
|
||||||
const h = Math.abs(riseFrom(a, b, cursor));
|
const h = Math.abs(riseFrom(a, b, cursor));
|
||||||
return corners4Draft(pts, cursor, `${w.toFixed(2)} × ${h.toFixed(2)} m`);
|
return corners4Draft(pts, { at: cursor, text: `B: ${w.toFixed(3)}m H: ${h.toFixed(3)}m` });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Commit ───────────────────────────────────────────────────────────────────
|
// ── Commit ───────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* Unit-Tests für das Cursor-HUD (Länge/Winkel) des `wall`-Befehls: nach dem
|
||||||
|
* Startpunkt muss `onMove` im Draft `hud.length`/`hud.angleDeg` relativ zum
|
||||||
|
* ZULETZT gesetzten Achspunkt liefern — auch nach mehreren Segmenten
|
||||||
|
* (Chaining), damit ein mehrteiliger Wandzug je Segment ein frisches HUD zeigt.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { wallCommand } from "./wall";
|
||||||
|
import type { CommandContext, Project, Vec2 } from "../types";
|
||||||
|
|
||||||
|
function project(): Project {
|
||||||
|
return {
|
||||||
|
id: "t",
|
||||||
|
name: "T",
|
||||||
|
lineStyles: [],
|
||||||
|
hatches: [],
|
||||||
|
components: [{ id: "c", name: "C", color: "#ccc", hatchId: "none", joinPriority: 10 }],
|
||||||
|
wallTypes: [
|
||||||
|
{ id: "aw", name: "AW", layers: [{ componentId: "c", thickness: 0.2 }] },
|
||||||
|
],
|
||||||
|
drawingLevels: [
|
||||||
|
{
|
||||||
|
id: "eg",
|
||||||
|
name: "EG",
|
||||||
|
kind: "floor",
|
||||||
|
visible: true,
|
||||||
|
locked: false,
|
||||||
|
floorHeight: 2.6,
|
||||||
|
cutHeight: 1.0,
|
||||||
|
baseElevation: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
layers: [{ code: "20", name: "Wände", color: "#0a0a0a", lw: 0.5, visible: true, locked: false }],
|
||||||
|
walls: [],
|
||||||
|
doors: [],
|
||||||
|
openings: [],
|
||||||
|
ceilings: [],
|
||||||
|
stairs: [],
|
||||||
|
rooms: [],
|
||||||
|
drawings2d: [],
|
||||||
|
context: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeCtx(lastPoint: Vec2 | null): CommandContext {
|
||||||
|
const p = project();
|
||||||
|
return {
|
||||||
|
project: p,
|
||||||
|
level: p.drawingLevels[0],
|
||||||
|
defaultCategoryCode: "20",
|
||||||
|
activeLineStyleId: "solid",
|
||||||
|
activeWallTypeId: "aw",
|
||||||
|
lastPoint,
|
||||||
|
selection: { wallIds: [], drawingId: null },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("wallCommand — Cursor-HUD (Länge/Winkel)", () => {
|
||||||
|
it("liefert hud.length/angleDeg relativ zum Startpunkt", () => {
|
||||||
|
const start: Vec2 = { x: 0, y: 0 };
|
||||||
|
const [afterStart] = wallCommand.onInput(
|
||||||
|
wallCommand.init(),
|
||||||
|
{ kind: "point", point: start },
|
||||||
|
makeCtx(null),
|
||||||
|
);
|
||||||
|
const [, res] = wallCommand.onMove(afterStart, { x: 4, y: 0 }, null, makeCtx(start));
|
||||||
|
expect(res.draft?.hud?.length).toBeCloseTo(4, 9);
|
||||||
|
expect(res.draft?.hud?.angleDeg).toBeCloseTo(0, 9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("HUD bezieht sich nach dem zweiten Punkt auf das NEUE (letzte) Segment", () => {
|
||||||
|
const p0: Vec2 = { x: 0, y: 0 };
|
||||||
|
const p1: Vec2 = { x: 4, y: 0 };
|
||||||
|
const [s1] = wallCommand.onInput(wallCommand.init(), { kind: "point", point: p0 }, makeCtx(null));
|
||||||
|
const [s2] = wallCommand.onInput(s1, { kind: "point", point: p1 }, makeCtx(p0));
|
||||||
|
// Nächstes Segment ab p1 nach oben (0,3) → Länge 3, Winkel 90°.
|
||||||
|
const [, res] = wallCommand.onMove(s2, { x: 4, y: 3 }, null, makeCtx(p1));
|
||||||
|
expect(res.draft?.hud?.length).toBeCloseTo(3, 9);
|
||||||
|
expect(res.draft?.hud?.angleDeg).toBeCloseTo(90, 9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("zeigt KEIN HUD vor dem Startpunkt (phase=start)", () => {
|
||||||
|
const [, res] = wallCommand.onMove(wallCommand.init(), { x: 1, y: 1 }, null, makeCtx(null));
|
||||||
|
expect(res.draft).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
import type { Wall, WallType } from "../../model/types";
|
import type { Wall, WallType } from "../../model/types";
|
||||||
import { wallTypeThickness } from "../../model/types";
|
import { wallTypeThickness } from "../../model/types";
|
||||||
import { wallCorners } from "../../model/geometry";
|
import { wallCorners } from "../../model/geometry";
|
||||||
import { uniqueId } from "../../tools/types";
|
import { segmentHud, uniqueId } from "../../tools/types";
|
||||||
import type {
|
import type {
|
||||||
Command,
|
Command,
|
||||||
CommandContext,
|
CommandContext,
|
||||||
@@ -164,14 +164,7 @@ function wallDraft(points: Vec2[], cursor: Vec2 | null, thickness: number): Tool
|
|||||||
}
|
}
|
||||||
const draft: ToolDraft = { preview, vertices: points };
|
const draft: ToolDraft = { preview, vertices: points };
|
||||||
const last = points[points.length - 1];
|
const last = points[points.length - 1];
|
||||||
if (cursor && last && segLen(last, cursor) >= EPS) {
|
if (cursor && last && segLen(last, cursor) >= EPS) draft.hud = segmentHud(last, cursor);
|
||||||
draft.hud = {
|
|
||||||
at: cursor,
|
|
||||||
text: `${segLen(last, cursor).toFixed(2)} m · ${Math.abs(
|
|
||||||
(segAngleDeg(last, cursor) + 360) % 360,
|
|
||||||
).toFixed(0)}°`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return draft;
|
return draft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user