2D: Hover-Teilpunkte auf Linien (konfigurierbare Verzögerung + Anzahl)

Neues Feature (Nutzer-Wunsch): ruht der Cursor im Auswahl-Ruhezustand
(kein Werkzeug/Drag) länger als eine einstellbare Zeit (Default 300ms)
auf einem 2D-Linien-Segment, erscheinen dessen gleiche Teilpunkte kurz
mit Akzentfarbe -- bei 2 Teilen (Default) nur der Mittelpunkt, bei 3/4/…
entsprechend mehr. Reine Sichtbarkeits-Hilfe, kein neues Snap-Ziel.

Verzögerung (ms) und Teile-Anzahl sind unten im Footer einstellbar, im
bestehenden Fang-Popover (StatusBar.tsx SnapControl) als zwei weitere
Zahlenfelder -- neue Felder hoverDivideDelayMs/hoverDivideCount auf
SnapSettings (tools/types.ts), NICHT an snap.enabled gekoppelt (eigenes,
vom Fang unabhängiges visuelles Feature).

PlanView.tsx: neue nearestLineSegment()-Suche (dieselbe Bildschirm-Nähe-
Logik wie pickDrawing, liefert aber die zwei Endpunkte des konkret
gehoverten Segments einer Polylinie, nicht nur die drawingId). Ein
Timer verankert/verwirft die Anzeige bei Segment-Wechsel; die beiden
neuen Props (hoverDivideDelayMs/hoverDivideCount) werden wie snapColor
durch viewportContent.tsx bis zu PlanView durchgereicht.

tsc/vitest 922/922 grün. Manuell in der App zu prüfen (Pointer-Hover
ist nicht automatisiert testbar, wie die übrigen Griff-Interaktions-
Fixes dieser Session).
This commit is contained in:
2026-08-22 00:34:59 +02:00
parent c5c60d3df5
commit 2af8d6aa1b
7 changed files with 189 additions and 2 deletions
+22
View File
@@ -62,6 +62,8 @@ export function Content({
hairline,
marqueeColor,
snapColor,
hoverDivideDelayMs,
hoverDivideCount,
renderMode,
view3d,
fov,
@@ -141,6 +143,8 @@ export function Content({
marqueeColor: string;
/** Farbe der Snap-/Endpunkt-Hervorhebung im Grundriss. */
snapColor: string;
hoverDivideDelayMs?: number;
hoverDivideCount?: number;
renderMode: RenderMode;
/** Kanonischer 3D-Blickwinkel (Preset) der Perspektive. */
view3d: View3d;
@@ -291,6 +295,8 @@ export function Content({
hairline={hairline}
marqueeColor={marqueeColor}
snapColor={snapColor}
hoverDivideDelayMs={hoverDivideDelayMs}
hoverDivideCount={hoverDivideCount}
mono={mono}
planViewRef={planViewRef}
onCursor={onCursor}
@@ -353,6 +359,8 @@ export function Content({
hairline={hairline}
marqueeColor={marqueeColor}
snapColor={snapColor}
hoverDivideDelayMs={hoverDivideDelayMs}
hoverDivideCount={hoverDivideCount}
mono={mono}
planViewRef={planViewRef}
onCursor={onCursor}
@@ -458,6 +466,8 @@ export function Content({
hairline={hairline}
marqueeColor={marqueeColor}
snapColor={snapColor}
hoverDivideDelayMs={hoverDivideDelayMs}
hoverDivideCount={hoverDivideCount}
mono={mono}
planViewRef={planViewRef}
onCursor={onCursor}
@@ -511,6 +521,8 @@ function LevelPlanView({
hairline,
marqueeColor,
snapColor,
hoverDivideDelayMs,
hoverDivideCount,
mono,
planViewRef,
onCursor,
@@ -557,6 +569,8 @@ function LevelPlanView({
hairline: boolean;
marqueeColor: string;
snapColor: string;
hoverDivideDelayMs?: number;
hoverDivideCount?: number;
mono: boolean;
planViewRef: React.RefObject<PlanViewHandle>;
onCursor: (model: Vec2 | null) => void;
@@ -678,6 +692,8 @@ function LevelPlanView({
hairline={hairline}
marqueeColor={marqueeColor}
snapColor={snapColor}
hoverDivideDelayMs={hoverDivideDelayMs}
hoverDivideCount={hoverDivideCount}
selectedDrawingId={selectedDrawingId}
selectedDrawingIds={selectedDrawingIds}
gripHandlers={gripHandlers}
@@ -703,6 +719,8 @@ function SectionPlanView({
hairline,
marqueeColor,
snapColor,
hoverDivideDelayMs,
hoverDivideCount,
mono,
planViewRef,
onCursor,
@@ -744,6 +762,8 @@ function SectionPlanView({
hairline: boolean;
marqueeColor: string;
snapColor: string;
hoverDivideDelayMs?: number;
hoverDivideCount?: number;
mono: boolean;
planViewRef: React.RefObject<PlanViewHandle>;
onCursor: (model: Vec2 | null) => void;
@@ -890,6 +910,8 @@ function SectionPlanView({
hairline={hairline}
marqueeColor={marqueeColor}
snapColor={snapColor}
hoverDivideDelayMs={hoverDivideDelayMs}
hoverDivideCount={hoverDivideCount}
selectedDrawingId={selectedDrawingId}
selectedDrawingIds={selectedDrawingIds}
gripHandlers={gripHandlers}