【问题标题】:Snap.svg drag multiple groupsSnap.svg 拖动多个组
【发布时间】:2017-10-06 03:16:46
【问题描述】:

我不知道选择后如何在 snap.svg 中拖动多个组。 When two elements are selected (opacity is changed for two of them) and I use the dragGroup function I would like to drag both elements, not only the one which was clicked.你能给我一些支持如何完成它吗?

请查看显示问题的 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
  }
}

【问题讨论】:

  • 最好的方法是将两个组放在另一个组中,然后简单地拖动我认为。有这种可能吗?否则,将两个组放在一个集合中,并对其进行迭代,存储它们的原始位置并根据 dx/dy 更新每个元素的位置。

标签: javascript jquery svg snap.svg


【解决方案1】:

最简单的方法是将两个组元素放在另一个组中。这样你只需将处理程序放在父组元素上,当你拖动它时,里面的所有东西都会随之移动。

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

【讨论】:

    猜你喜欢
    • 2014-07-09
    • 2015-01-20
    • 2015-10-07
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 2016-04-10
    相关资源
    最近更新 更多