创建基于按钮单击事件动态创建的 Konvajs 形状和连接

Create Konvajs Shapes and Connections creating dynamically based on button click events

我想在我的应用程序中使用 Vue-Konva/Konvajs 创建 Rectangle ShapesConnections。我不想创建加载 Static 值,而是我想在用户单击 Add Node 按钮时创建 Shapes 并在用户单击时创建 Connectors Add Connector 按钮并在 Shapes.

之间建立连接

我研究了一些事情并能够使用 mouse events 来完成,但无法将其转换为 button clicks

以下是我目前的代码:CodeSandbox

有人可以指导我如何在单击按钮事件时创建形状和连接器吗?非常感谢任何建议或指导。

我看起来像这样:

在尝试了一些东西之后,我能够让它正常工作。在这里发布,因为它可能对将来的人有用:

<template>
  <div class="container-fluid">
    <div class="row">
      <div class="col-sm-6">
        <button class="btn btn-primary btn-sm" @click="addEvent()">
          Add Event
        </button>&nbsp;
        <button class="btn btn-success btn-sm" @click="submitNodes()">
          Submit
        </button>&nbsp;
      </div>
    </div>
    <div class="row root">
      <div class="col-sm-12 body">
        <v-stage
          ref="stage"
          class="stage"
          :config="stageSize"
          @mouseup="handleMouseUp"
          @mousemove="handleMouseMove"
          @mousedown="handleMouseDown"
        >
          <v-layer ref="layer">
            <v-rect
              v-for="(rec, index) in nodeArray"
              :key="index"
              :config="{
                x: Math.min(rec.startPointX, rec.startPointX + rec.width),
                y: Math.min(rec.startPointY, rec.startPointY + rec.height),
                width: Math.abs(rec.width),
                height: Math.abs(rec.height),
                fill: 'rgb(0,0,0,0)',
                stroke: 'black',
                strokeWidth: 3,
              }"
            />
          </v-layer>
        </v-stage>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      stageSize: {
        width: null,
        height: 900
      },
      lines: [],
      isDrawing: false,
      eventFlag: false,
      nodeCounter: 0,
      nodeArray: []
    }
  },
  mounted () {
    if (process.browser && window !== undefined) {
      this.stageSize.width = window.innerWidth
      // this.stageSize.height = window.innerHeight
    }
  },
  methods: {
    handleMouseDown (event) {
      if (this.eventFlag) {
        this.isDrawing = true
        const pos = this.$refs.stage.getNode().getPointerPosition()
        const nodeInfo = this.nodeArray[this.nodeArray.length - 1]
        nodeInfo.startPointX = pos.x
        nodeInfo.startPointY = pos.y
        console.log(JSON.stringify(nodeInfo, null, 4))
      }
    },
    handleMouseUp () {
      this.isDrawing = false
      this.eventFlag = false
    },
    setNodes (element) {
      this.nodeArray = element
    },
    handleMouseMove (event) {
      if (!this.isDrawing) {
        return
      }
      // console.log(event);
      const point = this.$refs.stage.getNode().getPointerPosition()
      // Handle  rectangle part
      const curRec = this.nodeArray[this.nodeArray.length - 1]
      curRec.width = point.x - curRec.startPointX
      curRec.height = point.y - curRec.startPointY
    },
    // Function to read the Nodes after add all the nodes
    submitNodes () {
      console.log('ALL NODE INFO')
      console.log(JSON.stringify(this.nodeArray, null, 4))
      this.handleDragstart()
    },
    addEvent () {
      this.eventFlag = true
      this.setNodes([
        ...this.nodeArray,
        {
          width: 0,
          height: 0,
          draggable: true,
          name: 'Event ' + this.nodeCounter
        }
      ])
      this.nodeCounter++
    }
  }
}
</script>

<style scoped>
.root {
  --bg-color: #fff;
  --line-color-1: #D5D8DC;
  --line-color-2: #a9a9a9;
}

.body {
  height: 100vh;
  margin: 0;
}

.stage {
  height: 100%;
  background-color: var(--bg-color);
  background-image: conic-gradient(at calc(100% - 2px) calc(100% - 2px),var(--line-color-1) 270deg, #0000 0),
    conic-gradient(at calc(100% - 1px) calc(100% - 1px),var(--line-color-2) 270deg, #0000 0);
  background-size: 100px 100px, 20px 20px;
}
</style>