2017-05-08 70 views
1

我不知道如何在選擇它們後在snap.svg中拖動多個組。當選擇兩個元素(其中兩個元素的不透明度發生變化)並使用dragGroup函數時,我想拖動這兩個元素,而不僅僅是單擊的元素。你能給我一些支持如何完成它嗎?Snap.svg拖動多個組

請參閱的jsfiddle,這說明問題 - JSFiddle

SelectMultipleGroups(); 
dragGroup(Snap.select("#extGrid1")); 
dragGroup(Snap.select("#extGrid2")); 


function SelectMultipleGroups() { 

    var paper = Snap('#svgArea') 

    // group that will receive the selected items 
    //var selections = paper.group() 
    selections = Snap.set(); 

    // DRAG FUNCTIONS 
    // when mouse goes down over background, start drawing selection box 
    var box = paper.rect(-2000, -2000, 0, 0).attr('stroke', 'black'); //obszar zaznaczania (x, y, width, height); 
    function dragstart (x, y, event) { 

    //if path or circle were clicked don't draw box 
    if(event.target.nodeName == "path" || event.target.nodeName == "circle") 
    {  
     return false; 
    } 
    box = paper.rect(x, y-32, 0, 0).attr('stroke', 'black'); 
    } 
    // when mouse moves during drag, adjust box. If to left or above original point, you have to translate the whole box and invert the dx or dy values since .rect() doesn't take negative width or height 
    function dragmove (dx, dy, x, y, event) {   
     var xoffset = 0, 
      yoffset = 0 

     if (dx < 0) { 
     xoffset = dx 
     dx = -1 * dx 
     } 

     if (dy < 0) { 
     yoffset = dy 
     dy = -1 * dy 
     } 

     box.transform('T' + xoffset + ',' + yoffset) 
     box.attr('width', dx) 
     box.attr('height', dy) 
     box.attr('fill', 'none') 
    } 
    function dragend (event) {  

     var border = box.getBBox() 
     box.remove()  

     var items = Snap.selectAll('#svgArea g'); 

     items.forEach(function (el) { 
     // here, we want to get the x,y vales of each object regardless of what sort of shape it is, but rect uses rx and ry, circle uses cx and cy, etc 
     // so we'll see if the bounding boxes intercept instead 
     var mybounds = el.getBBox() 

     // do bounding boxes overlap? 
     // is one of this object's x extremes between the selection's xextremes? 
     if (Snap.path.isBBoxIntersect(mybounds, border)) {  
      el.attr({ 
       attr: "selected", 
       opacity: 0.5,   
      }); 
     } 
     }); 
    } 
    Snap.select('#svgArea').drag(dragmove, dragstart, dragend); 
}; 


function dragGroup (element) { 

    startFnc = function (e) { 

    var matrixSplit = element.transform().localMatrix.split(); 

    ox = matrixSplit.dx 
    oy = matrixSplit.dy 

    }, // handler for drag start 
    moveFnc = function (dx, dy) { // handler for moving 

    lx = dx + ox // add the new change in x to the drag origin 
    ly = dy + oy // add the new change in y to the drag origin 

    // limit the area for drag 
    lx = insideContainer(element, lx, ly).x 
    ly = insideContainer(element, lx, ly).y 

    element.transform('translate(' + lx + ',' + ly + ')') 

    }, 
    endFnc = function() { // handler for drag end 
    ox = 0 
    oy = 0 
    } 
    element.drag(moveFnc, startFnc, endFnc); 
}; 

// limit the area for drag 
function insideContainer (element, lx, ly) { 

    var thisGroup = element.getBBox(); 


    if (lx < 0) { 
    lx = 0 
    } 
    if (ly < 0) { 
    ly = 0 
    } 
    if (lx > ($("#svgArea").width() - thisGroup.width)) { 
    lx = ($("#svgArea").width() - thisGroup.width) 
    } 
    if (ly > ($("#svgArea").height() - thisGroup.height)) { 
    ly = ($("#svgArea").height() - thisGroup.height) 
    } 

    return { 
    x: lx, 
    y: ly 
    } 
} 
+0

最好的辦法,是把兩個組的另一組裏面,只需拖動,我認爲。這有可能嗎?否則,將這兩個組放在一個集合中,並迭代它,存儲它們的原始位置並根據dx/dy更新每個元素的位置。 – Ian

回答

0

最簡單的方法,是把兩個另一組內的組元素。這樣,您只需將處理程序放在父組元素上,當您拖動它時,內部的所有內容都隨之移動。

dragGroup(Snap.select("#parentGroup")); 

jsfiddle example

如果由於某種原因,你不能做到這一點,你將不得不遍歷每個組的那些元素和改造他們,存儲在開始拖動前位置的每個組。因此,它可能是這個樣子......

startFnc = function (e) { 

    selections.forEach(function(el) { 
     var matrixSplit = el.transform().localMatrix.split(); 

     el.data('ox',matrixSplit.dx) 
     el.data('oy',matrixSplit.dy) 
    }); 

    }, // handler for drag start 
    moveFnc = function (dx, dy) { // handler for moving 

    selections.forEach(function(el) { 

     lx = dx + el.data('ox') // add the new change in x to the drag origin 
     ly = dy + el.data('oy') // add the new change in y to the drag origin 

     // limit the area for drag 
     lx = insideContainer(el, lx, ly).x 
     ly = insideContainer(el, lx, ly).y 

     el.transform('translate(' + lx + ',' + ly + ')') 
    }); 
} 

jsfiddle