前端使用 Konva 实现可视化设计器(3)- 单选、多选、选择框

github/gitee Star 终于有几个了!
从这章开始,难度算是(或者说细节较多)升级,是不是值得更多的 Star 呢?!
继续求 Star ,希望大家多多一键三连,十分感谢大家的支持~
创作不易,Star 50 个,创作加速!
github源码
gitee源码
示例地址

选择框

在这里插入图片描述

准备工作

想要拖动一个元素,可以考虑使用节点的 draggable 属性。

不过,想要拖动多个元素,可以使用 transformer,官网也是简单的示例 Basic demo

按设计思路统一通过 transformer 移动/缩放所选,也意味着,元素要先选后动。

先准备一个 group、transformer、selectRect:

  // 多选器层
  groupTransformer: Konva.Group = new Konva.Group()

  // 多选器
  transformer: Konva.Transformer = new Konva.Transformer({
   
    shouldOverdrawWholeArea: true,
    borderDash: [4, 4],
    padding: 1,
    rotationSnaps: [0, 45, 90, 135, 180, 225, 270, 315, 360]
  })

  // 选择框
  selectRect: Konva.Rect = new Konva.Rect({
   
    id: 'selectRect',
    fill: 'rgba(0,0,255,0.1)',
    visible: false
  })

先说 transformer,设置 shouldOverdrawWholeArea 为了选择所选的空白处也能拖动;rotationSnaps 就是官方提供的 rotate 时的磁贴交互。

然后,selectRect 就是选择框,参考的就是上面提到的 Basic demo

最后,上面的 group 比较特别,它承载了上面的 transformer 和 selectRect,且置于第一章提到的 layerCover

    // 辅助层 - 顶层
    this.groupTransformer.add(this.transformer)
    this.groupTransformer.add(this.selectRect)
    this.layerCover.add(this.groupTransformer)

selectRect 不应该被“交互”,所以加个排查判断:

  // 忽略非素材
  ignore(node: Konva.Node) {
   
    // 素材有各自根 group
    const isGroup = node instanceof Konva.Group
    return !isGroup || node.id() === 'selectRect' || this.ignoreDraw(node)
  }

选择

准备一些状态变量:

  // selectRect 拉动的开始和结束坐标
  selectRectStartX = 0
  selectRectStartY = 0
  selectRectEndX = 0
  selectRectEndY = 0
  // 是否正在使用 selectRect
  selecting = false

选择开始,处理 stage 的 mousedown 事件:

	mousedown: (e: Konva.KonvaEventObject<GlobalEventHandlersEventMap['mousedown']>) => {
   
        // 略

        if (e.target === this.render.stage) {
   
          // 点击空白处

          // 清除选择
          // 外部也需要此操作,统一放在 selectionTool中
          // 后面会提到
          this.render.selectionTool.selectingClear()

          // 选择框
          if (e.evt.button === Types.MouseButton.左键) {
   
            const pos = this.render.stage.getPointerPosition()
            if (pos) {
   
              // 初始化状态值
              this.selectRectStartX = pos.x
              this.selectRectStartY = pos.y
              this.selectRectEndX = pos.x
              this.selectRectEndY = pos.y
            }

			// 初始化大小
            this.render.selectRect.width(0)
            this.render.selectRect.height(0)

			// 开始选择
            this.selecting = true
          }
        } else if (parent instanceof Konva.Transformer) {
   
          // transformer 点击事件交给 transformer 自己的 handler
        } else if (parent instanceof Konva.Group) {
   
          // 略
        }
      }

接着,处理 stage 的 mousemove 事件:

	mousemove: () => {
   
        // stage 状态
        const stageState = this.render.getStageState()

        // 选择框
        if (this.selecting) {
   
          // 选择区域中
          const pos = this.render.stage.getPointerPosition()
          if (pos) {
   
            // 选择移动后的坐标
            this.selectRectEndX 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值