From d6fde93c57f3a8a46a77deb583992f664a0f341e Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 21 Aug 2026 19:48:14 +0200 Subject: [PATCH] =?UTF-8?q?2D:=20Inline-Text-Editor-Nachbesserung=20?= =?UTF-8?q?=E2=80=94=20WYSIWYG-Textgr=C3=B6sse,=20Toolbar=20bleibt=20norma?= =?UTF-8?q?l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nutzer-Report: nach dem vorigen Fix (kein transform:scale() mehr) war die Feldgrösse jetzt fest/zoomunabhängig — das getippte Feld sollte aber genau so aussehen wie der später gerenderte Text (Schriftgrösse) UND genau so gross sein wie das gezeichnete Feld selbst (Breite/Höhe), beides am echten Zoom. Lösung: Position/Breite/Feldhöhe/Schriftgrösse folgen wieder alle currentPxPerMeter() (live) — aber die Schriftgrösse geht NICHT mehr über transform:scale() auf die GANZE Box (das hatte die Toolbar beim Reinzoomen mit aufgebläht, der vorige Bug), sondern nur auf die Textfläche selbst via CSS-Variable (--rt-font-size/--rt-min-height, gesetzt auf dem Wrapper, geerbt bis zu .rt-surface in styles.css). Die Toolbar (.rt-toolbar) referenziert diese Variable nicht und bleibt dadurch immer normal gross und bedienbar, unabhängig vom Zoom — nur der Text selbst ist WYSIWYG. tsc -b / vitest run (919/919) / npm run build grün. Nutzer prüft erneut in der laufenden App (kein Browser-Tool hier verfügbar für eigene visuelle Kontrolle). --- src/plan/PlanView.tsx | 34 ++++++++++++++++++++-------------- src/styles.css | 10 +++++++++- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/plan/PlanView.tsx b/src/plan/PlanView.tsx index 993d35a..e400d2a 100644 --- a/src/plan/PlanView.tsx +++ b/src/plan/PlanView.tsx @@ -13,6 +13,7 @@ import { useRef, useState, } from "react"; +import type { CSSProperties } from "react"; import type { HatchRender, Plan, Primitive } from "./generatePlan"; import type { EdgeGrip, Vec2 } from "../model/types"; import type { ToolHandlers, ToolId, ToolMods } from "../tools/types"; @@ -2496,24 +2497,29 @@ export const PlanView = forwardRef( ); if (!prim) return null; const doc = prim.doc ?? docFromText(prim.text, prim.marks ?? {}); - // 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; + // WYSIWYG: Position, Breite, Feldhöhe UND Schriftgrösse folgen alle dem + // echten Zoom (currentPxPerMeter) — die Box soll exakt so aussehen wie + // der spätere gerenderte Text, in genau der Grösse des gezeichneten + // Feldes (Nutzer-Wunsch). Die Schriftgrösse geht NICHT über + // transform:scale() auf die ganze Box (das skalierte vorher die + // Toolbar mit hoch und sprengte sie beim Reinzoomen), sondern NUR auf + // die Textfläche via CSS-Variable (--rt-font-size/--rt-min-height, + // s. styles.css `.planview-inline-text .rt-surface`) — die Toolbar + // bleibt dadurch immer normal gross und bedienbar. + const pxPerM = currentPxPerMeter(); const topAnchor = toScreen({ x: prim.at.x, y: prim.at.y + prim.heightM }); const screen = vbToClient(topAnchor.x, topAnchor.y); const hasWrap = !!prim.wrapWidth; - const widthPx = hasWrap ? prim.wrapWidth! * EDIT_PX_PER_M : undefined; + const widthPx = hasWrap ? prim.wrapWidth! * pxPerM : undefined; const minWidthPx = hasWrap ? undefined : 160; + const fontSizePx = Math.max(9, prim.heightM * pxPerM); // 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 * EDIT_PX_PER_M : undefined; + // Mindesthöhe der Textfläche — wächst bei mehr Text darüber hinaus. + const minHeightPx = editTextMinHeightM ? editTextMinHeightM * pxPerM : undefined; + const cssVars = { + "--rt-font-size": `${fontSizePx}px`, + ...(minHeightPx ? { "--rt-min-height": `${minHeightPx}px` } : {}), + } as CSSProperties; return ( <>
( top: screen.y, width: widthPx, minWidth: minWidthPx, - minHeight: minHeightPx, + ...cssVars, }} onPointerDown={(e) => e.stopPropagation()} onKeyDown={(e) => { diff --git a/src/styles.css b/src/styles.css index ca43546..488b1f0 100644 --- a/src/styles.css +++ b/src/styles.css @@ -6789,8 +6789,16 @@ body { .planview-inline-text .rt-editor { min-height: inherit; } +/* WYSIWYG: die Schriftgrösse UND die Feldhöhe der Textfläche folgen dem + echten Zoom (--rt-font-size/--rt-min-height, inline von PlanView.tsx + gesetzt, per CSS-Var-Vererbung bis hierher durchgereicht) — NUR die + Textfläche, NICHT die Toolbar (.rt-toolbar bleibt bei ihrer normalen, + immer bedienbaren Grösse). So sieht der getippte Text wie der später + gerenderte aus, ohne dass Buttons/Dropdowns beim Reinzoomen riesig werden + (der vorige Bug mit transform:scale() auf die GANZE Box). */ .planview-inline-text .rt-surface { - min-height: 1.4em; + font-size: var(--rt-font-size, 13px); + min-height: var(--rt-min-height, 1.4em); padding: 2px 4px; } /* Text-Werkzeug ohne Spaltenbreite: kein Wortumbruch — die Box wächst in der