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

写了一小段,试试


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. Aoac唤醒的软件方案

    Aoac唤醒 这篇文章包含了Win10下的Aoac唤醒和Win11下的Aoac唤醒的不同地方,在结尾处: 从Win10时代开始,通过软件来唤醒机器是一个很常见的事情了,但是很少有文档去将如何通过AOA ...

  2. Spring 16: SM(Spring + MyBatis) 注解式事务 与 声明式事务

    Spring事务处理方式 方式1:注解式事务 使用@Transactional注解完成事务控制,此注解可添加到类上,则对类中所有方法执行事务的设定,注解添加到方法上,则对该方法执行事务处理 @Tran ...

  3. 第二十五篇:vue-cli

    好家伙,感觉好像摸到一点核心了, 什么是vue-cli? 1.vue-cli官方提供的一个脚手架,用于快速生成一个vue模板, 预先定义好目录结构以及基础代码 2.什么是脚手架? (1)做电梯井抹灰. ...

  4. Linux 更换国内源

    1.事件背景 事情起因是因为我想安装xvfb,执行sudo apt-get install xvfb发现安装报错,看报错原因是被墙导致,因为我用的默认源也没有挂代理:然后就百度,发现都是互相抄,什么换 ...

  5. dp-背包模型

    一:01背包问题模型 1 题目: 有一个箱子容量为 V,同时有 n 个物品,每个物品有一个体积(正整数). 要求 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小. 输入格式 第一行是一个整数 ...

  6. day38-IO流05

    JavaIO流05 4.常用的类04 4.4节点流和处理流03 4.4.8打印流-PrintStream和PrintWriter 打印流只有输出流,没有输入流 1.简单介绍及应用 PrintStrea ...

  7. 利用ldt_struct 与 modify_ldt 系统调用实现任意地址读写

    利用ldt_struct 与 modify_ldt 系统调用实现任意地址读写 ldt_struct与modify_ldt系统调用的介绍 ldt_struct ldt是局部段描述符表,里面存放的是进程的 ...

  8. 2021年3月-第01阶段-Linux基础-Linux系统的启动流程

    Linux系统的启动流程 理解Linux操作系统启动流程,能有助于后期在企业中更好的维护Linux服务器,能快速定位系统问题,进而解决问题. 上图为Linux操作系统启动流程 1.加载BIOS 计算机 ...

  9. Java SE 2、抽象类

    抽象类 用abstract关键字来修饰一个类时,这个类就是抽象类 ​ 访问修饰符 abstract 类名 { ​ } 用abstract关键字来修饰一个方法时,这个方法就是抽象方法 ​ 访问修饰符 a ...

  10. Django 使用cmd 创建工程

    一.Django 安装 1 通过pip安装 Django 如果你是通过升级的方式安装Django,那么你需要先卸载旧的版本. Django 提供3种发行版本,推荐使用官方的稳定版本: 你的操作系统提供 ...