Dear Batik-Experts,
weeks ago I asked the question about how I can center a certain point in
a given svg-file, it worked very well with the answer provided by Michael.
But after I added the viewbox attribute to the svg-file today, I
suddenly found the centering not working properly again (at least after
I resize the gui with maximize for instance)...
I couldn't understand why it's not working, so could someone please take
a look at the codes below and tell me why or how I can fix this?
best regards,
Cui
package rotationTest;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class RotationTest extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
private JSVGCanvas canvas;
private Document svgDoc;
private static final int offset = 20;
private static final int bgWidth = 200;
private static final int bgHeight = 300;
private static final int circleX = 80;
private static final int circleY = 100;
public RotationTest(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().setLayout(new BorderLayout());
this.canvas = new JSVGCanvas();
this.canvas.setDocumentState (JSVGCanvas.ALWAYS_DYNAMIC);
DOMImplementation dom =
SVGDOMImplementation.getDOMImplementation ();
svgDoc =
dom.createDocument(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_SVG_TAG, null);
this.initBackGround();
this.initBall();
this.initCenterBtn();
this.canvas.setDocument(svgDoc);
Element rootE = svgDoc.getDocumentElement();
rootE.setAttributeNS(null, SVGConstants.SVG_WIDTH_ATTRIBUTE,
bgWidth+2*offset+"");
rootE.setAttributeNS(null, SVGConstants.SVG_HEIGHT_ATTRIBUTE,
bgHeight+2*offset+"");
rootE.setAttributeNS(null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE,
"0 0 "+(bgWidth+2*offset)+" "+(bgHeight+2*offset));
this.canvas.setMySize(new Dimension(bgWidth+2*offset,
bgHeight+2*offset));
this.getContentPane().add(this.canvas, "Center");
this.pack();
this.setVisible(true);
}
private void initCenterBtn() {
JButton centerBtn = new JButton("Center");
centerBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
center();
}
});
this.getContentPane().add(centerBtn, "North");
}
private void center(){
try{
AffineTransform at = this.canvas.getRenderingTransform();
Point2D circleTemp = new Point2D.Double(circleX, circleY);
at.transform(circleTemp, circleTemp);
double offsetX = this.canvas.getWidth()/2-circleTemp.getX();
double offsetY = this.canvas.getHeight()/2-circleTemp.getY();
double angle = getRotationAngle(at);
at.rotate(-angle);
at.translate(offsetX/at.getScaleX(), offsetY/at.getScaleY());
at.rotate(angle);
this.canvas.setRenderingTransform(at);
}catch(Exception e){
e.printStackTrace();
}
}
private void initBackGround(){
Element bgE =
svgDoc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_RECT_TAG);
svgDoc.getDocumentElement().appendChild(bgE);
bgE.setAttributeNS(null, SVGConstants.SVG_FILL_ATTRIBUTE,
"lightblue");
bgE.setAttributeNS(null, SVGConstants.SVG_X_ATTRIBUTE, ""+offset);
bgE.setAttributeNS(null, SVGConstants.SVG_Y_ATTRIBUTE, ""+offset);
bgE.setAttributeNS(null, SVGConstants.SVG_WIDTH_ATTRIBUTE,
""+bgWidth);
bgE.setAttributeNS(null, SVGConstants.SVG_HEIGHT_ATTRIBUTE,
""+bgHeight);
}
private void initBall(){
Element ballE =
svgDoc.createElementNS(SVGConstants.SVG_NAMESPACE_URI,
SVGConstants.SVG_CIRCLE_TAG);
svgDoc.getDocumentElement().appendChild(ballE);
ballE.setAttributeNS(null, SVGConstants.SVG_CX_ATTRIBUTE,
""+circleX);
ballE.setAttributeNS(null, SVGConstants.SVG_CY_ATTRIBUTE,
""+circleY);
ballE.setAttributeNS(null, SVGConstants.SVG_R_ATTRIBUTE, ""+offset);
}
private static double getRotationAngle(AffineTransform transform) {
// Eliminate any post-translation
final AffineTransform cloned = (AffineTransform)transform.clone();
cloned.preConcatenate(AffineTransform.getTranslateInstance(
-transform.getTranslateX(), -transform.getTranslateY()));
// Apply transformation to a vector
final Point2D firstVector = new Point2D.Double(1, 0);
final Point2D secondVector = cloned.transform(firstVector, null);
// Compute dot product
final double dotProduct = firstVector.getX() * secondVector.getX() +
firstVector.getY() * secondVector.getY();
// Compute positive angle
double angle = Math.acos(dotProduct
/ (firstVector.distance(0, 0) * secondVector.distance(0, 0)));
// Negate angle if rotation direction is clockwise
if (secondVector.getY() < 0) {
angle = -angle;
}
// Done
return angle;
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new RotationTest();
}
});
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]