From 7d3fd40cacb8ed0231675a63b5106cf501f4d4fb Mon Sep 17 00:00:00 2001 From: Karim Date: Thu, 20 Aug 2026 21:59:19 +0200 Subject: [PATCH] =?UTF-8?q?2D:=20Inline-Text-Editor=20nicht=20mehr=20zooma?= =?UTF-8?q?bh=C3=A4ngig=20skaliert=20(riesig/winzig-Bug)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nutzer-Report nach dem Sichtbarkeits-Fix: Editor erscheint "riesig", nicht über dem Ankerpunkt, Enter erzeugt keine neue Zeile. Ursache: die Editor- Box (Toolbar + Text) bekam via transform:scale() dieselbe Skalierung wie die Modell-Geometrie (scale = heightM·pxPerMeter/16) — bei normalem/nahem Arbeits-Zoom beim Textplatzieren wird das schnell 3-15x, die GESAMTE Toolbar (Buttons, Dropdowns) skaliert mit hoch und sprengt den Bildschirm. Plausible Folge fürs Enter-Problem: bei so einer Verzerrung landet der Fokus nicht zuverlässig in der eigentlichen Text-Fläche (rt-surface), sondern z. B. auf einem der riesigen Toolbar-Buttons, wo Enter nichts mit Zeilenumbruch zu tun hat. Fix: kein transform:scale() mehr. Die ANKER-Position folgt weiter dem echten Zoom (vbToClient/toScreen, WO die Box aufgeht bleibt korrekt), aber die Editor-GRÖSSE (Schrift/Toolbar) bleibt jetzt immer bei ihrer normalen, zoomunabhängigen CSS-Grösse — wie im Raumstempel-/Layout-Dialog. Die Textspalten-Breite (wrapWidth) folgt weiterhin der Modell-Breite, aber über eine FESTE Umrechnung (220px/m) statt dem Live-Zoom, damit der Rahmen beim Rein-/Rauszoomen während des Tippens nicht ständig neu umbricht. tsc -b / vitest run (919/919) / npm run build grün. Konnte die konkrete DOM-Fokus-Kette nicht interaktiv nachvollziehen (kein Browser-Tool verfügbar) — Nutzer prüft erneut. --- src/plan/PlanView.tsx | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/plan/PlanView.tsx b/src/plan/PlanView.tsx index 8afb0b9..993d35a 100644 --- a/src/plan/PlanView.tsx +++ b/src/plan/PlanView.tsx @@ -2496,23 +2496,24 @@ export const PlanView = forwardRef( ); if (!prim) return null; const doc = prim.doc ?? docFromText(prim.text, prim.marks ?? {}); - const pxPerM = currentPxPerMeter(); + // Anker-POSITION folgt weiter dem echten Zoom (vbToClient/toScreen) — + // die Box soll am richtigen Ort aufgehen. Die Editor-GRÖSSE (Schrift + + // Toolbar) bleibt dagegen bewusst zoomUNabhängig (keine transform:scale + // mehr): bei nahem Zoom wurde das vorher riesig (Toolbar skalierte mit + // hoch), bei fernem Zoom unbenutzbar winzig — Nutzer-Report. Die + // Editor-Breite folgt bei der Textspalte trotzdem der Modell-Breite, + // aber über eine FESTE (nicht Live-Zoom-)Umrechnung, damit der Rahmen + // nicht bei jedem Rein-/Rauszoomen während des Tippens die Zeilen + // neu umbricht. + const EDIT_PX_PER_M = 220; const topAnchor = toScreen({ x: prim.at.x, y: prim.at.y + prim.heightM }); const screen = vbToClient(topAnchor.x, topAnchor.y); - const FONT_PX_AT_12PT = 16; // 12pt @ 96dpi (RichTextEditor-Default, s. LayoutSheet.tsx). - const scale = (prim.heightM * pxPerM) / FONT_PX_AT_12PT; - // MIT wrapWidth (Textspalte): feste Breite, Editor bricht live um (nowrap - // AUS). OHNE (Text-Werkzeug): keine feste Breite — `.planview-inline-text - // .rt-surface` steht auf nowrap (s. styles.css), die Box wächst mit jedem - // Zeichen; eine Mindestbreite verhindert eine unsichtbare 0px-Box beim - // leeren Start (der eigentliche Grund, warum der Anker bisher unsichtbar - // blieb — `width:undefined` kollabierte auf shrink-to-fit von NICHTS). const hasWrap = !!prim.wrapWidth; - const widthPx = hasWrap ? (prim.wrapWidth! * pxPerM) / scale : undefined; + const widthPx = hasWrap ? prim.wrapWidth! * EDIT_PX_PER_M : undefined; const minWidthPx = hasWrap ? undefined : 160; // Aufgezogener Textspalten-Rahmen (textbox.ts): dessen Höhe als // Mindesthöhe des Editors — wächst bei mehr Text darüber hinaus. - const minHeightPx = editTextMinHeightM ? (editTextMinHeightM * pxPerM) / scale : undefined; + const minHeightPx = editTextMinHeightM ? editTextMinHeightM * EDIT_PX_PER_M : undefined; return ( <>
( width: widthPx, minWidth: minWidthPx, minHeight: minHeightPx, - transform: `scale(${scale})`, - transformOrigin: "0 0", }} onPointerDown={(e) => e.stopPropagation()} onKeyDown={(e) => {