Graphics2d zoomen

Lasnik

Mitglied
Hey, ich habe ein Programm, in welchem ich in die Mitte der Gitternetzlinien zoomen will. Ich habe mir viel zu dem Thema angesehen und zuletzt versucht eine StackOverFlow Antwort einzubauen.
Aber egal was ich probiere, es wird immer in die falsche Richtung gezoomt. Wie kann ich also zentral auf das Grid, welches in einem JPanel in einem JFrame integriert ist zoomen?
In den Zeilen 21 - 26 und 72 - 77 ist eigentlich alles relevante
[CODE lang="java" title="Grid.java" highlight="21-26, 72-77"]import java.awt.*;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;

public class Grid {
static int width, height, size, camX, camY;
static double zoom = 1;
static ArrayList<Cell> cells;

public static void init(int width, int height, int size, ArrayList<Cell> cells) {
Grid.width = width;
Grid.height = height;
Grid.size = size;
Grid.cells = cells;
}

static AffineTransform at = new AffineTransform();

public static void render(Graphics2D g2) {
// zooming and panning
at.translate(
(width * size * (1 - zoom)) / 2,
(height * size * (1 - zoom)) / 2);
at.scale(zoom, zoom);
zoom = 1;
g2.setTransform(at);
g2.translate(camX, camY);

for (Cell cell : cells) {
g2.setColor(cell.color);
g2.fillRect(size * cell.x, size * cell.y, size, size);

// count overlapping cells
int times = 0;
for (Cell cellCounter : cells) {
if (cellCounter.x == cell.x && cellCounter.y == cell.y) {
times++;
}
}
if (times > 1) {
g2.setColor(Grid.getContrastColor(cell.color));
g2.setFont(new Font("TimesRoman", Font.PLAIN, size));
g2.drawString(times + "", size * cell.x, size * (cell.y + 1));
}
}

// render Grid
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
g2.setColor(Color.white);
g2.drawRect(size * i, size * j, size, size);
}
}

}


public static void move(Movement move) {
switch (move) {
case GRID_UP:
move(0, 1);
break;
case GRID_DOWN:
move(0, -1);
break;
case GRID_LEFT:
move(1, 0);
break;
case GRID_RIGHT:
move(-1, 0);
break;
case GRID_ZOOM_IN:
zoom = 1.1;
break;
case GRID_ZOOM_OUT:
zoom = 0.9;
break;
}
Main.getStatic.main.frame.repaint();
}

private static void move(int x, int y) {
camX += x * size;
camY += y * size;
}

private static Color getContrastColor(Color color) {
double y = (299 * color.getRed() + 587 * color.getGreen() + 114 * color.getBlue()) / 1000;
return y >= 128 ? Color.black : Color.white;
}
}[/CODE]
 
Beispiel:

Java:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class Zoom {

    class ZoomPanel extends JPanel {
        private double zoom = 1.0;

        public void setZoom(double zoom) {
            this.zoom = zoom;
            repaint();
        }

        public void paintComponent(Graphics g) {
            g.setColor(getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(getForeground());

            Graphics2D g2 = (Graphics2D) g;
            Point2D cam = new Point.Double(400, 300);
            Point2D center = new Point.Double(400, 300); // Mitte der virtuellen "Welt" 
            // Alternativ die Mitte des Panels:
            // Point2D center = Point.Double(getWidth() / 2.0, getHeight() / 2.0); 

            AffineTransform at = new AffineTransform();
            
            at.translate(center.getX() - cam.getX(), center.getY() - cam.getY());
            at.translate(cam.getX() * (1 - zoom),
                         cam.getY() * (1 - zoom));
            at.scale(zoom, zoom);
            g2.setTransform(at);

            g2.fill(new Rectangle2D.Double(cam.getX() - 5, cam.getY() - 5, 10, 10));
            g2.draw(new Rectangle2D.Double(350, 250, 100, 100));
        }
    }


    public void run() {
        ZoomPanel panel = new ZoomPanel();
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(panel);
        frame.setSize(800, 600);
        frame.setVisible(true);

        Timer t = new Timer(500, e -> { 
            Timer timer = (Timer) e.getSource();
            panel.setZoom(panel.zoom + 0.1); 
            if (panel.zoom > 2) {
                timer.stop();
            }
        });
        t.start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Zoom().run());
    }
}
 

Zurück
Oben