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);
如果我只定义一个对象(例如,一个矩形)并将其从组中删除,并通过我自己的"移动"函数用于拖动调用,并包括设置" x"和" y"显式属性,然后工作。但是,如果我将矩阵包含在一个组中,那么...我无法弄清楚如何做到这一点,并且我已经尝试了一些方法(请参阅多个注释掉的行显示我和#39 ;尝试过)。我需要知道rect子组元素在拖动后最终的位置,或者至少是整个组的BBox。这些似乎都没有得到更新 - 即我放入的控制台日志永远显示相同的数字,无论我在哪里移动对象。
有人可以帮忙吗?
JSFiddle:JSFiddle
答案 0 :(得分:1)
我认为这是因为它们是两个不同的东西,所以它们实际上并不是可以互换的。
拖动处理程序使用转换。转换不会影响任何其他属性,它只是元素的一个属性(在本例中是组元素)。
getBBox将在其当前变换空间中工作,请注意这可能与客户端不同(例如,如果svg被放大/缩小)。所以它们是两种略有不同的方法,它们可以做不同的事情。
如果需要相对于客户端窗口的边界框,请使用getBoundingClientRect。如果在元素当前坐标空间中需要边界框,请使用getBBox。
答案 1 :(得分:1)
代码也使用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();
}
}
答案 2 :(得分:0)
为了发布这个问题,我创建了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(),这也很好 AND 足够快!我的新工作小提琴显示了所有这些方法:New JSFiddle。
所以,未来的用户:使用.node.getBoundingClientRect()。