问题描述
我需要在放大图像时计算视口的新位置。
I need to calculate the new position of the viewport when zooming in to an image.
UI构建如下:
- ImagePanel绘制图像
- ImagePanelWrapper是围绕imagePanel的JPanel
- JScrollPane包含ImagePanelWrapper
放大或缩小时,ImagePanel的缩放系数会发生变化,并且会重新计算ImagePanel的首选大小。因此,即使ImagePanel停留在相同的视口点,此面板上的图像也会移动。
When zooming in or out, the ImagePanel's zoom factor is changed and the preferred size of the ImagePanel is being recalculated. Therefore the image on this panel moves, even though the ImagePanel stays at the same viewport point.
当用户按住CTRL并使用鼠标滚轮时,将调用以下方法。给定的点是MouseWheelListener提供的光标位置。利用这些方法的功能,当放大或缩小时,图像已经停留在相同的左上角位置。
The following methods are called when the user holds down CTRL and uses the mouse wheel. The given point is the cursor location provided by the MouseWheelListener. With the functionality in these methods the image is already staying at the same top-left-position when zooming in or out.
问题是我只是弄清楚如何相对于鼠标移动,例如Paint.NET。有什么想法?
The problem is that I just cant figure out how to move relative to the mouse, like Paint.NET for example. Any ideas?
/**
*
*/
public void zoomOut(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f);
Point pos = this.getViewport().getViewPosition();
int newX = (int) (pos.x * 0.9f);
int newY = (int) (pos.y * 0.9f);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
/**
*
*/
public void zoomIn(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f);
Point pos = this.getViewport().getViewPosition();
int newX = (int) (pos.x * 1.1f);
int newY = (int) (pos.y * 1.1f);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
推荐答案
如果这些假设属实:
- 提供的Point相对于视口的左上角。
- 视口的尺寸小于底层ImagePanel。
然后可以调整视口,使光标位于图像中的同一点之前在缩放操作后,如果按以下方式移动:
Then the viewport can be adjusted so that the cursor is over the same point in the image before and after the zoom operation, if moved in the following manner:
/**
*
*/
public void zoomOut(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f);
Point pos = this.getViewport().getViewPosition();
int newX = (int)(point.x*(0.9f - 1f) + 0.9f*pos.x);
int newY = (int)(point.y*(0.9f - 1f) + 0.9f*pos.y);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
/**
*
*/
public void zoomIn(Point point) {
this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f);
Point pos = this.getViewport().getViewPosition();
int newX = (int)(point.x*(1.1f - 1f) + 1.1f*pos.x);
int newY = (int)(point.y*(1.1f - 1f) + 1.1f*pos.y);
this.getViewport().setViewPosition(new Point(newX, newY));
this.imagePanel.revalidate();
this.imagePanel.repaint();
}
这是完整性的数学计算:
Here's the math for completeness' sake:
这篇关于JScrollPane - 相对于鼠标位置进行缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!