svg中實現元素拖動
阿新 • • 發佈:2019-01-25
這段時間比較忙,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;
}
}
程式碼量不多,相信大家很容易就看懂了,有說的不對了,歡迎批評指正。