You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

KonvaJS拖拽节点交换位置异常:节点显示在中点而非目标位置

KonvaJS拖拽节点交换位置显示异常

我用KonvaJS开发拖拽项目,需求是拖拽节点到另一节点上时,两者交换位置。通过console.log能确认位置数据已经完成交换,但节点实际显示在两个节点的中点,而非目标节点的位置。比如拖拽节点65到节点35时就会出现这个问题。

相关代码片段:

nodeGroup.on("dragstart", function (evt) {
  if (evt.evt.ctrlKey) {
    stage.stopDrag();
    stage.startDrag();
    return;
  }
  //nodeGroup.moveToTop();
  const draggedNode = evt.target; // 被拖拽的节点
  draggedNode.zIndex(50); // 将拖拽节点置于顶层

  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";
  }
  // 保存节点原始位置
  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; // 被拖拽的节点
  var draggedRect = draggedNode.getClientRect(); // 拖拽节点的边界框
  var hasCollision = false;

  // 遍历所有节点,查找重叠的目标节点
  for (var n = 0; n < numberOfData; n++) {
    if (`node-${n}` !== draggedNode.id()) {
      // 跳过自身
      const checkNode = stage.find(`#node-${n}`)[0]; // 被碰撞的节点
      const checkRect = checkNode.getClientRect();
      if (hasOverlap(draggedRect, checkRect)) {
        // 交换拖拽节点与碰撞节点的位置
        const draggedNodeOldPosition = draggedNodeStartPosition;
        const checkNodePosition = { x: checkNode.x(), y: checkNode.y() };

        draggedNode.position(checkNodePosition);
        //checkNode.position(draggedNodeOldPosition);

        // 可选:交换层级
        const draggedNodeZIndex = draggedNode.zIndex();
        draggedNode.zIndex(checkNode.zIndex());
        checkNode.zIndex(draggedNodeZIndex);

        hasCollision = true;
        break; // 找到碰撞节点后退出循环
      }
    }
  }
  draggedNode.getLayer().draw(); // 重绘图层

  // 如果没有碰撞,恢复原始位置
  if (!hasCollision) {
    draggedNode.position(draggedNodeStartPosition);
  }

  const targetRect = evt.target.getClientRect();
  nodeGroup.children[0].attrs.fill = oldColor;
  var target = stage.getIntersection(stage.getPointerPosition());
});

我尝试过多种方法,包括仅修改拖拽节点的位置,但节点仍会移动到两个节点的中点,而非被拖拽到的节点位置。


内容的提问来源于stack exchange,提问作者An Khuat Quang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:06:02