2017-05-08 5 views
1

Ich weiß nicht, wie Sie mehrere Gruppen in snap.svg ziehen, nachdem Sie sie ausgewählt haben. Wenn zwei Elemente ausgewählt werden (die Deckkraft wird für zwei von ihnen geändert) und ich die dragGroup-Funktion verwende, möchte ich beide Elemente ziehen, nicht nur das Element, auf das geklickt wurde. Kannst du mir bitte etwas Unterstützung geben, wie ich es erreichen kann?Snap.svg ziehen mehrere Gruppen

Bitte beachten Sie die JSFiddle, das das Problem zeigt - 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

Der beste Weg wäre in einer anderen Gruppe beide Gruppen zu setzen, und ziehen Sie einfach, dass ich denke. Ist das eine Möglichkeit? Andernfalls setzen Sie beide Gruppen in eine Menge und iterieren darüber, wobei Sie ihre ursprüngliche Position speichern und jede Elementposition in Abhängigkeit von dx/dy aktualisieren. – Ian

Antwort

0

Der einfachste Weg, sowohl die Elemente der Gruppe in einer anderen Gruppe zu setzen wäre. Auf diese Weise legen Sie den Handler einfach auf das übergeordnete Gruppenelement, und wenn Sie es ziehen, bewegt sich alles darin.

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

jsfiddle example

aus irgendeinem Grund Wenn Sie dies nicht tun, würden Sie sie jede dieser Gruppenelemente und Transformation durchlaufen müssen, die jeweils Gruppen zu speichern, bevor die Drag Ausgangsposition. So könnte es etwa so aussehen ...

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