Cursor-HUD (VW-Stil) + weiches Winkel-Einrasten im Grundriss

Beim Zeichnen erscheint jetzt direkt am Cursor ein blau umrandetes
Massband-Kästchen mit Länge/Winkel (L: 3.118m  W: 60.000°, Winkel im
Bereich (−180,180]) statt nur in der Befehlszeile. Zusätzlich rastet
der Zugwinkel weich auf gängige Winkel (15°-Vielfache, Toleranz per
Default 2.5°) ein, sobald kein Objekt-Snap greift — mit gelblichem
Winkel-Badge und einer über den Cursor hinaus verlängerten, gestrichelten
Führungslinie (Vectorworks-Vorbild).

- tools/types.ts: ToolDraft.hud um length/angleDeg erweitert (text bleibt
  für Befehle ohne L/W-Paar), neuer segmentHud()-Helper.
- tools/snapping.ts: neue reine Funktion snapCommonAngle() + Einbindung in
  computeSnap (Objekt-Snap > harter Ortho-Zwang > weiches Winkelraster >
  Raster). Neues SnapSettings-Feld commonAngles + commonAngleTolerance,
  neuer SnapKind "angle".
- ui/StatusBar.tsx: Toggle + Toleranz-Eingabe in der Fang-Popover.
- plan/PlanView.tsx: DraftHud- und AngleGuide-Overlay (screen-space,
  zoomunabhängige Größe); die Winkel-Info reitet auf draft.snap mit.
- i18n: snap.commonAngles / snap.commonAngleTolerance (de/en).
- snapping.test.ts: snapCommonAngle-Fälle (exakt/Toleranz/Bereich/
  15°-Raster/Projektion) + Objekt-Snap-Vorrang vor dem Winkelraster.
This commit is contained in:
2026-07-11 00:21:21 +02:00
parent 9133c0961d
commit 3f042eb091
9 changed files with 435 additions and 18 deletions
+23
View File
@@ -222,6 +222,29 @@ function SnapControl({
}
/>
</label>
<label className="sb-snap-row">
<input
type="checkbox"
checked={snap.commonAngles}
disabled={!snap.enabled}
onChange={(e) => onSnapChange({ ...snap, commonAngles: e.target.checked })}
/>
<span>{t("snap.commonAngles")}</span>
</label>
<label className="sb-snap-row sb-snap-row-num">
<span>{t("snap.commonAngleTolerance")}</span>
<input
type="number"
step={0.5}
min={0.5}
max={10}
disabled={!snap.enabled || !snap.commonAngles}
value={snap.commonAngleTolerance}
onChange={(e) =>
onSnapChange({ ...snap, commonAngleTolerance: Number(e.target.value) })
}
/>
</label>
</div>
)}
</span>