Batik Drag Tutorial: How to move shapes in the Canvas

The code provided is a snippet with suggestions, on how to implement a drag operation in a JSVGCanvas. It is identical as the post I submitted in the Batik Mail list. A more detailed drag tutorial is in the works, with explanations about how to handle draggable <g> elements and the transform/translate attribute.

The Post

   1 You need to implement listeners for the mouseevents:
   2 
   3 public void registerListeners() {
   4         // Gets an element from the loaded document.
   5         // document is your SVGDocument
   6         elt = document.getElementById("The_Group_ID_That_holds_the_movable_Elements");
   7         EventTarget t = (EventTarget)elt;
   8 
   9         // Adds  'mouseevent' listeners
  10         t.addEventListener("mousedown", new OnDownAction(), false);
  11         t.addEventListener("mousemove", new OnMoveAction(), false);
  12         t.addEventListener("mouseup", new OnUpAction(), false);
  13         t.addEventListener("mouseover", new OnOverAction(), false);
  14         t.addEventListener("click", new OnClickAction(), false);
  15     }
  16 
  17 
  18 Next, you need to register a global variable with the state of the DRAG operation, 
  19 and the initial drag point:
  20 
  21 protected int drag;
  22 protected Element selectedItem;
  23 protected SVGOMPoint initialDragPoint;
  24 protected final int DRAG_UP = 0;
  25 protected final int DRAG_DOWN = 0;
  26 
  27 Next, in the onmousedown event, you set the "drag" variable to  DRAG_DOWN:
  28 
  29 public class OnDownAction implements EventListener {
  30         public void handleEvent(Event evt) {
  31                 //perform select, deselect operations, etc...
  32                 // i.e. assign or validate that you have a draggable item 
  33                 // in the "selectedItem" object (And define "thisNode" element)
  34                 
  35 
  36                 //For example, "thisNode" can be:
  37                 SVGLocatable thisNode = (SVGLocatable)evt.getTarget();
  38 
  39                 //End of example. The variable thisNode has the element
  40                 // that is the draggableItem. It can be a single Element
  41                 // or a G element.  If you are interested in a G element
  42                 // you may need a method to locate the desired parent
  43                 // of your eventTarget (like parsing the ID attr.) because
  44                 // the eventTarget may only be one single element of a
  45                 // complex shape, and you want to drag the full complex shape.
  46 
  47 
  48                 drag = DRAG_DOWN;
  49 
  50                 // Set the initial drag point
  51                 DOMMouseEvent elEvt = (DOMMouseEvent)evt;
  52                     int nowToX = elEvt.getClientX();
  53                     int nowToY = elEvt.getClientY();
  54 
  55                 // Convert Screen coordinates to Document Coordinates.
  56                     SVGOMPoint pt = new SVGOMPoint(nowToX, nowToY);
  57                     SVGMatrix mat = thisNode.getScreenCTM();  // elem -> screen
  58                     mat = mat.inverse();                  // screen -> elem
  59                     initialDragPoint = (SVGOMPoint)pt.matrixTransform(mat);
  60 
  61         }
  62 }
  63 
  64 Now, on mouse up, finalize the drag operation:
  65 
  66 public class OnUpAction implements EventListener {
  67         public void handleEvent(Event evt) {
  68                         drag = DRAG_UP;
  69         }
  70 }
  71 
  72 And Finally, the core of the drag:
  73 
  74 public class OnMoveAction implements EventListener {
  75         public void handleEvent(Event evt) {
  76                 if (drag == DRAG_DOWN) {
  77                         //Cast the event onto a Batik Mouse event, 
  78                  //so we can get ccordinates
  79                         DOMMouseEvent elEvt = (DOMMouseEvent)evt;
  80                          int nowToX = elEvt.getClientX();
  81                          int nowToY = elEvt.getClientY();
  82                         //convert it to a point for use with the Matrix
  83                         SVGOMPoint pt = new SVGOMPoint(nowToX, nowToY);
  84                         //Get the items screen coordinates, and apply the transformation
  85                  // elem -> screen
  86                         SVGMatrix mat = ((SVGLocatable)evt.getTarget()).getScreenCTM();  
  87 
  88                         mat = mat.inverse();                  // screen -> elem
  89                         SVGOMPoint dragpt = (SVGOMPoint)pt.matrixTransform(mat);
  90 
  91            /* Now to actually move the objects, there are several approaches:
  92 
  93            a.) If they are individual elements (i.e. no <g>´s), you can simply modify 
  94                the element attributes X, Y. by:
  95                "element.setAttribute("x", ""+ dragpt.getX());"
  96 
  97            b.) You can iterate though all the elements in the selection (in case of 
  98                multiple selections or <g> elements) and individually change the x, y
  99                attributes of each item, as in a.)
 100 
 101            c.) You can apply a transform on your selected element. To do so you need 
 102                to perform a matrix transform from previous transforms this object 
 103                has had. For example, the first time you drag an object, you will add a
 104                transform attribute such as: transform="translate(dragpt.x, dragpt.y)", 
 105                but for subsequent drag operations you need to do, for each axis: 
 106                oldtransformCoordinate + newCordinate
 107                For a fully functional example of this approach, you can see the Adobe 
 108                SVGDraw application, found at: 
 109                http://www.adobe.com/svg/demos/svgDraw/svgDraw/index.html
 110                Although this demo is purely Javascript-Adobe SVG Viewer application, 
 111                you may learn a lot at how to handle the DOM and perform multiple 
 112                operations. Pay specific attention to the Matrix transform methods.
 113                            
 114               To analyze easily the Javascript code, i recommend the Eclipse IDE v3.0.2 
 115               with the jseditor plugin (sourceforge.net/projects/jseditor)
 116                         */
 117                 }
 118         }
 119 }

Display

To do

DragTutorial (last edited 2012-06-22 14:12:47 by drool)