[英]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.