Zoom-Prozent relativ zum angewandten Massstab statt zur Einpassung

Die Zoom-Anzeige band 100% bisher an die eingepasste Default-Ansicht, nicht
an den angewandten Papier-Massstab — der Wert driftete willkürlich. Er wird
jetzt in App.tsx aus angewandtem Nenner und Live-Nenner abgeleitet
(scaleDenominator / liveScale * 100): im angewandten Massstab exakt 100%,
hineinzoomen >100%, herauszoomen <100%. Die fit-basierte onZoom-Meldekette
aus PlanView entfällt (Single Source).
This commit is contained in:
2026-07-04 00:02:50 +02:00
parent 5d99701024
commit 989e61c261
2 changed files with 9 additions and 26 deletions
+9 -14
View File
@@ -274,8 +274,15 @@ export default function App() {
const [liveScale, setLiveScale] = useState<number | null>(null); const [liveScale, setLiveScale] = useState<number | null>(null);
// Cursor in Modell-Metern (aus der Plan-Ansicht) bzw. null (nicht über Plan). // Cursor in Modell-Metern (aus der Plan-Ansicht) bzw. null (nicht über Plan).
const [cursor, setCursor] = useState<Vec2 | null>(null); const [cursor, setCursor] = useState<Vec2 | null>(null);
// Live-Zoom der Plan-Ansicht in Prozent (eingepasst = 100 %). // Live-Zoom in Prozent RELATIV zum angewandten Papier-Massstab: 100 % =
const [zoomPercent, setZoomPercent] = useState(100); // Live-Ansicht steht exakt im angewandten Massstab (liveScale == scaleDenominator).
// Reinzoomen > 100 %, Rauszoomen < 100 %. Einzige Quelle: angewandter Nenner
// (scaleDenominator) / Live-Nenner (liveScale). Ohne Live-Massstab (keine
// Plan-Ansicht) Fallback 100 %.
const zoomPercent =
liveScale != null && liveScale > 0
? (scaleDenominator / liveScale) * 100
: 100;
// ── Zeichenwerkzeuge (transienter View-State; bleibt lokal) ─────────────── // ── Zeichenwerkzeuge (transienter View-State; bleibt lokal) ───────────────
// Aktives Werkzeug, Werkzeug-Parameter (Wandtyp/Kategorie/Linienstil), Snap- // Aktives Werkzeug, Werkzeug-Parameter (Wandtyp/Kategorie/Linienstil), Snap-
@@ -2822,7 +2829,6 @@ export default function App() {
displayKey={displayKey} displayKey={displayKey}
planViewRef={planViewRef} planViewRef={planViewRef}
onCursor={setCursor} onCursor={setCursor}
onZoom={setZoomPercent}
onScale={setLiveScale} onScale={setLiveScale}
selectedWallIds={selectedWallIds} selectedWallIds={selectedWallIds}
selectedCeilingIds={selectedCeilingIds} selectedCeilingIds={selectedCeilingIds}
@@ -3762,7 +3768,6 @@ function Content({
displayKey, displayKey,
planViewRef, planViewRef,
onCursor, onCursor,
onZoom,
onScale, onScale,
selectedWallIds, selectedWallIds,
selectedCeilingIds, selectedCeilingIds,
@@ -3824,7 +3829,6 @@ function Content({
displayKey: string; displayKey: string;
planViewRef: React.RefObject<PlanViewHandle>; planViewRef: React.RefObject<PlanViewHandle>;
onCursor: (model: Vec2 | null) => void; onCursor: (model: Vec2 | null) => void;
onZoom: (percent: number) => void;
onScale: (n: number) => void; onScale: (n: number) => void;
selectedWallIds: string[]; selectedWallIds: string[];
selectedCeilingIds: string[]; selectedCeilingIds: string[];
@@ -3893,7 +3897,6 @@ function Content({
mono={mono} mono={mono}
planViewRef={planViewRef} planViewRef={planViewRef}
onCursor={onCursor} onCursor={onCursor}
onZoom={onZoom}
onScale={onScale} onScale={onScale}
selectedWallIds={selectedWallIds} selectedWallIds={selectedWallIds}
selectedCeilingIds={selectedCeilingIds} selectedCeilingIds={selectedCeilingIds}
@@ -3943,7 +3946,6 @@ function Content({
mono={mono} mono={mono}
planViewRef={planViewRef} planViewRef={planViewRef}
onCursor={onCursor} onCursor={onCursor}
onZoom={onZoom}
onScale={onScale} onScale={onScale}
selectedWallIds={selectedWallIds} selectedWallIds={selectedWallIds}
selectedCeilingIds={selectedCeilingIds} selectedCeilingIds={selectedCeilingIds}
@@ -4024,7 +4026,6 @@ function Content({
mono={mono} mono={mono}
planViewRef={planViewRef} planViewRef={planViewRef}
onCursor={onCursor} onCursor={onCursor}
onZoom={onZoom}
onScale={onScale} onScale={onScale}
selectedWallIds={selectedWallIds} selectedWallIds={selectedWallIds}
selectedCeilingIds={selectedCeilingIds} selectedCeilingIds={selectedCeilingIds}
@@ -4064,7 +4065,6 @@ function LevelPlanView({
mono, mono,
planViewRef, planViewRef,
onCursor, onCursor,
onZoom,
onScale, onScale,
selectedWallIds, selectedWallIds,
selectedCeilingIds, selectedCeilingIds,
@@ -4097,7 +4097,6 @@ function LevelPlanView({
mono: boolean; mono: boolean;
planViewRef: React.RefObject<PlanViewHandle>; planViewRef: React.RefObject<PlanViewHandle>;
onCursor: (model: Vec2 | null) => void; onCursor: (model: Vec2 | null) => void;
onZoom: (percent: number) => void;
onScale: (n: number) => void; onScale: (n: number) => void;
selectedWallIds: string[]; selectedWallIds: string[];
selectedCeilingIds: string[]; selectedCeilingIds: string[];
@@ -4171,7 +4170,6 @@ function LevelPlanView({
plan={plan} plan={plan}
resetKey={level.id} resetKey={level.id}
onCursor={onCursor} onCursor={onCursor}
onZoom={onZoom}
onScale={onScale} onScale={onScale}
selectedWallIds={selectedWallIds} selectedWallIds={selectedWallIds}
selectedCeilingIds={selectedCeilingIds} selectedCeilingIds={selectedCeilingIds}
@@ -4217,7 +4215,6 @@ function SectionPlanView({
mono, mono,
planViewRef, planViewRef,
onCursor, onCursor,
onZoom,
onScale, onScale,
selectedWallIds, selectedWallIds,
selectedCeilingIds, selectedCeilingIds,
@@ -4246,7 +4243,6 @@ function SectionPlanView({
mono: boolean; mono: boolean;
planViewRef: React.RefObject<PlanViewHandle>; planViewRef: React.RefObject<PlanViewHandle>;
onCursor: (model: Vec2 | null) => void; onCursor: (model: Vec2 | null) => void;
onZoom: (percent: number) => void;
onScale: (n: number) => void; onScale: (n: number) => void;
selectedWallIds: string[]; selectedWallIds: string[];
selectedCeilingIds: string[]; selectedCeilingIds: string[];
@@ -4330,7 +4326,6 @@ function SectionPlanView({
plan={plan} plan={plan}
resetKey={level.id} resetKey={level.id}
onCursor={onCursor} onCursor={onCursor}
onZoom={onZoom}
onScale={onScale} onScale={onScale}
selectedWallIds={selectedWallIds} selectedWallIds={selectedWallIds}
selectedCeilingIds={selectedCeilingIds} selectedCeilingIds={selectedCeilingIds}
-12
View File
@@ -210,11 +210,6 @@ export interface PlanViewProps {
* verhält sich die Ansicht wie zuvor. * verhält sich die Ansicht wie zuvor.
*/ */
onCursor?: (model: Vec2 | null) => void; onCursor?: (model: Vec2 | null) => void;
/**
* Meldet den aktuellen Zoom in Prozent relativ zur eingepassten Ansicht
* (100 % = eingepasst). Optional.
*/
onZoom?: (percent: number) => void;
/** /**
* Meldet den LIVE Papier-Massstab als Nenner N (1:N), berechnet aus dem * Meldet den LIVE Papier-Massstab als Nenner N (1:N), berechnet aus dem
* aktuellen Ausschnitt + Canvas-Größe + dpi (docs/design/plans-output.md §3). * aktuellen Ausschnitt + Canvas-Größe + dpi (docs/design/plans-output.md §3).
@@ -351,7 +346,6 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
plan, plan,
resetKey, resetKey,
onCursor, onCursor,
onZoom,
onScale, onScale,
onSelect, onSelect,
onMarquee, onMarquee,
@@ -554,12 +548,6 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
}; };
}, []); }, []);
// Zoom in Prozent (eingepasst = 100 %) nach oben melden: kleinere viewBox-
// Breite = stärker hineingezoomt. Reiner Bericht; ändert die Ansicht nicht.
useEffect(() => {
onZoom?.((defaultView.w / view.w) * 100);
}, [onZoom, defaultView.w, view.w]);
// LIVE Papier-Massstab (1:N) nach oben melden. Berechnung aus der effektiven // LIVE Papier-Massstab (1:N) nach oben melden. Berechnung aus der effektiven
// meet-Skala (Bildschirm-px je viewBox-Einheit) → px je Meter → mm je Meter, // meet-Skala (Bildschirm-px je viewBox-Einheit) → px je Meter → mm je Meter,
// verglichen mit der Papier-Abbildung. Aktualisiert bei Ausschnitts-/Größen- // verglichen mit der Papier-Abbildung. Aktualisiert bei Ausschnitts-/Größen-