Use fixed zoom levels for more stable rendering

This commit is contained in:
fourbites
2025-09-20 01:45:28 +02:00
parent 6da7fa249b
commit fc0beb238c
2 changed files with 30 additions and 6 deletions
@@ -27,7 +27,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingUtilities;
@@ -10,12 +10,12 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class ZoomManager {
protected static final double ZOOM_SNAP_THRESHOLD = 0.05;
protected static final double ZOOM_OUT_FACTOR = 0.9;
protected static final double ZOOM_IN_FACTOR = 1.1;
protected static final double[] DEFAULT_ZOOM_STEPS = { 0.25, 0.3333, 0.5, 1.0, 2.0 };
protected double _zoomLevel = 1.0;
protected double _minZoomLevel = 0.25;
protected double _maxZoomLevel = 2.0;
protected double _zoomSteps[] = DEFAULT_ZOOM_STEPS;
public interface ZoomListener {
@@ -108,6 +108,15 @@ public class ZoomManager {
return new Point(virtX, virtY);
}
/**
* Sets the zoom steps to use when zooming in and out.
*
* @param zoomSteps the zoom steps to set
*/
public void setZoomSteps(double[] zoomSteps) {
_zoomSteps = zoomSteps;
}
/**
* Creates a mouse wheel listener that adjusts the zoom level.
*
@@ -115,8 +124,24 @@ public class ZoomManager {
*/
public MouseWheelListener createMouseWheelListener() {
return e -> {
int closestStepIndex = 0;
double smallestDiff = Math.abs(_zoomLevel - _zoomSteps[0]);
for (int i = 0; i < _zoomSteps.length; i++) {
double diff = Math.abs(_zoomLevel - _zoomSteps[i]);
if (diff < smallestDiff) {
smallestDiff = diff;
closestStepIndex = i;
}
}
int notches = e.getWheelRotation();
scaleZoomLevel(notches > 0 ? ZOOM_OUT_FACTOR : ZOOM_IN_FACTOR);
int newIndex = closestStepIndex + (notches > 0 ? -1 : 1);
if (newIndex < 0) {
newIndex = 0;
} else if (newIndex >= _zoomSteps.length) {
newIndex = _zoomSteps.length - 1;
}
setZoomLevel(_zoomSteps[newIndex]);
};
}