Behebe Zoom-Sprung und Zentrierung nach Rauszoomen
Bug 1: deltaY vor Akkumulation auf einen Notch-Wert begrenzen. Plattformspezifische Scroll-Multiplikatoren (Windows-Mausgeschwindigkeit, hohe DPI-Mäuse) können Werte wie 120 statt 40 liefern. Ohne Normierung akkumuliert sich ein Überlaufwert, der Folge-Events sofort auslöst. Bug 2: resetToFitView() setzt nach setFitToWidth(true) explizit scrollPane.setHvalue(0.5) und setVvalue(0.5) (nach layout()-Aufruf), damit vorherige Pan-Scroll-Werte die Zentrierung nicht nachwirken. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+24
-4
@@ -631,12 +631,19 @@ public final class PdfPreviewPane {
|
||||
* Pro Raste (ca. {@value #ZOOM_NOTCH_THRESHOLD} Einheiten) ändert sich der Zoom
|
||||
* um {@value #ZOOM_STEP}. Pro ScrollEvent wird maximal eine Zoom-Stufe angewendet.
|
||||
*
|
||||
* <p>Der Rohwert von {@code deltaY} wird vor der Akkumulation auf einen
|
||||
* Notch-Wert ({@value #ZOOM_NOTCH_THRESHOLD}) begrenzt. Plattformspezifische
|
||||
* Scroll-Multiplikatoren (z. B. Windows-Mausgeschwindigkeit, hohe DPI-Mäuse)
|
||||
* können sonst Werte wie 120 oder mehr pro Raste liefern, was einen
|
||||
* Akkumulator-Überlauf in Folge-Events verursacht.
|
||||
*
|
||||
* @param deltaY vertikaler Scroll-Delta des {@link ScrollEvent}
|
||||
*/
|
||||
private void accumulateAndApplyZoomDelta(double deltaY) {
|
||||
zoomAccumulator += deltaY;
|
||||
// 32a: Pro Mausrad-Raste genau eine Zoom-Stufe (if statt while verhindert
|
||||
// mehrfaches Springen bei großen deltaY-Werten)
|
||||
// Normierung: maximal einen Notch-Wert pro Event akkumulieren, um
|
||||
// plattformspezifische deltaY-Überhöhungen (z. B. 120 statt 40) abzufangen
|
||||
double capped = Math.signum(deltaY) * Math.min(Math.abs(deltaY), ZOOM_NOTCH_THRESHOLD);
|
||||
zoomAccumulator += capped;
|
||||
if (zoomAccumulator >= ZOOM_NOTCH_THRESHOLD) {
|
||||
zoomAccumulator -= ZOOM_NOTCH_THRESHOLD;
|
||||
applyZoom(Math.min(ZOOM_MAX, zoomLevel + ZOOM_STEP));
|
||||
@@ -700,12 +707,18 @@ public final class PdfPreviewPane {
|
||||
/**
|
||||
* Setzt Zoom, Akkumulator und Pan-Zustand zurück und reaktiviert den Fit-to-View-Modus.
|
||||
* Wird beim Laden einer neuen Datei und beim Leeren der Komponente aufgerufen.
|
||||
*
|
||||
* <p>Nach dem Reaktivieren von {@code fitToWidth} werden H- und V-Scroll-Werte
|
||||
* explizit auf 0.5 gesetzt (nach einem {@code layout()}-Aufruf, damit die neuen
|
||||
* Inhaltsgrenzen bekannt sind). Ohne diesen Schritt trägt der ScrollPane ggf. noch
|
||||
* die H/V-Werte aus dem vorherigen Zoom-/Pan-Zustand und zeigt die PDF nach dem
|
||||
* Reset nicht zentriert an.
|
||||
*/
|
||||
private void resetToFitView() {
|
||||
zoomLevel = 1.0;
|
||||
zoomAccumulator = 0.0;
|
||||
naturalViewportWidth = 0.0;
|
||||
// 32e: Pan-Zustand und Mauszeiger zurücksetzen
|
||||
// Pan-Zustand und Mauszeiger zurücksetzen
|
||||
panStartX = -1;
|
||||
panStartY = -1;
|
||||
viewStack.setCursor(null);
|
||||
@@ -714,6 +727,13 @@ public final class PdfPreviewPane {
|
||||
imageView.fitHeightProperty().bind(viewStack.heightProperty());
|
||||
scrollPane.setFitToWidth(true);
|
||||
scrollPane.setFitToHeight(true);
|
||||
// Zentrierung sicherstellen: nach layout() H/V auf Mitte setzen,
|
||||
// damit verbleibende Scroll-Werte aus dem Zoom-/Pan-Modus nicht nachwirken
|
||||
Platform.runLater(() -> {
|
||||
scrollPane.layout();
|
||||
scrollPane.setHvalue(0.5);
|
||||
scrollPane.setVvalue(0.5);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user