Swing Apache Batik - Zoom an einer bestimmten Stelle

Dieses Thema Swing - Apache Batik - Zoom an einer bestimmten Stelle im Forum "Allgemeine Java-Themen" wurde erstellt von FrittenFritze, 8. Dez. 2016.

Thema: Apache Batik - Zoom an einer bestimmten Stelle Moin zusammen, ich sitze gerade an einem Problem und zwar, ich verwende in meinem Projekt Apache Batik. s gibt dort...

  1. Moin zusammen,

    ich sitze gerade an einem Problem und zwar, ich verwende in meinem Projekt Apache Batik. s gibt dort die Möglichkeit die geladene SVG Grafik zu zoomen, das funktioniert auch soweit sehr gut.

    Code (Text):

    import java.awt.Point;
    import java.awt.event.MouseWheelEvent;
    import java.awt.event.MouseWheelListener;
    import java.awt.geom.AffineTransform;

    import org.apache.batik.swing.JSVGCanvas;

    public class WDSMouseWheelListener implements MouseWheelListener {
     
       protected JSVGCanvas _svgCanvas;
       protected double _factor = 0.1;
     
       public WDSMouseWheelListener (JSVGCanvas svgCanvas) {
         this._svgCanvas = svgCanvas;
       }

       @Override
       public void mouseWheelMoved(MouseWheelEvent e) {
         AffineTransform at = _svgCanvas.getRenderingTransform();
       
         double scaleX = at.getScaleX();
         double  scaleY = at.getScaleY();
     
      if (e.getWheelRotation() > 0) {
      scaleX = scaleX - _factor;
      scaleY = scaleY - _factor;
      } else {
      scaleX = scaleX + _factor;
      scaleY = scaleY + _factor;
      }
     
      if (scaleX < 0.1) {
      return;
      }
     
      at.setToScale(scaleX, scaleY);
      _svgCanvas.setRenderingTransform(at, true);
       }

    }
     
    Nur ist es aber so, dass die Grafik an der oberen linken Ecke aufgehängt ist und es von da aus gezoomt wird, was sehr komisch aussieht. Sprich es ist nicht so, dass die Grafik am Mauscursor gezoomt wird, was an der Stelle natürlicher wäre.

    Über den JSVGCanvas kriege ich zwar die Cursorposition raus, mehr aber auch nicht...

    Hat jemand eine Idee, wie es doch gehen könnte? Ich habe leider nichts diesbezüglich in der Doku gefunden :(
     
    Zuletzt bearbeitet: 8. Dez. 2016
  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. Du könntest das hier versuchen:
    Code (Java):
    at.translate(mousePosX, mousePosY).scale(1.1, 1.1).translate(-mousePosX, -mousePosY)
     
  4. Guten Morgen erstmal und sorry für die späte Rückmeldung.

    Ich habe es ausprobiert:

    Code (Text):

    public class TestMouseWheelListener implements java.awt.event.MouseWheelListener {

       @Override
       public void mouseWheelMoved(MouseWheelEvent e) {
         JSVGCanvas canvas = null;
         int wheelRotation = e.getWheelRotation();
         double scaleX = 0;
         double scaleY = 0;
         double stepSize = 0.1;
         
         if (e.getSource() instanceof JSVGCanvas) {
           canvas = (JSVGCanvas) e.getSource();
           scaleX = canvas.getRenderingTransform().getScaleX();
           scaleY = canvas.getRenderingTransform().getScaleY();
           
           System.out.println ("OLD: " + scaleX + ":" + scaleY);
         }
         
         switch (wheelRotation) {
         case -1:
           scaleX = scaleX - stepSize;
           scaleY = scaleY - stepSize;
           break;
         case 1:
           scaleX = scaleX + stepSize;
           scaleY = scaleY + stepSize;
           break;
         }
         
         System.out.println (wheelRotation);
         System.out.println ("New: " + scaleX + ":" + scaleY);
         
         AffineTransform at = canvas.getRenderingTransform();
         at.translate(e.getX(), e.getY());
         at.scale(scaleX, scaleY);
         at.translate(-e.getX(), -e.getY());
         canvas.setRenderingTransform(at, true);
       }
    }
     
    Das Ergebnis sieht so aus (System.out):

    Das heißt, dass Bild wird nur noch größer... und dann auch in riesigen Schritten. Beim ersten und dem zweiten Inkrementieren aber scheint es sauber zu funktionieren...

    Ideen?
     
  5. In deinem Code sind scaleX und Y immer positiv auch nachdem du das Mausrad ein paar mal rückwärts bewegt hast.
    Setze scaleX und scaleY auf 1.1 bzw -1.1 je nachdem in welche Richtung gescrollt wurde. getScaleX und getScaleY brauchst du nicht und du musst auch nichts addieren.
     
  6. Hab es gestern doch noch hinbekommen:

    Code (Text):

    public class TestMouseWheelListener implements java.awt.event.MouseWheelListener {

       private double _scaleX = 1;
      private double _scaleY = 1;
      private double _stepSize = 0.1;

        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
        JSVGCanvas canvas = null;
        int wheelRotation = e.getWheelRotation();
     
        Point2D p1 = e.getPoint();
        Point2D p2 = null;
     
        if (e.getSource() instanceof JSVGCanvas) {
        canvas = (JSVGCanvas) e.getSource();
        }
     
        AffineTransform at = canvas.getRenderingTransform();
     
        try {
           p2 = at.inverseTransform(p1, null);
         } catch (NoninvertibleTransformException e1) {
           e1.printStackTrace();
         }
     
        System.out.println ("OLD: " + _scaleX + ":" + _scaleY);
     
        _scaleX -= (_stepSize * e.getWheelRotation());
        _scaleY -= (_stepSize * e.getWheelRotation());
        _scaleX = Math.max(_scaleX, _stepSize);
        _scaleY = Math.max(_scaleY, _stepSize);
     
        System.out.println (wheelRotation);
     
        System.out.println ("New: " + _scaleX + ":" + _scaleY);
     
        at.setToIdentity();
        at.translate(p1.getX(), p1.getY());
        at.scale(_scaleX, _scaleY);
        at.translate(-p2.getX(), -p2.getY());
        canvas.setRenderingTransform(at, true);
        }
       }
     
    Macht genau das, was es soll :)

    Was ist aber nicht verstehe, was machen diese beiden Zeilen denn genau?

    Code (Text):

        at.translate(p1.getX(), p1.getY());
        at.scale(_scaleX, _scaleY);
        at.translate(-p2.getX(), -p2.getY());
     
     
  7. KOSTENLOSES Java-Grundlagen Training im Wert von 39 € Sichere dir hier den kostenlosen Zugriff auf umfangreiches Java-Know How und starte richtig durch!