Use fixed zoom levels for more stable rendering
This commit is contained in:
@@ -27,7 +27,6 @@ import java.awt.event.MouseEvent;
|
|||||||
import java.awt.event.MouseWheelEvent;
|
import java.awt.event.MouseWheelEvent;
|
||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
public class ZoomManager {
|
public class ZoomManager {
|
||||||
|
|
||||||
protected static final double ZOOM_SNAP_THRESHOLD = 0.05;
|
protected static final double ZOOM_SNAP_THRESHOLD = 0.05;
|
||||||
protected static final double ZOOM_OUT_FACTOR = 0.9;
|
protected static final double[] DEFAULT_ZOOM_STEPS = { 0.25, 0.3333, 0.5, 1.0, 2.0 };
|
||||||
protected static final double ZOOM_IN_FACTOR = 1.1;
|
|
||||||
|
|
||||||
protected double _zoomLevel = 1.0;
|
protected double _zoomLevel = 1.0;
|
||||||
protected double _minZoomLevel = 0.25;
|
protected double _minZoomLevel = 0.25;
|
||||||
protected double _maxZoomLevel = 2.0;
|
protected double _maxZoomLevel = 2.0;
|
||||||
|
protected double _zoomSteps[] = DEFAULT_ZOOM_STEPS;
|
||||||
|
|
||||||
public interface ZoomListener {
|
public interface ZoomListener {
|
||||||
|
|
||||||
@@ -54,8 +54,8 @@ public class ZoomManager {
|
|||||||
* Useful when the zoom level changes to update the viewport.
|
* Useful when the zoom level changes to update the viewport.
|
||||||
*
|
*
|
||||||
* @param viewport the rectangle to rescale
|
* @param viewport the rectangle to rescale
|
||||||
* @param width the new width
|
* @param width the new width
|
||||||
* @param height the new height
|
* @param height the new height
|
||||||
* @return a new rectangle representing the rescaled bounds
|
* @return a new rectangle representing the rescaled bounds
|
||||||
*/
|
*/
|
||||||
public Rectangle rescaleBounds(Rectangle viewPort, int width, int height) {
|
public Rectangle rescaleBounds(Rectangle viewPort, int width, int height) {
|
||||||
@@ -108,6 +108,15 @@ public class ZoomManager {
|
|||||||
return new Point(virtX, virtY);
|
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.
|
* Creates a mouse wheel listener that adjusts the zoom level.
|
||||||
*
|
*
|
||||||
@@ -115,8 +124,24 @@ public class ZoomManager {
|
|||||||
*/
|
*/
|
||||||
public MouseWheelListener createMouseWheelListener() {
|
public MouseWheelListener createMouseWheelListener() {
|
||||||
return e -> {
|
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();
|
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]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user