2017-05-08 116 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