最近收到一个需求,根据角度在平面上画出对应的区域,实际就是 以固定的原点,根据起始角度和结束角度和半径,画出他的区域。

写了一小段,试试


export class Draw {
  constructor(domId) {
    let canvas = document.getElementById(domId);
    this.initLoad = false
    this.storeName = ""
    this.canvas = canvas;
    this.context = canvas.getContext('2d'); //创建在画布上绘图的环境
  }
  init(x,y,offset=0) {
    // 圆心坐标 x, y .  起始角度的偏差值 offset
    this.initLoad = true
    this.cx = x;
    this.cy = y;
    this.offset = offset
  }
  mousemoveInit(callback) {
    let _this = this
    this.canvas.addEventListener("mousemove", function __handler__(evt) {
      if (!_this.initLoad) return
        var x = evt.clientX;
        var y = evt.clientY;
        var rect = _this.canvas.getBoundingClientRect();  //返回元素的大小及其相对于视口的位置
        x -= rect.left;
        y -= rect.top;
        let xl = Math.abs(x-_this.cx) //取绝对值
        let yl = Math.abs(y-_this.cy)
        let hl = _this.findHypotenuse(xl,yl)  //根据直角边,求斜边的长度
        if (hl<200){
          let ang = _this.getAngle(xl,yl,x,y) // 获取点相对圆心的角度, 0 度在横轴x 上
          let offsetAng = _this.getOffsetAngle(ang)
          callback(x, y,offsetAng)
          // console.log(x, y,offsetAng); // (x, y) 就是鼠标在 canvas 单击时的坐标 ang 是角度
        }else{
          callback(0, 0,500)
        }
        
    });
  }
  
  getOffsetAngle(ang) {
    // 根据计算的标准角度 返回用户需要的偏差角度
    return ang>90?ang-this.offset:ang+270
  }
  getAngle(x, y,ox,oy) {
      // 根据直角边 求角度
      var radian = Math.atan(y / x);//弧度    (y / x)为直线的斜率
      var angle = Math.floor(180 / (Math.PI / radian));//弧度转角度
      if (x < 0) {//x小于0的时候加上180°,即实际角度
          angle = angle + 180;
      }
      if (ox>=this.cx && oy>= this.cy) {
        return angle;
      } else if (ox  <= this.cx && oy>= this.cy) {
        return 180-angle
      }else if (ox  <= this.cx && oy<= this.cy) {
        return 180+angle
      }else if (ox>=this.cx && oy<= this.cy) {
        return 360-angle
      }
  }
  findHypotenuse (base,perpendicular) {
    // 根据直角边 求斜边的长度
    const bSquare = base ** 2;
    const pSquare = perpendicular ** 2;
    const sum = bSquare + pSquare;
    const hypotenuse = Math.sqrt(sum);  //返回一个数的平方根
    return Math.floor(hypotenuse);
  }
  mathAngle(angle,r) {
    // 根据角度求 坐标
    let angObj = {
      x: '',
      y: ''
    }
    var angles = 0;
    var radian = 0;
    if (angle<=90) {
      angles = 90-angle
    }else if (angle>90 && angle <=180) {
      angles = angle-90
    }else if (angle>180 && angle <=270) {
      angles = 270- angle
    }else if (angle>270 && angle <=360) {
      angles = angle-270
    }
    radian = angles * Math.PI / 180
    let xlen = Math.floor(Math.sin(radian)*r)
    let ylen = Math.floor(Math.cos(radian)*r)
    
    if (angle<=90) {
      angObj.x = this.cx+xlen
      angObj.y = this.cy+ylen
    }else if (angle>90 && angle <=180) {
      angObj.x = this.cx-xlen
      angObj.y = this.cy+ylen
    }else if (angle>180 && angle <=270) {
      angObj.x = this.cx-xlen
      angObj.y = this.cy-ylen
    }else if (angle>270 && angle <=360) {
      angObj.x = this.cx+xlen
      angObj.y = this.cy-ylen
    }
    return angObj
  }
  clearRect () {
    // 清除画布
    this.context.clearRect(0,0,this.cx*2,this.cy*2);
  }
  lines (x1,y1,x2,y2,color,width=5) {
    // 画直线
    this.context.beginPath();
    this.context.lineWidth = width;
    this.context.moveTo(x1,y1);
    
    this.context.lineTo(x2,y2); 
    this.context.strokeStyle = color; 
    this.context.stroke();
  }
  pieChart(r,sAngle,eAngle,color,flag=true) {
    // 画扇形
    let startAngle = 2*sAngle/360
    let endAngle = 2*eAngle/360
    this.context.beginPath();
    this.context.lineWidth = 1;
    this.context.moveTo(this.cx,this.cy);
    this.context.strokeStyle = "white";
    this.context.fillStyle = color;
    this.context.arc(this.cx,this.cy,r,startAngle*Math.PI,endAngle*Math.PI);
    this.context.fill();
    this.context.closePath();
    this.context.stroke();
  }
  pieName(x,y,color,name) {
    //文字绘制到扇形旁边
    this.context.fillText(name,x,y);
  }
}
export class Angle extends Draw {
  correct (ang) {
    // 将传入的角度按照偏差值 进行纠正
    return ang+this.offset<=360?ang+this.offset:ang+this.offset-360
  }
  correctM (sAngle,eAngle) {
    // 取俩角度中间值
    if (sAngle > eAngle) {
      let ang = sAngle + 1/2*(360-sAngle+eAngle);
      return ang>360?ang-360:ang
    }
    return sAngle + 1/2*(eAngle-sAngle);
  }
  drawAir (r,sAngle,eAngle,color,name) {
    // 画分区的扇形
    sAngle = this.correct(sAngle)
    eAngle = this.correct(eAngle)
    this.pieChart(r,sAngle,eAngle,color,name)
    
  }
  drawName (r,sAngle,eAngle,color,name) {
    // 画分区的名字
    sAngle = this.correct(sAngle)
    eAngle = this.correct(eAngle)
    //计算文字要放的角度
    var txtAngle = this.correctM(sAngle,eAngle)
    this.context.textAlign = 'center';
    if(txtAngle>95 && txtAngle<260){
      this.context.textAlign = 'end';
    }
    if(txtAngle<85 && txtAngle>5){
      this.context.textAlign = 'left';
    }
    if(txtAngle<350 && txtAngle>275){
      this.context.textAlign = 'left';
    }
    
    var x,y;
    x=this.cx+Math.cos(txtAngle*Math.PI/180)*(r+20);
    y=this.cy+Math.sin(txtAngle*Math.PI/180)*(r+20);
    this.pieName(x,y,color,name)
    
  }
  drawMachine(r,angle,color) {
    // 画机器的位置
    this.lines(this.cx,this.cy,40,140,"#ff0")
  }
}

 
<template>
<canvas id="can" width="600" height="600"></canvas>
</template>
<script>
import {onMounted} from 'vue'
import {Draw} from './draw.js'
export default {
setup(){
function pageLoad(){
let draw = new Draw('can')
draw.init(300,300)
draw.airAngle(200,20,90,'#ff0',false)
draw.airAngle(200,150,290,'#ff8',false)
draw.mousemoveInit((x, y,ang)=>{
console.log(x, y,ang)
})
}
onMounted(() =>{
pageLoad()
})
} }
</script>

得到了这样的效果

鼠标滑到 对应的区域,将返回该点的坐标 和角度

使用canvas 根据角度画圆弧的更多相关文章

  1. 有趣html5(两)----使用canvas结合剧本画在画布上的简单图(html5另一个强大)

    请珍惜劳动小编成果,这篇文章是原来小编,转载请注明出处. 于html5中能够使用canvas标签在画布上绘图,先直接上代码,这篇文章先简介一下canvas的用法.简单画几个圆,矩形,三角形,写字. 在 ...

  2. UIBezierPath画圆弧的记录

    UIBezierPath通过 - (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)s ...

  3. Canvas中如何画一条清晰的线宽为奇数(如1px逻辑像素)的线?

    我在开发中使用canvas的机会不是很多,但是第一次实际使用中就遇到了问题,"很久很久以前,我自己画了一个雷达图,线宽都是1像素,但是显示效果不如期望,这才发现canvas中的画线还是有坑的 ...

  4. IOS 绘制基本图形( 画圆、画线、画圆弧、绘制三角形、绘制四边形)

    // 当自定义view第一次显示出来的时候就会调用drawRect方法- (void)drawRect:(CGRect)rect { // 1.获取上下文 CGContextRef ctx = UIG ...

  5. KiCad EDA 画圆弧

    KiCad EDA 画圆弧 看起来像是成功了. KiCad 画圆弧一直没有完善解决,但是 KiCad 一直有在努力.

  6. 关于 KiCad 画圆弧走线

    关于 KiCad 画圆弧走线 有很多关于 关于 KiCad 画圆弧走线的帖子. 最新进展是 V6 在开发中. 但是因为关于 DRC 问题,开发好像有难度. https://bugs.launchpad ...

  7. canvas入门(画圆)

    1.想在H5上画一个canvas,必须在页面上你需要的地方添加canvas标签, <canvas id="myCanvas"></canvas>   接着需 ...

  8. Html5新特性 &lt;canvas&gt;画板画直线

     以下样例为用canvas标签画多条直线 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" & ...

  9. 用HTML5 Canvas做一个画图板

    使用HTML5可以非常简单地在canvas上实现画图应用,用支持html5的浏览器便可在下面的区域进行绘画,要看到演示效果,请确保你的浏览器支持HTML5: 功能很简单,原理其实和拖放是类似的,主要是 ...

随机推荐

  1. Maven中使用ssm框架出现:org.apache.tomcat.util.modeler.BaseModelMBean.invoke 调用方法[manageApp]时发生异常

    org.apache.tomcat.util.modeler.BaseModelMBean.invoke 调用方法[manageApp]时发生异常 首先可以排查一下像: @RequestMapping ...

  2. 在 C# CLR 中学习 C++ 之了解 extern

    一:背景 在 CLR 源码中有很多的 extern 和 extern "C" 这样的关键词,比如下面这些代码: extern size_t gc_global_mechanisms ...

  3. docker 匿名和具名挂载

    匿名挂载,只指定容器内了,没指定容器外 -v 容器内路径 docker run -d -P --name nginx01 -v /etc/nginx nginx #-P 随机映射端口 ; -v 不指定 ...

  4. windows清理必看

    清理缓存 代码如下 介绍此文件夹都是缓存文件全选删除即可 ctrl+A全选shift+del强制删除(不会添加到回收站) %temp% 找到C盘右击属性选择想要删除的文件进行清理即可 清理完点击清理系 ...

  5. Java SE 6、super关键字,包

    1.super关键字 super代表父类的引用,用于访问父类的属性,方法,构造器 super可以访问父类的属性,但不能访问父类的 private 属性 super.属性名; 可以访问父类的方法,不能访 ...

  6. typora收费了,最后一个免费版提供下载

    typora收费了,在这里,博主提供最后一个免费版下载,地址如下,顺便把typora导入和导出word时需要的工具也一同提供.最看不惯免费用着别人的软件,还搞引流的垃圾网站和公众号.地址如下 http ...

  7. Mysqldump 的 的 6 大使用场景的导出命令

    Mysqldump 选项解析 场景描述 1. 导出 db1.db2 两个数据库的所有数据. mysqldump -uroot -p -P8635 -h192.168.0.199 --hex-blob ...

  8. Elasticsearch:如何把Elasticsearch中的数据导出为CSV格式的文件

    本教程向您展示如何将数据从Elasticsearch导出到CSV文件. 想象一下,您想要在Excel中打开一些Elasticsearch中的数据,并根据这些数据创建数据透视表. 这只是一个用例,其中将 ...

  9. CentOS7使用yum方式安装Containerd

    # 安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的 yum install -y yum-utils device-m ...

  10. Beats:Beats 入门教程 (二)