vue canvas画多边形

第一个版本,只是单纯用来画多边形的,而且只能画一个。

<template>
  <div class="main">
    <div>这纷纷飞花,这纷纷飞花已坠落</div>
    <div>
      <canvas 
        id="mycanvas" 
        ref="mycanvas" 
        width="700" 
        height="450" 
        @mousedown="canvasDown($event)" 
        @mousemove="canvasMove($event)" 
        @dblclick="doubleclick()"></canvas>
    </div>
  </div>
</template>


<script>
export default {
  data() {
    return {
        isdraw: false,
        context: null,
        coordinates: [],
    };
  },
  methods: {
    initDraw() {
      const canvas = document.querySelector("#mycanvas");
      this.context = canvas.getContext("2d");
      this.context.strokeStyle='blue';
    },
    canvasDown(e) {
        var x = e.offsetX;
        var y = e.offsetY;
        this.coordinates.push({cor_x:x,cor_y:y});
        this.isdraw = true;
    },
    drawline(){
        for(var i=0; i<this.coordinates.length-1; i++){
            this.context.beginPath();
            var x0 = this.coordinates[i].cor_x;
            var y0 = this.coordinates[i].cor_y;
            var x1 = this.coordinates[i+1].cor_x;
            var y1 = this.coordinates[i+1].cor_y;
            this.context.moveTo(x0, y0);
            this.context.lineTo(x1, y1);
            this.context.stroke();
            this.context.closePath();
        }
    },
    canvasMove(e){
        if(this.coordinates.length == 0){
            return 0;
        }
        if(this.isdraw == false){
            return 0;
        }
        var last_x = this.coordinates[this.coordinates.length-1].cor_x;
        var last_y = this.coordinates[this.coordinates.length-1].cor_y;
        this.context.clearRect(0,0,700,450);
        this.drawline();
        this.context.beginPath();
        this.context.moveTo(last_x,last_y);
        var x = e.offsetX;
        var y = e.offsetY;
        this.context.lineTo(x,y);
        this.context.stroke();
        this.context.closePath();
    },
    doubleclick(){
        var x0 = this.coordinates[0].cor_x;
        var y0 = this.coordinates[0].cor_y;
        var x1 = this.coordinates[this.coordinates.length-1].cor_x;
        var y1 = this.coordinates[this.coordinates.length-1].cor_y;
        this.context.beginPath();
        this.context.moveTo(x0,y0);
        this.context.lineTo(x1,y1);
        this.context.stroke();
        this.context.closePath();
        this.isdraw = false
    }
  },
  mounted() {
    this.initDraw()
  },
  beforeDestroy() {},
};
</script>

<style scoped>
.main {
  height: 90vh;
  color: black;
  background: white;
}
#mycanvas {
  border: 1px solid red;
}
</style>

下面是第二个版本,添加了很多效果,自行体会。

<template>
  <div class="main">
    <div>绘制多边形,单击开始,双击结束。支持多个</div>
    <div>
      <button @click="test">清空</button>
    </div>
    <div>
      <img src="../assets/gate.jpg" id="img">
      <canvas 
        id="mycanvas" 
        ref="mycanvas" 
        width="700" 
        height="450" 
        @mousedown="canvasDown($event)" 
        @mousemove="canvasMove($event)" 
        @mouseup="canvasUp($event)"
        @dblclick="doubleclick()">浏览器不持之canvas</canvas>
    </div>
  </div>
</template>


<script>
export default {
  data() {
    return {
        isdraw: false, //是否在画图形
        ctx: null, //canvas对象
        coordinates: [], //一个多边形的坐标信息
        cor_index: 0, //当前多边形的索引
        endtip: false, //是否结束一个多边形的绘制
        all_coordinates: [], //所有多边形的信息
        isdrag: false,
        drag_index: [-1,-1],
        img: ""
    };
  },
  methods: {
    test(){
      this.all_coordinates = [];
      this.coordinates = []
      this.isdraw = false;
      this.endtip = false;
      this.ctx.clearRect(0,0,700,450);
    },
    fillarea(){
      this.ctx.fillStyle = 'rgba(0, 195, 155,0.4)';
      for(var i=0;i<this.all_coordinates.length;i++){
        var cors = this.all_coordinates[i];
        var x0 = cors[0].cor_x;
        var y0 = cors[0].cor_y;
        this.ctx.beginPath();
        this.ctx.moveTo(x0,y0);
        for(var j=1;j<cors.length;j++){
          var x = cors[j].cor_x;
          var y = cors[j].cor_y;
          this.ctx.lineTo(x,y);
        }
        this.ctx.fill();
        this.ctx.closePath();
      }
    },
    initDraw() { //初始化画布对象
      const canvas = document.querySelector("#mycanvas");
      this.ctx = canvas.getContext("2d");
      this.ctx.strokeStyle = 'rgb(0, 195, 155)';
    },
    isdragpoint(x,y){
      if(this.all_coordinates.length == 0){
        return false;
      }
      for(var i=0;i<this.all_coordinates.length;i++){
        for(var j=0;j<this.all_coordinates[i].length;j++){
          var px = this.all_coordinates[i][j].cor_x;
          var py = this.all_coordinates[i][j].cor_y;
          if(Math.abs(x-px) <= 5 && Math.abs(y-py) <= 5){
            this.drag_index[0] = i;
            this.drag_index[1] = j;
            return true;
          }
        }
      }
      return false;
    },
    canvasDown(e) {
        var x = e.offsetX;
        var y = e.offsetY;

        if(this.isdragpoint(x,y)){
          this.isdrag = true;
          return 0;
        }
      //画布中鼠标按下
        if(this.endtip){//已经结束了上个多边形的绘制,把上个多边形的坐标放入数组,同时清空单个多边形数组信息
          this.endtip = false;
        }
        //获取鼠标按下的坐标,放入数组中

        this.coordinates.push({cor_x:x,cor_y:y});
        this.isdraw = true; //正在画多边形
    },
    drawlines(){
      //把所有多边形画出来
      for(var i=0; i<this.all_coordinates.length; i++){
        var cors = this.all_coordinates[i];
        //前后坐标连线
        for(var j=0; j<cors.length-1; j++){
          this.ctx.beginPath();
          var x0 = cors[j].cor_x;
          var y0 = cors[j].cor_y;
          var x1 = cors[j+1].cor_x;
          var y1 = cors[j+1].cor_y;
          this.ctx.moveTo(x0,y0);
          this.ctx.lineTo(x1,y1);
          this.ctx.stroke();
          this.ctx.closePath();
        }
        //最后一个与第一个连线
        var begin_x = cors[0].cor_x;
        var begin_y = cors[0].cor_y;
        var end_x = cors[cors.length-1].cor_x;
        var end_y = cors[cors.length-1].cor_y;
        this.ctx.beginPath();
        this.ctx.moveTo(begin_x,begin_y);
        this.ctx.lineTo(end_x,end_y);
        this.ctx.stroke();
        this.ctx.closePath();
      }
    },
    drawline(){
      //把当前绘制的多边形之前的坐标线段绘制出来
        for(var i=0; i<this.coordinates.length-1; i++){
            this.ctx.beginPath();
            var x0 = this.coordinates[i].cor_x;
            var y0 = this.coordinates[i].cor_y;
            var x1 = this.coordinates[i+1].cor_x;
            var y1 = this.coordinates[i+1].cor_y;
            this.ctx.moveTo(x0, y0);
            this.ctx.lineTo(x1, y1);
            this.ctx.stroke();
            this.ctx.closePath();
        }
    },
    drawcircle(){
      //为当前的多边形端点画圆
      this.ctx.fillStyle = 'rgb(0, 195, 155)';
      for(var i=0;i<this.coordinates.length;i++){
        var x = this.coordinates[i].cor_x;
        var y = this.coordinates[i].cor_y;
        this.ctx.beginPath();
        this.ctx.moveTo(x,y);
        this.ctx.arc(x,y,5,0,Math.PI*2);
        this.ctx.fill();
        this.ctx.closePath();
      }
    },
    drawcircles(){
      //为所有的多边形端点画圆
      this.ctx.fillStyle = 'rgb(0, 195, 155)';
      for(var i = 0; i<this.all_coordinates.length; i++){
        var cors = this.all_coordinates[i];
        for(var j=0; j<cors.length; j++){
          var x = cors[j].cor_x;
          var y = cors[j].cor_y;
          this.ctx.beginPath();
          this.ctx.moveTo(x,y);
          this.ctx.arc(x,y,5,0,Math.PI*2);
          this.ctx.fill();
          this.ctx.closePath();
        }
      }
    },
    canvasUp(e){
      if(this.isdrag){
        this.isdrag = false;
      }
      this.drag_index = [-1,-1];
    },
    canvasMove(e){
      //画布中鼠标移动
      //没开始画或者结束画之后不进行操作
        var x = e.offsetX;
        var y = e.offsetY;
        if(this.isdrag){
          this.ctx.clearRect(0,0,700,450);
          this.all_coordinates[this.drag_index[0]][this.drag_index[1]].cor_x = x;
          this.all_coordinates[this.drag_index[0]][this.drag_index[1]].cor_y = y;
          this.drawlines();
          this.drawcircles();
          this.fillarea();
        }

        if(this.coordinates.length == 0 || !this.isdraw || this.endtip){
            return 0;
        }

        //获取上一个点
        var last_x = this.coordinates[this.coordinates.length-1].cor_x;
        var last_y = this.coordinates[this.coordinates.length-1].cor_y;
        this.ctx.clearRect(0,0,700,450); //清空画布
        this.drawline();//把之前的点连线
        this.drawcircle();
        if(this.all_coordinates.length != 0){//不止一个多边形,把多边形们画出来
          this.drawlines();
          this.drawcircles();
          this.fillarea();
        }
        //获取鼠标移动时的点,画线,实现线段跟踪效果。
        this.ctx.beginPath();
        this.ctx.moveTo(last_x,last_y);

        this.ctx.lineTo(x,y);
        this.ctx.stroke();
        this.ctx.closePath();
    },
    doubleclick(){
      //双击画布,在最后一个点的时候双击,自动连线第一个点,同时宣告画结束
        var x0 = this.coordinates[0].cor_x;
        var y0 = this.coordinates[0].cor_y;
        var x1 = this.coordinates[this.coordinates.length-1].cor_x;
        var y1 = this.coordinates[this.coordinates.length-1].cor_y;
        this.ctx.beginPath();
        this.ctx.moveTo(x0,y0);
        this.ctx.lineTo(x1,y1);
        this.ctx.stroke();
        this.ctx.closePath();
        this.isdraw = false;
        this.endtip = true
        this.drawcircle();
        this.coordinates.pop();
        this.all_coordinates.push(this.coordinates);
        
        this.ctx.fillStyle = 'rgba(0, 195, 155,0.4)';
        var bx = this.coordinates[0].cor_x;
        var by = this.coordinates[0].cor_y;
        this.ctx.beginPath();
        this.ctx.moveTo(bx,by);
        for(var k=1;k<this.coordinates.length;k++){
            var x = this.coordinates[k].cor_x;
            var y = this.coordinates[k].cor_y;
            this.ctx.lineTo(x,y)
        }
        this.ctx.fill();
        this.ctx.closePath();
        console.log(this.coordinates)
        this.coordinates = [];
    }
  },
  mounted() {
    this.initDraw()
  },
  beforeDestroy() {},
};
</script>

<style scoped>
.main {
  height: 90vh;
  color: black;
  background: white;
}
#mycanvas {
  border: 1px solid red;
  position: fixed;
  left: 0;
  right: 0;
  margin: auto;
}
#img{
  width: 700px;
  height: 450px;
  user-select:none;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值