Это мой первый вопрос, связанный с переполнением стека, поэтому не стесняйтесь комментировать, как я могу улучшить свой вопрос.Unoverlappable Draggables с Snap.svg (Javascript)
Я пытаюсь сделать два прямоугольных прямоугольника SVG, которые не могут пересекаться. Чтобы сделать это, я использовал Snap.svg, чтобы заставить элементы перетаскивать, и с каждым вызовом функции переместить их ограничивающие поля, чтобы увидеть, сталкиваются ли они, используя метод утилиты .isBBoxIntersect в Snap API. Если они сталкиваются, я хочу убедиться, что они не будут перекрываться, и, таким образом, сделать каждый объект невозможен другим. Объект, который в данный момент перетаскивается, затем перемещается по определенной оси, пока столкновение не вернет false еще раз. У меня есть базовый код, что я хочу здесь:
<html>
<head>
<title>
</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script>
</head>
<body>
<script>
var s = Snap(600,500);
var rect = s.rect(0,0,40,40);
var rectr = s.rect(400,90,50,50);
var b=0;
var c=0;
var isInter;
var move = function(dx,dy, x, y, event) {
var b1 = rect.getBBox();
var b2 = rectr.getBBox();
isInter = Snap.path.isBBoxIntersect(b1, b2);
if (isInter==false) {
b=dx;
c=dy;
}
if (isInter==true) {
if (b1.y2==b2.y&&b1.x2==b2.x||b1.x==b2.x2&&b1.y2==b2.y){c=b2.y-b1.h, b=dx
}
else if (b1.x==b2.x2&&b1.y==b2.y2||b1.x2==b2.x&&b1.y==b2.y2){c=b2.y2; b=dx;}
else if (b1.y2==b2.y){(dy>=b2.y-b1.h) ? (c=b2.y-b1.h, b=dx): (b=dx, c=dy);}
else if (b1.y==b2.y2){(dy<=b1.y) ? (c=b2.y2, b=dx):(b=dx,c=dy);}
else if (b1.x2==b2.x){(dx>=b1.x) ? (b=b2.x-b1.width, c=dy):(b=dx, c=dy);}
else if (b1.x==b2.x2){(dx<=b1.x2) ? (b=b2.x2, c=dy):(b=dx, c=dy);}
else {b=dx; c=dy;}
}
this.attr({
transform: this.data('origTransform') + ((this.data('origTransform')) ? "t": "T") + [b,c]
});
}
var start = function() {
this.data('origTransform', this.transform().local);
b=0;
c=0;
}
rect.drag(move, start);
circle.drag(move, start);
</script>
</body>
</html>
Эти три главные проблемы, которые пришли:
Если перетащить слишком быстро, двигатель не может идти в ногу, и перетаскивания будут перекрываться. Я надеюсь на метод предотвращения перекрытия независимо от того, насколько быстро он перетаскивается.
Столкновение работает только при прямой, когда оно перетаскивается на rectr. Я мог бы легко добавить еще один блок обнаружения столкновений для rectr on rect, но я думаю, что это слишком сильно замедлит двигатель WAY. Мое обнаружение столкновения кажется слишком сложным. Таким образом, я надеюсь на более эффективный способ проверки столкновения.
Если прямая перетаскивается сначала, тогда прямая перетаскивается на rectr, обнаружение столкновения полностью не срабатывает. Это может быть проблема .getBBox(), но я не могу сказать наверняка.
Любая помощь по этим трем вопросам была бы чрезвычайно оценена.
Спасибо!
Трудно прочитать логики в вашем коде, не лучше замечаний, например, какие б, в. Вы уверены, что хотите тестировать bbox с такими вещами, как b1.y == b2.y? Не уверен, что вероятность их равных, просто проверьте, есть ли они = = или <= и т.д., чтобы найти точки блокировки. Возможно, я еще не совсем понял код. – Ian
Практически любой подход, позволяющий полностью перекрывать перекрытие, обычно обеспечивает нежелательное «заикание» в движении.Попытайтесь просто изменить непрозрачность сталкивающихся элементов, когда они сталкиваются, возвращая непрозрачность = 1, когда столкновение ложно. Это обеспечивает «нежную» обратную связь с пользователем во время перетаскивания, когда элементы столкнулись. –
@ Ian Я надеялся, что rect «прилипнет» к стороне rectr, на которую он столкнулся. Если я использовал> = или <= операторы, существует возможность прямого «телепортации» в условное выражение с оператором <= or > =, даже если он столкнулся с другой стороной rectr. –