KonvaJS 交换节点在组中的位置未按预期工作

问题描述 投票:0回答:1

我正在使用 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());
  });

我尝试了多种方法,包括仅更改被拖动节点的位置,但它仍然将节点移动到中间点,而不是被拖动到的节点位置

代码笔

javascript html konvajs
1个回答
0
投票

从您的代码中不清楚您是否使用 Konva.Groups 或其他形状。但是,由于我看到提到“nodeGroup”,那么您可能正在使用组。

组的位置并不像其他形状那样简单。组 do 具有位置,但通常我们不会明确设置它,因此它最初保持在 (0,0)。但是当您直接或通过变换拖动组时,group.position()is发生了变化。

其他形状,根据您的要求。我们可以使用位置来切换形状位置 - 当移动圆形和矩形时,我们必须做一些数学运算,因为它们的position位置不同。但这是符合逻辑的。

但是对于 Group,您需要注意 group.position 与子形状位置的关系。

© www.soinside.com 2019 - 2024. All rights reserved.