前端使用 Konva 实现可视化设计器(6)- 复制粘贴、删除、位置、zIndex调整

本文详细介绍了使用Konva库进行节点复制、粘贴、删除操作的代码实现,包括右键菜单控制、层次调整、事件处理,以及与zIndex管理相关的逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请大家动动小手,给我一个免费的 Star 吧~

这一章处理一下复制、粘贴、删除、画布归位、层次调整,通过右键菜单控制。

github源码

gitee源码

示例地址

复制粘贴

复制粘贴(通过快捷键)

在这里插入图片描述

  // 复制暂存
  pasteCache: Konva.Node[] = [];
  // 粘贴次数(用于定义新节点的偏移距离)
  pasteCount = 1;

  // 复制
  pasteStart() {
   
    this.pasteCache = this.render.selectionTool.selectingNodes.map((o) => {
   
      const copy = o.clone();
      // 恢复透明度、可交互
      copy.setAttrs({
   
        listening: true,
        opacity: copy.attrs.lastOpacity ?? 1,
      });
      // 清空状态
      copy.setAttrs({
   
        nodeMousedownPos: undefined,
        lastOpacity: undefined,
        lastZIndex: undefined,
        selectingZIndex: undefined,
      });
      return copy;
    });
    this.pasteCount = 1;
  }

  // 粘贴
  pasteEnd() {
   
    if (this.pasteCache.length > 0) {
   
      this.render.selectionTool.selectingClear();
      this.copy(this.pasteCache);
      this.pasteCount++;
    }
  }

快捷键处理:

    keydown: (e: GlobalEventHandlersEventMap['keydown']) => {
   
        if (e.ctrlKey) {
   
          if (e.code === Types.ShutcutKey.C) {
   
            this.render.copyTool.pasteStart() // 复制
          } else if (e.code === Types.ShutcutKey.V) {
   
            this.render.copyTool.pasteEnd() // 粘贴
          }
        }
      }
    }

逻辑比较简单,可以关注代码中的注释。

复制粘贴(右键)

在这里插入图片描述

  /**
   * 复制粘贴
   * @param nodes 节点数组
   * @param skip 跳过检查
   * @returns 复制的元素
   */
  copy(nodes: Konva.Node[]) {
   
    const arr: Konva.Node[] = [];

    for (const node of nodes) {
   
      if (node instanceof Konva.Transformer) {
   
        // 复制已选择
        const backup = [...this.render.selectionTool.selectingNodes];
        this.render.selectionTool.selectingClear();
        this.copy(backup);
      } else {
   
        // 复制未选择
        const copy = node.clone();
        // 使新节点产生偏移
        copy.setAttrs({
   
          x: copy.x() + this.render.toStageValue(this.render.bgSize) * this.pasteCount,
          y: copy.y() + this.render.toStageValue(this.render.bgSize) * this.pasteCount,
        });
        // 插入新节点
        this.render.layer.add(copy);
        // 选中复制内容
        this.render.selectionTool.select([...this.render.selectionTool.selectingNodes, copy]);
      }
    }

    return arr;
  }

逻辑比较简单,可以关注代码中的注释。

删除

在这里插入图片描述

处理方法:

  // 移除元素
  remove(nodes: Konva.Node[]) {
   
    for (const node of nodes) {
   
      if (node instanceof Konva.Transformer) {
   
        // 移除已选择的节点
        this.remove(this.selectionTool.selectingNodes);
        // 清除选择
        this.selectionTool.selectingClear();
      } else {
   
        // 移除未选择的节点
        node.remove();
      }
    }
  }

事件处理:

      keydown: (e: GlobalEventHandlersEventMap['keydown']) => {
   
        if (e.ctrlKey) {
   
          // 略
        } else if (e.code === Types.ShutcutKey.删除) {
   
          this.render.remove(this.render.selectionTool.selectingNodes)
        }
      }

画布归位

逻辑比较简单,恢复画布比例和偏移量:

  // 恢复位置大小
  positionZoomReset() {
   
    this.render.stage.setAttrs({
   
      scale: {
    x: 1, y: 1 }
    })

    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值