我正在使用 Konva js 开发一个拖放项目,我希望当一个节点拖到另一个节点上时能够交换 2 个节点的位置。 在我的代码中,位置交换工作正常,因为我可以单击每个节点到 console.log 以查看节点的位置已交换。但更新后的节点位置目前处于两个节点的中间点。
nodeGroup.on("dragstart", function (evt) {
if (evt.evt.ctrlKey) {
stage.stopDrag();
stage.startDrag();
return;
}
//nodeGroup.moveToTop();
const draggedNode = evt.target; // The node being drag
draggedNode.zIndex(50); // set the drag node on top
var targetRect = node.getClientRect();
var nodeGroup = evt.currentTarget;
oldColor = nodeGroup.children[0].attrs.fill;
if (nodeGroup) {
if (nodeGroup.children[0].attrs.fill === "red") return;
nodeGroup.children[0].attrs.fill = "red";
}
//save the node's original position
draggedNodeStartPosition = { x: nodeGroup.x(), y: nodeGroup.y() };
});
nodeGroup.on("dragend", function (evt) {
if (!evt.evt) return;
if (evt.evt.ctrlKey) {
return;
}
var draggedNode = evt.currentTarget; // The node being drag
var draggedRect = draggedNode.getClientRect(); // Dragged node 's bounding box
var hasCollision = false;
//check all of the nodes to find the node that is overlapping
for (var n = 0; n < numberOfData; n++) {
if (`node-${n}` !== draggedNode.id()) {
// skip checking the node being drag
const checkNode = stage.find(`#node-${n}`)[0]; // the node being colided or drag into
const checkRect = checkNode.getClientRect();
if (hasOverlap(draggedRect, checkRect)) {
// Swap the positions of the dragged node and the collided node
const draggedNodeOldPosition = draggedNodeStartPosition;
const checkNodePosition = { x: checkNode.x(), y: checkNode.y() };
draggedNode.position(checkNodePosition);
//checkNode.position(draggedNodeOldPosition);
// Optional: Update zindex properties if needed
const draggedNodeZIndex = draggedNode.zIndex();
draggedNode.zIndex(checkNode.zIndex());
checkNode.zIndex(draggedNodeZIndex);
hasCollision = true;
break; // Exit the loop since we found a collision
}
}
}
draggedNode.getLayer().draw(); //reset layer
// If there was no collision, update the old position
if (!hasCollision) {
draggedNode.position(draggedNodeStartPosition);
}
const targetRect = evt.target.getClientRect();
nodeGroup.children[0].attrs.fill = oldColor;
var target = stage.getIntersection(stage.getPointerPosition());
});
我尝试了多种方法,包括仅更改被拖动节点的位置,但它仍然将节点移动到中间点,而不是被拖动到的节点位置
不要使用 shape.getClientRect() 进行定位。它受舞台位置和图层位置的影响。它给出了相对于 HTML5 画布容器左上角的位置。在这种情况下,这不是您想要的。
而是使用简单的 shape.position()。