【问题标题】:Dragging SVG element over another SVG element将 SVG 元素拖到另一个 SVG 元素上
【发布时间】:2015-03-23 23:56:22
【问题描述】:

有什么方法可以将一个 SVG 元素拖到另一个 SVG 元素上?我尝试过,但就像在this 教程中一样,我只能将我放置的第二个拖到第一个上。我不可能毫无问题地将第一个拖到第二个上。 有谁知道如何解决这个问题?

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

【问题讨论】:

  • 在同一个父 Div 中创建两个 SVG。设置溢出:可见;
  • 只需将pointer-events: none; 设置为除拖动时可拖动的所有对象吗?
  • 你是个天才,Ximik

标签: javascript svg


【解决方案1】:

在我看到@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>

【讨论】:

    【解决方案2】:

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

    有一个好处,那就是通过删除和重绘它,它可以确保所有元素的显示顺序得到维护,而如果您必须维护 z-indexes,管理数字可能会导致其自身的一系列问题。

    【讨论】:

      猜你喜欢
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 2014-01-04
      相关资源
      最近更新 更多