Raphael JS中拖动矩形来回弹跳
Dragging a rectangle in Raphael JS bounces back and forth
在这个 jsFiddle 中,我有一个带有矩形的 Raphael JS 网格,我需要将其移动到网格。矩形的每个角都有四个红色手柄,当它移动时手柄也会移动。
到目前为止,我可以四处移动矩形(效果很好),但是当我尝试将其向左移动时,矩形会闪烁并来回弹跳。问题可能是我在拖动 move
函数中设置了 x
矩形坐标吗?任何想法将不胜感激。
var move = function(dx, dy) {
rect.attr("x", ox + dx);
rect.attr("y", oy + dy);
leftTop.attr("x", ox1 + dx);
leftTop.attr("y", oy1 + dy);
rightTop.attr("x", ox2 + dx);
rightTop.attr("y", oy2 + dy);
leftBottom.attr("x", ox3 + dx);
leftBottom.attr("y", oy3 + dy);
rightBottom.attr("x", ox4 + dx);
rightBottom.attr("y", oy4 + dy);
if ((dx - lastdx) < 0)
seeMoveLeft(rect, leftTop, rightTop,
leftBottom, rightBottom);
lastdx = dx;
};
var up = function() {};
rect.drag(move, start, up);
var seeMoveLeft = function (rect, leftTop, rightTop,
leftBottom, rightBottom){
var left = rect.attr('x');
// find next left grid
var found = false;
var min = left - 40;
for (var i=left; i>=min; i--){
if (i % 40 == 0) {
found = true;
break;
}
}
if (found) {
var diff = left - i;
rect.attr('x', i);
var lt = leftTop.attr('x');
leftTop.attr('x', lt - diff);
var rt = rightTop.attr('x');
rightTop.attr('x', rt - diff);
var lb = leftBottom.attr('x');
leftBottom.attr('x', lb - diff);
var rb = rightBottom.attr('x');
rightBottom.attr('x', rb - diff);
}
}
问题是你在这里设置了 rect 的新 x:
rect.attr("x", ox + dx);
那你在这里修改一下:
if ((dx - lastdx) < 0)
seeMoveLeft(rect, leftTop, rightTop,
leftBottom, rightBottom);
但是由于移动函数是基于 mousemove 事件的,所以有时候,你会在一个过程中得到相同的 dx 值 2 次排。这对于 mousemove 事件是正常的,尤其是当你移动缓慢时。您可以在下面尝试,每次 clientX 保持不变时,window 将变为绿色。
var lastClientX;
window.addEventListener('mousemove', (e) => {
if (lastClientX && e.clientX === lastClientX) {
document.body.style.backgroundColor = 'green';
} else {
document.body.style.backgroundColor = 'yellow';
}
lastClientX = e.clientX;
})
body {
width: 100%;
height 100%;
}
当你有 2 个连续相同的 dx 时,你的情况会发生什么,x - lastdx
不会验证,因此位置不会调整,会保持不变在 rect.attr("x", ox + dx);
。所以第一次移动事件,位置调整到seeMoveLeft的网格,然后位置改变但不调整,因为dx不小比 lastdx 相等。因此你看到了闪烁。
最简单的纠正方法,如果 dx 与 lastdx 相同,则跳过定位。像这样:
if(lastdx !== dx){
rect.attr("x", ox + dx);
leftTop.attr("x", ox1 + dx);
rightTop.attr("x", ox2 + dx);
leftBottom.attr("x", ox3 + dx);
rightBottom.attr("x", ox4 + dx);
}
在这个 jsFiddle 中,我有一个带有矩形的 Raphael JS 网格,我需要将其移动到网格。矩形的每个角都有四个红色手柄,当它移动时手柄也会移动。
到目前为止,我可以四处移动矩形(效果很好),但是当我尝试将其向左移动时,矩形会闪烁并来回弹跳。问题可能是我在拖动 move
函数中设置了 x
矩形坐标吗?任何想法将不胜感激。
var move = function(dx, dy) {
rect.attr("x", ox + dx);
rect.attr("y", oy + dy);
leftTop.attr("x", ox1 + dx);
leftTop.attr("y", oy1 + dy);
rightTop.attr("x", ox2 + dx);
rightTop.attr("y", oy2 + dy);
leftBottom.attr("x", ox3 + dx);
leftBottom.attr("y", oy3 + dy);
rightBottom.attr("x", ox4 + dx);
rightBottom.attr("y", oy4 + dy);
if ((dx - lastdx) < 0)
seeMoveLeft(rect, leftTop, rightTop,
leftBottom, rightBottom);
lastdx = dx;
};
var up = function() {};
rect.drag(move, start, up);
var seeMoveLeft = function (rect, leftTop, rightTop,
leftBottom, rightBottom){
var left = rect.attr('x');
// find next left grid
var found = false;
var min = left - 40;
for (var i=left; i>=min; i--){
if (i % 40 == 0) {
found = true;
break;
}
}
if (found) {
var diff = left - i;
rect.attr('x', i);
var lt = leftTop.attr('x');
leftTop.attr('x', lt - diff);
var rt = rightTop.attr('x');
rightTop.attr('x', rt - diff);
var lb = leftBottom.attr('x');
leftBottom.attr('x', lb - diff);
var rb = rightBottom.attr('x');
rightBottom.attr('x', rb - diff);
}
}
问题是你在这里设置了 rect 的新 x:
rect.attr("x", ox + dx);
那你在这里修改一下:
if ((dx - lastdx) < 0)
seeMoveLeft(rect, leftTop, rightTop,
leftBottom, rightBottom);
但是由于移动函数是基于 mousemove 事件的,所以有时候,你会在一个过程中得到相同的 dx 值 2 次排。这对于 mousemove 事件是正常的,尤其是当你移动缓慢时。您可以在下面尝试,每次 clientX 保持不变时,window 将变为绿色。
var lastClientX;
window.addEventListener('mousemove', (e) => {
if (lastClientX && e.clientX === lastClientX) {
document.body.style.backgroundColor = 'green';
} else {
document.body.style.backgroundColor = 'yellow';
}
lastClientX = e.clientX;
})
body {
width: 100%;
height 100%;
}
当你有 2 个连续相同的 dx 时,你的情况会发生什么,x - lastdx
不会验证,因此位置不会调整,会保持不变在 rect.attr("x", ox + dx);
。所以第一次移动事件,位置调整到seeMoveLeft的网格,然后位置改变但不调整,因为dx不小比 lastdx 相等。因此你看到了闪烁。
最简单的纠正方法,如果 dx 与 lastdx 相同,则跳过定位。像这样:
if(lastdx !== dx){
rect.attr("x", ox + dx);
leftTop.attr("x", ox1 + dx);
rightTop.attr("x", ox2 + dx);
leftBottom.attr("x", ox3 + dx);
rightBottom.attr("x", ox4 + dx);
}