鼠标在canvas画布上绘制凸多边形

/*主要功能:
   *     1.鼠标绘制凸多边形
   *     2.拖动多边形顶点坐标,可修改多边形
   *     2.凸多边形内嵌套多个多边形
   *     3.判断是否在监控区内
   * */
exports.install = function (Vue, options) {
  Vue.prototype.shieldFn = function (canvas,ctx) {
      var _sThis = this;
    //屏蔽区坐标;最终坐标;所有屏蔽区最终坐标;是否可以绘制屏蔽区
    var shieldPosi = [],sendShieldPosi=[],allShieldPosi = [];
    var shield_count = 0;//屏蔽区域的数量
    var dbclick = false;//上次绘制是否结束

    var imgData;

    // console.log("图片地址----",_sThis.$store.state.exportImgUrl)
    //加载图片
    var image = new Image();
    image.src = _sThis.$store.state.exportImgUrl;
    image.onload = function(){
      ctx.drawImage(image,0,0,canvas.width,canvas.height);
    }

    //鼠标按下
    canvas.onmousedown = function (event) {
      var downPosi = _sThis.windowToCanvas(canvas,event.clientX,event.clientY);

      //屏蔽区的坐标;需要判断是否在监控区域内
      var isIn = _sThis.pointInPoly(downPosi,_sThis.$store.state.sendMonitorPosi);

      if(isIn){
        //在监控区域
        shieldPosi.push(downPosi);
        //是否是凸多边形
        if(shieldPosi.length>3){
          var  polygoning = _sThis.convex(shieldPosi,shieldPosi.length);

          if(polygoning!=1){
            shieldPosi.pop(downPosi);
            alert("您绘制的不是凸多边形,请重新绘制");
            return;
          }
        }
      }else{
        alert("只能在监控区域内绘制")
      }

      //鼠标移动
      canvas.onmousemove = function (ev) {
        var movePosi = _sThis.windowToCanvas(canvas,ev.clientX,ev.clientY);
        drawLine(ctx,movePosi.x,movePosi.y,shieldPosi,2,"black","skyblue","rgba(255,255,255,0.8)");
      }
    }


    //双击;取消绘制;保存画布;获取最终所有点的坐标
    canvas.ondblclick = function (e) {
      var dbPosi = _sThis.windowToCanvas(canvas,e.clientX,e.clientY);

      var  polygon = _sThis.convex(shieldPosi,shieldPosi.length);//是否是凸多边形

      if(polygon!=1){
        alert("您绘制的不是凸多边形,请重新绘制");
        return;
      }

      shieldPosi.push(dbPosi);
      var shieldEndPosis = _sThis.endPosi(shieldPosi,sendShieldPosi);//最终坐标

      drawLine(ctx,dbPosi.x,dbPosi.y,shieldPosi,2,"black","skyblue","rgba(255,255,255,0.8)"); //显示最后一个顶点的圆形样式
      shield_count++;

      allShieldPosi.push(sendShieldPosi);
      _sThis.$store.commit("getShieldPosi",allShieldPosi)
      console.log("所有屏蔽区最终坐标========",_sThis.$store.state.shieldEndPosi);

      canvas.onmousemove = null;

      //保存画布;清空原数组
      imgData = ctx.getImageData(0,0,canvas.width,canvas.height);
      sendShieldPosi = [];
      shieldPosi = [];
      dbclick = true;//

    }


    //--------------------绘制遮罩的函数---------------------------------------
    function drawLine(ctx,moveX,moveY,posi,lineWidth,lineColor,arcFillColor,areaColor){
      ctx.clearRect(0,0,canvas.width,canvas.height);

      if(dbclick){
          //上次双击已结束;将画布数据复制
        ctx.putImageData(imgData,0,0);
      }else{
        ctx.drawImage(image,0,0,canvas.width,canvas.height);
      }

      //--多边形----
      ctx.beginPath();
      ctx.lineJoin = 'round';//线段连接点
      ctx.strokeStyle = lineColor;
      ctx.fillStyle = areaColor;
      ctx.lineWidth = lineWidth;

      //绘制直线线段起始坐标点
      if(posi.length!=0){
        ctx.moveTo(posi[0].x,posi[0].y);
      }

      for(var i = 0; i < posi.length ; i++){
        ctx.lineTo(posi[i].x,posi[i].y);
      }
      ctx.lineTo(moveX,moveY);//鼠标移动的坐标位置
      ctx.fill();
      ctx.closePath();
      ctx.stroke();

      //---顶点----
      ctx.beginPath();
      ctx.fillStyle = arcFillColor;
      for(var i =0; i < posi.length;i++){
        ctx.arc(posi[i].x, posi[i].y,5,0,2*Math.PI);
        ctx.closePath();
        ctx.fill();//这一部分不能放到for循环的外面
      }
    }

  }

  Vue.prototype.clearAllShield = function (canvas,ctx) {
    ctx.clearRect(canvas,0,0,canvas.width,canvas.height);
    this.imgToCanvas(canvas,ctx,this.$store.state.exportImgUrl);

  }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值