vue canvas绘制多边形

一、html部分

<div>
    <el-row>
      <el-col :span="3">
        <div class="toolbar">
          <div >
            <el-button type="primary" size="mini" icon="el-icon-plus" @click="add">添加</el-button>
            <el-button type="primary" size="mini" icon="el-icon-view" @click="addExhibition">展示</el-button>
          </div>
        </div>
      </el-col>
      <el-col :span="20">
        <div class="canvas-box" style="width: 1276px; height: 718px;">
          <canvas id="mapcvs" width="1276" height="718"></canvas>
          <canvas id="cvs" width="1276" height="718"></canvas>
        </div>
      </el-col>
    </el-row>
  </div>

二、js部分

1、增加
add() {
	 flag = false //防止重复
	 clicksNum++ //当前第一几条数据
	 points[clicksNum] = {point:[],color:this.color16()} //随机颜色
	 cvs.addEventListener('mousedown', this.mousedownHandler, false)
	 cvs.addEventListener('dblclick', this.mousedbclick, false)
},
2、鼠标按下绘制
mousedownHandler(event) {
	 if (event.button == 0 && !flag) {
	   points[clicksNum].point.push({
	     x: event.pageX - cvsClientRect.x,
	     y: event.pageY - cvsClientRect.y
	   })
	   if (points.length >= 1) {
	     cvs.addEventListener('mousemove', this.mousemoveHandler, false)
	   }
	   this.drawPolygon(points[clicksNum].point,points[clicksNum].color)
 	}
},
3、鼠标双击确定绘制范围
mousedbclick(event) {
	flag = true
	cvs.removeEventListener('mousemove', this.mousemoveHandler)
},
4、清空绘制
clear() {
   points = []
   ctx.clearRect(0, 0, cvs.width, cvs.height)
},

三、全部代码

<template>
  <div>
    <el-row>
      <el-col :span="3">
        <div class="toolbar">
          <div >
            <el-button type="primary" size="mini" icon="el-icon-plus" @click="add">添加</el-button>
            <el-button type="primary" size="mini" icon="el-icon-view" @click="addExhibition">展示</el-button>
          </div>
          <div class="record" v-for="(item,index) in pointsData" :key="index">
            <div  :style="{ backgroundColor: item.color}"></div>
            <el-button type="success" icon="el-icon-edit" circle ></el-button>
            <el-button type="danger" icon="el-icon-delete" circle @click="itemClear(index)"></el-button>
          </div>
        </div>
      </el-col>
      <el-col :span="20">
        <div class="canvas-box" style="width: 1276px; height: 718px;">
          <canvas id="mapcvs" width="1276" height="718"></canvas>
          <canvas id="cvs" width="1276" height="718">不支持canvas</canvas>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
var cvs
var cvsClientRect
var ctx
let points//绘制数据
let clicksNum = -1
var flag
var mapcntx
var mapcanvas
export default {
  props:['imgSrc'],
  data() {
    return {
      pointsData:[],绘制数据
      colorList: ['#EB675E',"#EB675E","#B33EA1","#FDCF78","#6991ED","#9599E1","#D3AAE1","#FF88B3","#E77B79","#0FABEB","#ADFFC1",'#92D2E1','#9FB0E1'],
      colorActionList:[]
    }
  },
  mounted() {
    cvs = document.getElementById('cvs')
    cvsClientRect = cvs.getClientRects()[0]
    ctx = cvs.getContext('2d')
    points = []
    flag = false
    mapcanvas = document.getElementById('mapcvs')
    mapcntx = mapcanvas.getContext('2d')
    var img = new Image()
    img.src = this.imgSrc
    img.onload = function() {
      var pattern = mapcntx.createPattern(img, 'no-repeat')
      mapcntx.drawImage(img, 0, 0)
      mapcntx.fillStyle = pattern
      mapcntx.fillRect(0, 0, 300, 300)
    }
  },
  methods: {
    //增加
    add() {
      flag = false
      clicksNum++
      console.log(clicksNum)
      points[clicksNum] = {point:[],color:this.color16()}
      cvs.addEventListener('mousedown', this.mousedownHandler, false)
      cvs.addEventListener('dblclick', this.mousedbclick, false)
    },
    //全部删除
    clear() {
      points = []
      ctx.clearRect(0, 0, cvs.width, cvs.height)
    },
    mousedownHandler(event) {
      if (event.button == 0 && !flag) {
        
        points[clicksNum].point.push({
          x: event.pageX - cvsClientRect.x,
          y: event.pageY - cvsClientRect.y
        })
        if (points.length >= 1) {
          cvs.addEventListener('mousemove', this.mousemoveHandler, false)
        }
        this.drawPolygon(points[clicksNum].point,points[clicksNum].color)
      }
    },
    //鼠标双击
    mousedbclick(event) {
      flag = true
      cvs.removeEventListener('mousemove', this.mousemoveHandler)
    },
    //canvas绘制
    drawPolygon(point,color) {
      ctx.clearRect(0, 0, cvs.width, cvs.height)

      ctx.strokeStyle = color
      ctx.beginPath()
      ctx.lineWidth=3
      ctx.moveTo(point[0].x, point[0].y)
      for (var i = 1; i < point.length; i++) {
        ctx.lineTo(point[i].x, point[i].y)
      }
      ctx.closePath()
      ctx.stroke()
      this.$nextTick(()=>{  
        this.pointsData = points.filter(d => d)
        this.$emit('drawAreaDataEv',points)
        this.$forceUpdate()
      })
    },
    //鼠标左键抬起当前位置
    mousemoveHandler(event) {
      this.drawPolygon(
        points[clicksNum].point.concat({
          x: event.pageX - cvsClientRect.x,
          y: event.pageY - cvsClientRect.y
        }),
        points[clicksNum].color
      )
    },
    //全部展示
    addExhibition() {
      ctx.clearRect(0, 0, cvs.width, cvs.height)
      points.forEach(ite=>{
        ctx.strokeStyle = ite.color
        ctx.beginPath()
        ctx.lineWidth=3
        ctx.moveTo(ite.point[0].x, ite.point[0].y)
        ite.point.forEach(it=>{
          ctx.lineTo(it.x, it.y)
        })
        ctx.closePath()
        ctx.stroke()
      })
    },
    //删除其中一条数据
    itemClear(index) {
      points = points.filter(d => d)
      this.colorList.unshift(this.pointsData[index].color)
      this.colorActionList.splice(clicksNum,1)
      points.splice(index,1)
      this.pointsData.splice(index,1)
      clicksNum--
      this.$emit('drawAreaDataEv',points)
      this.addExhibition()
    },
    //判断距离
    distanceCheck(lng_a, lat_a, lng_b, lat_b) {
      var pk = 180 / 3.14169;
      var a1 = lat_a / pk;
      var a2 = lng_a / pk;
      var b1 = lat_b / pk;
      var b2 = lng_b / pk;
      var t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
      var t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
      var t3 = Math.sin(a1) * Math.sin(b1);
      var tt = Math.acos(t1 + t2 + t3);
      return Math.floor(6366000 * tt);
    },
    //十六进制颜色随机
    color16(){
      let color = ''
			if(clicksNum>=this.colorList.length-1) {
        color = this.colorList[this.colorList.length-1]
      }else {
        color = this.colorList[clicksNum]
        this.colorActionList.push(color)
        this.colorList.splice(clicksNum,1)
      }
     return color
		}
  }
}
</script>

<style lang="scss">
canvas {
  // border: 1px solid #000;
  position: absolute;
}
.record {
  display: flex;
  align-items: center;
  margin-top: 10px;
  >div {
    width: 80px;
    height: 3px;
    margin: 0 10px;
    cursor: pointer;
  }
}
.toolbar {
  margin-right: 20px;
}
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值