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

1

0

I would like to create Rectangle Shapes and Connections using the Vue-Konva/Konvajs within my application. I do not want to create load the Static values rather I would like to create the Shapes when the user clicks on the Add Node button and create Connectors when the user clicks on the Add Connector button and build the connections between Shapes.

I looked into a few things and was able to do it using the mouse events but was unable to convert it to button clicks.

Following is the current code I have: CodeSandbox

Can someone please guide me on how to create shapes and connectors on click of the button events? Any suggestion or guidance is much appreciated.

I am looking something like this: enter image description here

Brouwer answered 4/11, 2021 at 16:37 Comment(2)
Did you see this ? konvajs.org/docs/vue/index.htmlCurse
@VanquishedWombat Thanks a lot for the response. I looked at this example but the problem is that they have already created the star shape and then they are dragging it within the stage but in my case, I would like to create a new shape every time a user clicks on Add Node button.Brouwer
B
4

After trying a few things I was able to get it working. Posting here as it can be useful to someone in the future:

<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>
Brouwer answered 5/11, 2021 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.