svg中实现元素拖动

svg中实现元素拖动

<svg style="background-color: bisque" width="500px" height="500px" 
    οnmοusemοve="mousemove(event)"
    οnmοuseup="mouseup(event)">
    <rect id="firstRect" height="40px" width="100px" x="10" y="10" rx="10px" ry="10px" fill="white" stroke="black"
          οnmοusedοwn="mousedown(event)"></rect>
</svg>
var originX = 0; // 鼠标初始位置
var originY = 0;

var domX = 0; // dom初始元素
var domY = 0;

var dom; // 初始元素

var isMouseDown = false;
window.onload = function () {
    dom = document.getElementById("firstRect");
}
    function mousedown(e) {
        // 鼠标初始位置
        originX = e.clientX; // 初始位置
        originY = e.clientY;

        // 元素初始位置
        domX = dom.getAttribute("x");
        domY = dom.getAttribute("y");

        domX.replace("px", "");
        domY.replace("px", "");

        domX = parseInt(domX);
        domY = parseInt(domY);

        isMouseDown = true;
    }
    function mousemove(e) {
        if (isMouseDown) {
            // 元素位置
            var distanceX = e.clientX - originX;
            var distanceY = e.clientY - originY;

            var curX = domX + distanceX;
            var curY = domY + distanceY;

            dom.setAttribute("x", curX);
            dom.setAttribute("y", curY);
        }
    }
function mouseup(e) {
    isMouseDown = false; // 取消按钮
}



借助svg,我们可以画出多种多样的图形,而且利用g标签,还可以把多个标签组合在一起,让他们具有相同的行为。
语法也比较简洁,希望还么有接触过的同学,学习一下。 
要实现拖动功能(大神绕行…),我们需要给元素定义mousedown(响应鼠标在元素范围按住),mousemove(移动),mouseup(松开鼠标),先定义一个rect标签(有机会补图)。

<rect width="100" height="100" 
fill='#f00' stroke='#d7a7bd' stroke-width='3' 
stroke-linecap="round" 
stroke-dasharray='5,10,5' x='20' y='20' 
οnmοusedοwn="selectElement(event)"/>

然后现在我们添加代码来处理选中的元素

var currentX = 0;
var currentY = 0;
var currentMatrix = 0;

function selectElement(evt) {
   selectedElement = 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)");
}

现在当我们鼠标按在了元素上(这里是rect),我们需要记录现在是哪一个元素被选中了,并且我们需要知道当前这个元素的transform的值。然后记录鼠标的x,y坐标,这样当我们移动的时候,就可以知道移动了多少,最后,我们给这个元素添加了一个moveElement方法和DeselectElement分别响应鼠标的移动和弹起(松开手指)、移出(超出范围后响应) 
下面是拖动的方法

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;
 }

就是找到当前鼠标的新位置,并且计算出这个位置和前一个记录位置的偏移量,然后把这个值记录在元素的transform数组(从0开始计算)的第四个和第五个值,然后我们更新一下currentX和currentY,这样当我们再次移动的时候,对比的x,y才是正确的。 
最后,我们需要完善当鼠标移出或弹起的时候的事件,也就是鼠标跑的太快了,超出当前元素的范围的时候,我们就不要再记录位置,或者当用户的鼠标弹起了,也不能让元素再跟着鼠标跑了,下面是代码。

function deselectElement(evt) {
      if(selectedElement != 0){
        selectedElement.removeAttributeNS(null, "onmousemove");
        selectedElement.removeAttributeNS(null, "onmouseout");
        selectedElement.removeAttributeNS(null, "onmouseup");
        selectedElement = 0;
      }
    }

原文链接:https://blog.csdn.net/qingwazange/article/details/76039318

发布了16 篇原创文章 · 获赞 213 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/cxu123321/article/details/104069247
今日推荐