1. 程式人生 > >svg中實現元素拖動

svg中實現元素拖動

這段時間比較忙,php的設計模式想寫工廠模式,但是比較難寫,不是一時半會兒能寫完的,先把現在正在使用的關於svg中元素的拖動,記錄一下。
藉助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' onmousedown="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;
      }
    }

程式碼量不多,相信大家很容易就看懂了,有說的不對了,歡迎批評指正。