2010-12-22 55 views
4

大家好,我正在研究SVG,我面临的问题是我想在我的应用程序中实现对齐网格功能,我已经在SVG中使用了网格,我也有在其中实现了拖放功能。现在我想实现对齐网格功能。任何帮助将是真棒,应该非常心存感激,SVG的文件名是(DndD.svg)与该名称保存 问候: Zain公司使用Javascript对齐网格功能

下面是代码

<html> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <title>JSP Page</title> 
    </head> 
    <body> 
     <object data="DndD.svg" id="oo" style="width: 800px" height="500px"> 

     </object> 
     <span id="trail" style="visibility: hidden"></span> 
    </body> 
<script type="text/javascript"> 

      var far=document.getElementById("oo") 
      far.addEventListener("load", function(){ 
      var svgDoc=far.contentDocument; 
      var svgRoot=svgDoc.documentElement; 
      var r=svgDoc.getElementById("rectangle") 
      r.onmousemove=function(evt){ 
      var x=evt.pageX 
      var y=evt.pageY 
      document.getElementById('trail').style.visibility="visible"; 
      document.getElementById('trail').style.position="absolute"; 
      document.getElementById('trail').style.left=evt.clientX+10; 
      document.getElementById('trail').style.top=evt.clientY; 
      document.getElementById("trail").innerHTML=x+","+y 
      } 
      var line2; 
      var count=0 
      var xx=0 
      var yy=0 
      line2="line_id"+count 
      for(var i=0;i<=48;i++){ 
       xx=xx+10 
       var line=svgDoc.createElementNS("http://www.w3.org/2000/svg", "line") 
       line.setAttribute("id", line2) 
       line.setAttribute("x1", xx) 
       line.setAttribute("y1", "0") 
       line.setAttribute("x2", xx) 
       line.setAttribute("y2", "400") 
       line.setAttribute("stroke", "red") 
       line.setAttribute("stroke-width", "1") 
       line.setAttribute("pointer-events", "none") 
       svgRoot.appendChild(line) 

      } 

      for(var i=0;i<=39;i++){ 
       yy=yy+10 
       var line=svgDoc.createElementNS("http://www.w3.org/2000/svg", "line") 
       line.setAttribute("id", line2) 
       line.setAttribute("x1", "0") 
       line.setAttribute("y1", yy) 
       line.setAttribute("x2", "500") 
       line.setAttribute("y2", yy) 
       line.setAttribute("stroke", "red") 
       line.setAttribute("stroke-width", "1") 
       line.setAttribute("pointer-events", "none") 
       svgRoot.appendChild(line) 

      } 

       var rec = svgDoc.createElementNS("http://www.w3.org/2000/svg", "rect"); 
       rec.setAttribute("id", "btn_rect"); 
       rec.setAttribute("fill","orange") 
       rec.setAttribute("stroke","black") 
       rec.setAttribute("x","100px") 
       rec.setAttribute("y","100px") 
       rec.setAttribute("width","45px") 
       rec.setAttribute("height","45px") 
       rec.setAttribute("rx","3px") 
       rec.setAttribute("ry","3px") 
       svgRoot.appendChild(rec); 

    },false) 
    </script> 
    </html> 

SVG CODE other file 

<?xml version="1.0" standalone="no"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg version="1.1" 
id="Layer_1" 
xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink" 
onload="Init(evt)" 
onmousedown="Grab(evt)" 
onmousemove="Drag(evt)" 
onmouseup="Drop(evt)" 
> 

<rect x="0" y="0" width="500px" height="400px" fill="black" stroke="black" id="rectangle" pointer-events="none"/> 
<script> 
     <![CDATA[ 


     var SVGDocument = null; 
     var SVGRoot = null; 
     SVG_lay=new Array(); 
     var TrueCoords = null; 
     var GrabPoint = null; 
     var BackDrop2 = null; 
     var DragTarget = null; 

        function Init(evt) 
        { 
        SVGDocument = evt.target.ownerDocument; 
        SVGRoot = SVGDocument.documentElement; 

        // these svg points hold x and y values... 
        // very handy, but they do not display on the screen (just so you know) 
        TrueCoords = SVGRoot.createSVGPoint(); 
        GrabPoint = SVGRoot.createSVGPoint(); 

        // this will serve as the canvas over which items are dragged. 
        // having the drag events occur on the mousemove over a backdrop 
        // (instead of the dragged element) prevents the dragged element 
        // from being inadvertantly dropped when the mouse is moved rapidly 
        BackDrop2 = SVGDocument.getElementById('BackDrop1'); 
        } 

          function Grab(evt) 
          { 
          // find out which element we moused down on 
          var targetElement = evt.target; 
           //SVG_lay.push(targetElement); 
          // you cannot drag the background itself, so ignore any attempts to mouse down on it 
          if (BackDrop2 != targetElement) 
          { 
          //set the item moused down on as the element to be dragged 
          DragTarget = targetElement; 

          // move this element to the "top" of the display, so it is (almost) 
          // always over other elements (exception: in this case, elements that are 
          // "in the folder" (children of the folder group) with only maintain 
          // hierarchy within that group 
          DragTarget.parentNode.appendChild(DragTarget); 

          // turn off all pointer events to the dragged element, this does 2 things: 
          // 1) allows us to drag text elements without selecting the text 
          // 2) allows us to find out where the dragged element is dropped (see Drop) 
          DragTarget.setAttributeNS(null, 'pointer-events', 'none'); 

          // we need to find the current position and translation of the grabbed element, 
          // so that we only apply the differential between the current location 
          // and the new location 
          var transMatrix = DragTarget.getCTM(); 
          GrabPoint.x = TrueCoords.x - Number(transMatrix.e); 
          GrabPoint.y = TrueCoords.y - Number(transMatrix.f); 

          } 
          }; 


           function Drag(evt) 
           { 
           // account for zooming and panning 
           GetTrueCoords(evt); 

           // if we don't currently have an element in tow, don't do anything 
           if (DragTarget) 
           { 
           // account for the offset between the element's origin and the 
           // exact place we grabbed it... this way, the drag will look more natural 
           var newX = TrueCoords.x - GrabPoint.x; 
           var newY = TrueCoords.y - GrabPoint.y; 


           // apply a new tranform translation to the dragged element, to display 
           // it in its new location 
           DragTarget.setAttributeNS(null, 'transform', 'translate(' + newX + ',' + newY + ')'); 
           } 
           }; 


            function Drop(evt) 
            { 
            // if we aren't currently dragging an element, don't do anything 
            if (DragTarget) 
            { 
            // since the element currently being dragged has its pointer-events turned off, 
            // we are afforded the opportunity to find out the element it's being dropped on 
            var targetElement = evt.target; 

            // turn the pointer-events back on, so we can grab this item later 
            DragTarget.setAttributeNS(null, 'pointer-events', 'all'); 
            if ('BackDrop1' == targetElement.parentNode.id) 
            { 
            // if the dragged element is dropped on an element that is a child 
            // of the folder group, it is inserted as a child of that group 
            targetElement.parentNode.appendChild(DragTarget); 
            alert(DragTarget.id + ' has been dropped into a folder, and has been inserted as a child of the containing group.'); 
            } 


            else { 
            // for this example, you cannot drag an item out of the folder once it's in there; 
            // however, you could just as easily do so here 
            // alert(DragTarget.id + ' has been dropped on top of ' + targetElement.id); 

             if('bin' == targetElement.id) 
             { 
             //targetElement.parentNode.appendChild(DragTarget); 

             var ch=SVGDocument.getElementById(DragTarget.id); 
             var pa=ch.parentNode; 
             pa.removeChild(ch); 
             } 
            } 

            // set the global variable to null, so nothing will be dragged until we 
            // grab the next element 
            DragTarget = null; 
            } 
            }; 


             function GetTrueCoords(evt) 
             { 
             // find the current zoom level and pan setting, and adjust the reported 
             // mouse position accordingly 
             var newScale = SVGRoot.currentScale; 
             var translation = SVGRoot.currentTranslate; 
             TrueCoords.x = (evt.clientX - translation.x)/newScale; 
             TrueCoords.y = (evt.clientY - translation.y)/newScale; 
             }; 
       ]]></script> 

</svg> 

回答

7

好吧,我已经写了一个捕捉功能:

function snap(value, gridSize, roundFunction) { 
    if (roundFunction === undefined) roundFunction = Math.round; 
    return gridSize * roundFunction(value/gridSize); 
} 

alert(snap(14, 10)); 
alert(snap(16, 10)); 

也许它会帮助你。它会做什么? snap(14,10)会将'14'对齐到长度为10的网格。最接近的网格是10(14 - 10 = 4,20 - 14 = 6)。但是'16'会对齐到'20'。

Regards, Kevin

+0

你摇滚的人!很酷。检查svg-edit,它已经捕捉到网格功能。也许你可以通过编写snap功能2.0获得一些灵感 – 2013-12-07 21:29:10