前端使用 Konva 實現視覺化設計器(4)

xachary發表於2024-04-11

上一章做一個補充,就是實現透過上下左右按鍵移動所選節點。

繼續求 Star ,希望大家多多一鍵三連,十分感謝大家的支援~

創作不易,Star 50 個,創作加速!

github原始碼

gitee原始碼

示例地址

透過按鍵移動節點

image

準備工作

給 SelectionTool 新增兩個必要的方法:

  // 更新已選位置
  selectingNodesAreaMove(offset: Konva.Vector2d) {
    this.selectingNodesArea?.x(this.selectingNodesArea.x() + offset.x)
    this.selectingNodesArea?.y(this.selectingNodesArea.y() + offset.y)
  }

  // 更新節點位置
  selectingNodesMove(offset: Konva.Vector2d) {
    for (const node of this.render.selectionTool.selectingNodes) {
      node.x(node.x() + offset.x)
      node.y(node.y() + offset.y)
    }
  }

根據上一章的設計,選中一個/多個節點的時候,還會伴隨一個 group 作為輔助,所以我們除了移動所選節點的同時,還需要移動 selectingNodesArea。

按鍵控制,就是需要處理 dom 的 keydown 和 keyup 兩個事件,放在 KeyMoveHandlers 檔案中,這裡是核心程式碼:

      keydown: (e: GlobalEventHandlersEventMap['keydown']) => {
        if (!e.ctrlKey) {
          if (
            Object.values(Types.MoveKey)
              .map((o) => o.toString())
              .includes(e.code)
          ) {
            if (e.code === Types.MoveKey.上) {
              this.render.selectionTool.selectingNodesAreaMove({ x: 0, y: -this.speed })
              this.render.selectionTool.selectingNodesMove({ x: 0, y: -this.speed })
            } else if (e.code === Types.MoveKey.左) {
              this.render.selectionTool.selectingNodesAreaMove({ x: -this.speed, y: 0 })
              this.render.selectionTool.selectingNodesMove({ x: -this.speed, y: 0 })
            } else if (e.code === Types.MoveKey.右) {
              this.render.selectionTool.selectingNodesAreaMove({ x: this.speed, y: 0 })
              this.render.selectionTool.selectingNodesMove({ x: this.speed, y: 0 })
            } else if (e.code === Types.MoveKey.下) {
              this.render.selectionTool.selectingNodesAreaMove({ x: 0, y: this.speed })
              this.render.selectionTool.selectingNodesMove({ x: 0, y: this.speed })
            }

            if (this.speed < this.speedMax) {
              this.speed++
            }
          }
        }
      },
      keyup: () => {
        this.speed = 1
      }

這裡設計的規則是,按一下移動 1 畫素,按著不動則會按 1 畫素增速移動,鬆開按鍵則恢復原來速度。

接下來,計劃實現下面這些功能:

  • 放大縮小所選的“磁貼效果”(基於網格)
  • 拖動所選的“磁貼效果”(基於網格)
  • 節點層次單個、批次調整
  • 鍵盤複製、貼上
  • 等等。。。

是不是更加有趣呢?是不是值得更多的 Star 呢?勾勾手指~

原始碼

gitee原始碼

示例地址

相關文章