将SVG元素拖动到另一个SVG元素上

时间:2015-03-23 14:31:36

标签: javascript svg

有什么方法可以将SVG元素拖到另一个SVG元素上?我试过但是在this教程中我只能拖动第二个放在第一个上面的那个。我没办法在没有问题的情况下在第二个上拖第一个。 有谁知道如何解决这个问题?

以下是整个教程:http://www.petercollingridge.co.uk/book/export/html/437

2 个答案:

答案 0 :(得分:3)

在我看到@ Strat-O给你同样的方法之前,我正在写它。

所以这是一个评论的例子:

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="400" height="200">
    
    <style>
      .draggable {
        cursor: move;
      }
    </style>
    
    <script type="text/ecmascript"><![CDATA[
    var selectedElement = 0;
    var currentX = 0;
    var currentY = 0;
    var currentMatrix = 0;

	function cloneToTop(oldEl){
	  // already at top, don't go farther…
	  if(oldEl.atTop==true) return oldEl;
	  // make a copy of this node
	  var el = oldEl.cloneNode(true);
 	  // select all draggable elements, none of them are at top anymore
	  var dragEls= oldEl.ownerDocument.documentElement.querySelectorAll('.draggable');
	  for(i=0; i<dragEls.length; i++){
	  	dragEls[i].atTop=null;
	  	}
	  var parent = oldEl.parentNode;
	  // remove the original node
	  parent.removeChild(oldEl);
	  // insert our new node at top (last element drawn is first visible in svg)
  	  parent.appendChild(el);
  	  // Tell the world that our new element is at Top
	  el.atTop= true;
	  return el;
	  }


    function selectElement(evt) {
      selectedElement = cloneToTop(evt.target);
      currentX = evt.clientX;
      currentY = evt.clientY;
      currentMatrix = selectedElement.getAttributeNS(null, "transform").slice(7,-1).split(' ');
    
      for(var i=0; i<currentMatrix.length; i++) {
        currentMatrix[i] = parseFloat(currentMatrix[i]);
      }
      
      selectedElement.setAttributeNS(null, "onmousemove", "moveElement(evt)");
      selectedElement.setAttributeNS(null, "onmouseout", "deselectElement(evt)");
      selectedElement.setAttributeNS(null, "onmouseup", "deselectElement(evt)");
    }
        
    function moveElement(evt) {
      var dx = evt.clientX - currentX;
      var dy = evt.clientY - currentY;
      currentMatrix[4] += dx;
      currentMatrix[5] += dy;
      
      selectedElement.setAttributeNS(null, "transform", "matrix(" + currentMatrix.join(' ') + ")");
      currentX = evt.clientX;
      currentY = evt.clientY;
    }
        
    function deselectElement(evt) {
      if(selectedElement != 0){
          selectedElement.removeAttributeNS(null, "onmousemove");
          selectedElement.removeAttributeNS(null, "onmouseout");
          selectedElement.removeAttributeNS(null, "onmouseup");
          selectedElement = 0;
          }
        }
        
    ]]> </script>
    <g>
    <circle/>
    </g>

    <rect x="0.5" y="0.5" width="399" height="199" fill="none" stroke="black"/>
    
    <rect class="draggable" id="blue" x="30" y="30" width="80" height="80" fill="blue" transform="matrix(1 0 0 1 46 18)" onmousedown="selectElement(evt)"/>
          
    <rect class="draggable" id="green" x="160" y="50" width="50" height="50" fill="green" transform="matrix(1 0 0 1 51 11)" onmousedown="selectElement(evt)"/>

</svg>

答案 1 :(得分:1)

不幸的是,只有一种方法可以让元素出现在SVG中的另一个元素的前面,那就是删除下面的元素,然后转过来重新绘制它。您可以设置z-index或其他有用的属性。我花了一点时间在这上面,这是我的结论。

有一个优点,即通过删除和重绘它,它确保维护所有元素的显示顺序,而如果你必须维护z索引,管理数字可能会导致它自己的一组问题。