我正在使用 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());
});
我尝试了多种方法,包括仅更改被拖动节点的位置,但它仍然将节点移动到中间点,而不是被拖动到的节点位置
从您的代码中不清楚您是否使用 Konva.Groups 或其他形状。但是,由于我看到提到“nodeGroup”,那么您可能正在使用组。
组的位置并不像其他形状那样简单。组 do 具有位置,但通常我们不会明确设置它,因此它最初保持在 (0,0)。但是当您直接或通过变换拖动组时,group.position()is发生了变化。
其他形状,根据您的要求。我们可以使用位置来切换形状位置 - 当移动圆形和矩形时,我们必须做一些数学运算,因为它们的position位置不同。但这是符合逻辑的。
但是对于 Group,您需要注意 group.position 与子形状位置的关系。