2D: Teilpunkte werden auch beim Zeichnen snapbar, aber NUR nach Verweilen

Erweiterung des Hover-Teilpunkte-Features: bisher rein visuell im
Auswahl-Ruhezustand (vorheriger Commit). Nutzer-Wunsch: "wenn der
Snappunkt eines neuen Elements auch [z. B. 200ms] auf der Linie ist,
sollten die Teilpunkte auch für eine gewisse Zeit angezeigt werden und
snapbar sein. Aber nur dann!" -- also auch während des Zeichnens
(Command-Engine, Legacy-Werkzeuge, Griff-Ziehen, Transformieren), aber
bewusst NICHT dauerhaft (sonst würde jede N-tel-Position jeder Linie
den Fang-Kandidatenraum überfluten).

computeSnap() (tools/snapping.ts) bekommt eine modulweite Verweil-
Erkennung (wie lastCoalesceKey in projectSlice.ts) -- bewusst
MODULWEIT statt in SnapInput, weil computeSnap von mehreren
unabhängigen Stellen aufgerufen wird (Command-Engine-Snap-Callback,
Legacy-tool.onMove, Transform, Griff-Editieren) und der Verweil-
Zustand aufrufer-übergreifend gelten muss, damit "verweilt der Cursor
lange genug auf DERSELBEN Linie" unabhängig davon erkannt wird, WELCHER
Aufrufer gerade snappt. Sobald erreicht, werden die `hoverDivideCount`-
gleichen Teilpunkte der verweilten Strecke als normale Snap-Kandidaten
(neuer SnapKind "divide", Priorität wie Mittelpunkt) berücksichtigt --
bei einem Streckenwechsel setzt sich die Verweildauer sofort zurück.

Neuer Marker-Glyph (gefüllte Raute) in SnapMarker (overlays.tsx) für
kind "divide" -- bewusst anders als Mittelpunkt (Linie) und Auf-Kante
(Raute nur Umriss), damit nachvollziehbar bleibt, warum es gerade dort
fängt.

+3 Tests (Fake-Timer-gesteuert: kein Fang vor der Verzögerung, Fang
danach exakt auf dem Drittelpunkt, Verwerfen bei Linienwechsel
zwischendurch). tsc/vitest 925/925 grün.
This commit is contained in:
2026-08-22 00:42:40 +02:00
parent 2af8d6aa1b
commit 605e8910d3
4 changed files with 135 additions and 6 deletions
+9 -1
View File
@@ -37,7 +37,15 @@ export type SnapKind =
| "grid"
| "ortho"
| "extension"
| "angle";
| "angle"
/**
* Teilpunkt einer Linie, NUR fangbar, solange der Cursor lange genug (s.
* `SnapSettings.hoverDivideDelayMs`) auf DERSELBEN Linie verweilt hat (s.
* `computeSnap`s Verweil-Erkennung) — bewusst NICHT dauerhaft aktiv wie die
* übrigen Snap-Arten, sonst würde jede N-tel-Position jeder Linie den
* Fang-Kandidatenraum überfluten.
*/
| "divide";
export interface SnapResult {
/** Gefangener Punkt (Meter). */