【问题标题】:Snap SVG: Dragging group doesn't update elementsSnap SVG:拖动组不会更新元素
【发布时间】:2015-01-13 19:52:48
【问题描述】:

这里的JSFiddle:JSFiddle

拖动一组对象时,单个对象的位置属性似乎没有得到更新。无论我使用默认的 drag() 处理程序还是定义自己的处理程序,都会发生这种情况。甚至 group BBox 操作似乎也没有更新。代码:

var s = Snap("#svg");

var move = function (dx, dy, posx, posy) {
    this.attr({
        x: posx,
        y: posy
    });
    //this.transform("t" + dx + "," + dy);
};
var block = s.rect(100, 100, 100, 100);
var circle = s.circle(100, 100, 50);
var group = s.g(block, circle);

//group.drag(move, function () {}, function () {});
group.drag();
//block.drag(move, function () {}, function () {});

//just a way to keep info coming w/o an interminable script
document.addEventListener('mousemove', function (e) {
    bbox = block.getBBox();
    block_x = block.attr("x");
    block_y = block.attr("y");
    gbbox = group.getBBox();
    console.log("block is at " + block_x + "," + block_y,
        "   Block Bbbox is at " + bbox.x + "," + bbox.y,
        "   Group Bbbox is at " + gbbox.x + "," + gbbox.y);


}, false);

如果我只定义一个对象(例如,一个矩形)并将其排除在组之外,并将我自己的“移动”函数传递给拖动调用,并包括显式设置“x”和“y”属性,然后就可以了。但是,如果我将 rect 包含在一个组中,那么...我不知道该怎么做,并且我尝试了几种方法(请参阅显示我尝试过的内容的多个注释掉的行)。我需要知道 rect 子组元素在拖动后结束的位置,或者至少是整个组的 BBox。这些似乎都没有得到更新——即我输入的控制台日志永远显示相同的数字,无论我将对象移动到哪里。

谁能帮忙?

这里的JSFiddle:JSFiddle

【问题讨论】:

    标签: javascript snap.svg


    【解决方案1】:

    为了发布这个问题,我创建了 JSFiddle,但忽略了关键的 snap.svg 定义......

    <script src="http://snapsvg.io/assets/js/snap.svg-min.js"></script>
    

    ...这样,group.getBBox() 方法确实有效。然而:

    显然,使用 getBBox() 非常慢 - 比像我在对对象分组之前那样访问“x”属性要慢得多。我所知道的是,如果我使用 getBBox()(我在屏幕上有很多对象),我的代码会变慢。

    在前面提到的同一篇文章中进一步提到[“使用 snap.svg 获取 svg 组的坐标”1 推荐 getBoundingClientRect(),它也可以正常工作并且足够快!我的新 Fiddle 展示了所有这些方法在这里:New JSFiddle

    所以,未来的用户:使用 .node.getBoundingClientRect()。

    【讨论】:

      【解决方案2】:

      我认为这是因为它们是两个不同的东西,所以它们实际上不能互换。

      拖动处理程序使用变换。转换不会影响任何其他属性,它只是元素上的一个属性(在本例中为 group 元素)。

      getBBox 将在其当前的变换空间中工作,注意这可能与客户端不同(例如,如果 svg 被放大/缩小)。所以它们是两种略有不同的方法,做不同的事情。

      如果您需要相对于客户端窗口的边界框,请使用 getBoundingClientRect。如果您需要元素当前坐标空间中的边界框,请使用 getBBox。

      【讨论】:

      • 嗨 Ian,我有几个元素的组,组拖动完成后我需要特定元素的 bBox。但是,正如您所说,拖动变换仅适用于被拖动的元素(组),组内部元素的 bBox 与拖动组之前相同您知道我可以尝试获得正确的 bBox 吗?谢谢
      • 不看代码很难知道,看看svg.dabbles.info/snaptut-graffle-transform插件中的top函数是否有帮助。
      • 嗨伊恩,来自链接的方法做了某种转换,但它不正确。根据当前的缩放比例,它会在 xaxis、yaxis 上产生不同的偏移量。我在页面底部添加了代码 sn-p。谢谢
      【解决方案3】:

      代码也使用 snap.svg.zpd,因此可以进行缩放。问题出在 onStopMove 函数上。当组移动时触发事件。在组中是一个圆圈(this.select('#main-inner-circle')),它在组内没有预定义的位置。我试图在移动组后获得该内圈的正确 cx 和 cy。

      self.onMove = function (dx, dy, ev, x, y) {
                  var clientX, clientY;
                  var tdx, tdy;
                  if ((typeof dx == 'object') && (dx.type == 'touchmove')) {
                      clientX = dx.changedTouches[0].clientX;
                      clientY = dx.changedTouches[0].clientY;
                      dx = clientX - this.data('ox');
                      dy = clientY - this.data('oy');
                  }
      
                  var snapInvMatrix = this.transform().diffMatrix.invert();
                  snapInvMatrix.e = snapInvMatrix.f = 0;
                  tdx = snapInvMatrix.x(dx, dy);
                  tdy = snapInvMatrix.y(dx, dy);            
      
                  this.transform("t" + [tdx, tdy] + this.data('ot'));
              }
      
              self.onStartMove = function (x, y, ev) {
                  if ((typeof x == 'object') && (x.type == 'touchstart')) {
                      x.preventDefault();
                      this.data('ox', x.changedTouches[0].clientX);
                      this.data('oy', x.changedTouches[0].clientY);
                  }
      
                  this.data('ot', this.transform().local);
                  if (callbacks.onStartMove) {
                      callbacks.onStartMove();
                  }
              }
      
              self.onStopMove = function () {
                  var self = this.select('#main-inner-circle');
                  this.data('ot', this.transform().local);
                  //self.data('ot', self.transform().local);
                  console.log(self.getTransformedBBox());
                  console.log(this.getBBox());
                  //console.log($(self.node).offset().left - $(self.node).parent().offset().left);
                  var bBox = this.getBBox();
                  //var x = bBox.x + $(self.node).offset().left - $(self.node).parent().offset().left + self.getBBox().width / 2;
                  //var y = bBox.y + $(self.node).offset().top - $(self.node).parent().offset().top + self.getBBox().height / 2;
                  model.updateElementCoordinates(index, $(this.node).attr("rel"), { x: self.getTransformedBBox().cx, y: self.getTransformedBBox().cy });
      
                  if (callbacks.onStopMove) {
                      callbacks.onStopMove();
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 2015-04-23
        • 2014-02-19
        • 2017-02-10
        • 2014-03-22
        • 1970-01-01
        • 2016-11-28
        • 1970-01-01
        • 1970-01-01
        • 2012-04-18
        相关资源
        最近更新 更多