I found a few questions similar to the one I have, including this and this, but none that really answered the problem, and it's because I am using a JScrollPane. I found the code necessary for the formula; it's this:
originX -= mouseX / zoom - mouseX;
originY -= mouseY / zoom - mouseY;
So I tried plugging it into a JScrollPane:
JScrollPane scrollPane = drawFrame.scrollPane;
JScrollBar vert = scrollPane.getVerticalScrollBar(),
horiz = scrollPane.getHorizontalScrollBar();
horiz.setValue(
(int)(horiz.getValue() - (float)pastMouseX / zoom + pastMouseX)
);
vert.setValue(
(int)(vert.getValue() - (float)pastMouseY / zoom + pastMouseY)
);
And the point at which the mouse zooms into is all over the place and I don't know why. Here is the minimal reproducible example:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
public class ResizeTest extends JFrame{
JScrollPane scrollPane;
BufferedImage image;
int mouseX, mouseY;
float zoom;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
new ResizeTest();
}
});
}
public ResizeTest(){
zoom = 1;
try{
image = ImageIO.read(new File("a.jpg"));
}catch(IOException e){
e.printStackTrace();
}
JPanel panel = new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.scale(zoom, zoom);
g2.drawImage(image, 0, 0, null);
System.out.println(zoom);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(image.getWidth(), image.getHeight());
}
};
scrollPane = new JScrollPane(panel);
panel.addMouseWheelListener(new MouseWheelListener(){
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if(e.isControlDown()) {
if(e.getWheelRotation() > 0){
zoom /= 1.3333333333f;
if(zoom < 0.125)
zoom = 0.125f;
}
else if (e.getWheelRotation() < 0){
zoom *= 1.3333333333f;
if(zoom > 10)
zoom = 10;
}
if(zoom < 10){
JScrollBar vert = scrollPane.getVerticalScrollBar(),
horiz = scrollPane.getHorizontalScrollBar();
horiz.setValue(
(int)(horiz.getValue() - (float)mouseX / zoom + mouseX)
);
vert.setValue(
(int)(vert.getValue() - (float)mouseY / zoom + mouseY)
);
}
} else {
scrollPane.dispatchEvent(e);
}
panel.repaint();
}
});
panel.addMouseMotionListener(new MouseMotionListener(){
@Override
public void mouseDragged(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
@Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
});
setSize(new Dimension(1200,700));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(scrollPane);
setVisible(true);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(1200, 700);
}
}