如何使用单击按钮生成 Canvas 图层

How to generate Canvas layer with on click button

我有一个问题 - 如何在 Vue.js 中点击按钮时绘制 canvas 层(例如简单的正方形)?我有舞台,在那个舞台上的位置是 x:0,y:0 我想在单击按钮后生成那个正方形并通过拖放将其放置在那个舞台上?我正在使用 Konvajs 创建 Canvas

有人可以帮我吗?

<template>

 <div id="main">
  <h1></h1>            
  <div id="obszarroboczy" style="width: 500px; height: 600px;">

 <v-stage ref="stage"
      :config="configKonva"

      @dragstart="handleDragstart"
      @dragend="handleDragend">
      <v-layer ref="layer">
        <v-star
          v-for="item in list"
          :key="item.id"
          :config="item"></v-star>
      </v-layer>
      <v-layer ref="dragLayer"></v-layer>
    </v-stage>     
  </div>
  <div class="col-md-6">
    <button v-on:click="handleClick" id="more_canvas">More</button>
  </div>  
</div>
</template>

<script>


import Vue from "vue";
import axios from "axios";
import draggable from "vuedraggable";
import swal from "sweetalert2";
import VueKonva from "vue-konva";
export default {
  name: "EnumCurrencyIndex",
  $mount: "#main",
  components: {
    draggable
  },

  data() {
    return {
      model: [],
      editable: true,
      isDragging: false,
      delayedDragging: false,
      type: "currency",
      editedElement: null,
      newElement: "",
      list: [],
      configKonva: {
        width: 400,
        height: 400
      }, 
       configCircle: {
            x: 100,
            y: 100,
            radius: 70,
            fill: 'red',
            stroke: 'black',
            strokeWidth: 4
       },
      vm:  {}
    };
  },
  beforeMount() {
    this.fetchData();
  },


  computed: {
    dragOptions() {
      return {
        animation: 0,
        group: "description",
        disabled: !this.editable,
        ghostClass: "ghost"
      };
    },
    listString() {
      return this.model;
    },
     dragCanvas()  {
      return this.model;
    }
  },
  watch: {
    $route: "fetchData",
    isDragging(newValue) {
      if (newValue) {
        this.delayedDragging = true;
        return;
      }
      this.$nextTick(() => {
        this.delayedDragging = false;
      });
    }
  },
  methods: {

     handleDragstart(starComponent) {
       var vm = this;
      const shape = starComponent.getStage();
      const dragLayer = vm.$refs.dragLayer.getStage();
      const stage = vm.$refs.stage.getStage();
      // moving to another layer will improve dragging performance
      shape.moveTo(dragLayer);
      stage.draw();
      starComponent.config.shadowOffsetX = 15;
      starComponent.config.shadowOffsetY = 15;
      starComponent.config.scaleX = starComponent.config.startScale * 1.2;
      starComponent.config.scaleY = starComponent.config.startScale * 1.2;
    },
    handleDragend(starComponent) {
      var vm = this;
      const shape = starComponent.getStage();
      const layer = vm.$refs.layer.getStage();
      const stage = vm.$refs.stage.getStage();
      shape.moveTo(layer);
      stage.draw();
      shape.to({
        duration: 0.5,
        easing: Konva.Easings.ElasticEaseOut,
        scaleX: starComponent.config.startScale,
        scaleY: starComponent.config.startScale,
        shadowOffsetX: 5,
        shadowOffsetY: 5

      });


    },
     handleClick(configCircle) {
       var vm = this;
        const shape = vm.$refs.layer.getStage();
      const layer = vm.$refs.layer.getStage();
      const stage = vm.$refs.stage.getStage();

        console.log(1);
layer.add(configCircle);
stage.add(layer);




      },
 haveIntersection(r1, r2) {
            return !(
                r2.x > r1.x + r1.width ||
                r2.x + r2.width < r1.x ||
                r2.y > r1.y + r1.height ||
                r2.y + r2.height < r1.y
            );
        },


    orderList() {
      this.model = this.model.sort((one, two) => {
        return one.position - two.position;
      });
    },
    onMove({ relatedContext, draggedContext }) {
      const relatedElement = relatedContext.element;
      const draggedElement = draggedContext.element;
      return (
        (!relatedElement || !relatedElement.fixed) && !draggedElement.fixed
      );
    },
    fetchData() {
      var vm = this;
      axios
        .get(`/api/${this.resource}?type=${this.type}`)
        .then(function(response) {
          Vue.set(vm.$data, "model", response.data.model);
        })
        .catch(function(error) {
          console.log(error);
        });
    }
  },
  mounted() {
     var box = document.getElementById("obszarroboczy");
    this.configKonva.width = box.offsetWidth;
    this.configKonva.height = box.offsetHeight;

    var vm = this;
    for (let n = 0; n < 30; n++) {
      const scale = Math.random();
      const stage = vm.$refs.stage.getStage();
      vm.list.push({
        x: Math.random() * stage.getWidth(),
        y: Math.random() * stage.getHeight(),
        rotation: Math.random() * 180,
        numPoints: 5,
        innerRadius: 30,
        outerRadius: 50,
        fill: "#89b717",
        opacity: 0.8,
        draggable: true,
        scaleX: scale,
        scaleY: scale,
        shadowColor: "black",
        shadowBlur: 10,
        shadowOffsetX: 5,
        shadowOffsetY: 5,
        shadowOpacity: 0.6,
        startScale: scale
      });

    };

  },

  directives: {
    "element-focus": function(el, binding) {
      if (binding.value) {
        el.focus();
      }
    }
  }
};
</script>
<style>
#obszarroboczy {
  width: 100px;
  height: 300px;
}
.normal {
  background-color: grey;
}
.table td {
  width: 100px;
  height: 100px;
  background: white;
  border: 2px dotted black;
  max-width: 100px;
  padding: 5px;
}
.drag {
  display: flex;
  flex-direction: row;
}

.list {
  flex-grow: 1;
  max-width: 47%;
  margin-right: 40px;
}

.name {
  width: 50%;
  display: inline-block;
  height: 50px;
  background: pink;
  border: 5px green solid;
  box-sizing: border-box;
  padding: 5px;
}
.name.large {
  width: 100%;
}

.dragArea {
  min-height: 100px;
}
.dragArea img {
  margin: 3px;
  cursor: pointer;
}
</style>
var mainCanvas = new Vue({
  el: '#main', // the element where the method wil lrender the canvas to
  data: {
    name: 'Vue.js'
  },
  methods: {
    handleClick: function (event) { // handleClick is the method name for the button
      var stage = new Konva.Stage({ // this line till the stage.add() line renders the draggable square
        container: 'obszarroboczy',
        width: 500,
        height: 500
      });

      var layer = new Konva.Layer();

      var rect = new Konva.Rect({
        x: 0,
        y: 0,
        width: 100,
        height: 100,
        fill: 'green',
        stroke: 'black',
        strokeWidth: 4,
        draggable: true
      });

      layer.add(rect);

      stage.add(layer);
    }
  }
});

我添加了注释来解释某些重要行的作用,但您可以查看 GitHub 中的官方 KonvaJS Docs 以获得关于上面每一行的作用的更详细解释。