繁体   English   中英

Snap SVG:拖动组不会更新元素

[英]Snap SVG: Dragging group doesn't update elements

JSFiddle在这里: JSFiddle

拖动一组对象时,单个对象的位置属性似乎没有更新。 无论使用默认的drag()处理程序还是定义自己的处理程序,都会发生这种情况。 甚至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);

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

有人可以帮忙吗?

JSFiddle在这里: JSFiddle

我认为这是因为它们是两种不同的事物,因此它们实际上并不是可互换的。

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

getBBox将在其当前的转换空间中工作,请注意,这可能与客户端不同(例如,如果svg被放大/缩小)。 因此,它们是两种略有不同的方法,它们执行不同的操作。

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

代码也使用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();
            }
        }

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

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

...因此,确实可以使用group.getBBox()方法。 然而:

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

再往下,在earier提到的相同信息[“获取与snap.svg阻力SVG组坐标” 1推荐getBoundingClientRect(),这也工作正常足够快! 我的新的,正在工作的Fiddle展示了所有这些方法,位于: New JSFiddle

因此,未来的用户:请使用.node.getBoundingClientRect()。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM