使用canvas 根据角度画圆弧
最近收到一个需求,根据角度在平面上画出对应的区域,实际就是 以固定的原点,根据起始角度和结束角度和半径,画出他的区域。
写了一小段,试试
export class Draw { constructor(domId) { let canvas = document.getElementById(domId); this.initLoad = false this.canvas = canvas; this.context = canvas.getContext('2d'); } init(x,y,defaultColor='#000') { this.initLoad = true this.cx = x; this.cy = y; this.defaultColor = defaultColor } 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) callback(x, y,ang) console.log(x, y,ang); // (x, y) 就是鼠标在 canvas 单击时的坐标 ang 是角度 } }); } getAngle(x, y,ox,oy) { // 根据直角边 求角度 var radian = Math.atan(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 } lines (x1,y1,x2,y2) { // 画直线 this.context.beginPath(); this.context.moveTo(x1,y1); this.context.lineTo(x2,y2); this.context.strokeStyle = this.defaultColor; this.context.stroke(); } triangle (x1,y1,x2,y2,x3,y3,color,type) { // 画三角形 this.context.beginPath(); this.context.moveTo(x1, y1); this.context.lineTo(x2, y2); this.context.lineTo(x3, y3); this.context.lineTo(x1, y1); this.context[type + 'Style'] = color; this.context[type](); this.context.strokeStyle = color; this.context.stroke(); } air(r,sAngle,eAngle,color,flag=true) { // 画圆弧 // 传入的角度按照 顺时针计算 0度 对应 0*Math.PI 360度 对应 2*Math.PI let startAngle = 2*sAngle/360 let endAngle = 2*eAngle/360 this.context.beginPath(); this.context.arc(this.cx,this.cy,r,startAngle*Math.PI,endAngle*Math.PI,flag); this.context.fillStyle=color;//设置填充颜色 this.context.fill();//开始填充 this.context.strokeStyle = this.defaultColor; this.context.stroke(); } airAngle (r,sAngle,eAngle,color,flag=true) { // 计算链接的三角形 点的坐标 if ((eAngle-sAngle<=180)){ let angObjStart = this.mathAngle(sAngle,r) let angObjEnd = this.mathAngle(eAngle,r) this.air(r,sAngle,eAngle,color,flag) this.triangle(this.cx,this.cy,angObjStart.x,angObjStart.y,angObjEnd.x,angObjEnd.y,color,'fill') // 画起始角度 this.lines(this.cx,this.cy,angObjStart.x,angObjStart.y) // 画结束角度 this.lines(this.cx,this.cy,angObjEnd.x,angObjEnd.y) }else { let angObjStart = this.mathAngle(sAngle,r) let angObjEnd = this.mathAngle(180,r) this.air(r,sAngle,180,color,flag) this.triangle(this.cx,this.cy,angObjStart.x,angObjStart.y,angObjEnd.x,angObjEnd.y,color,'fill') this.lines(this.cx,this.cy,angObjStart.x,angObjStart.y) let angObjStart2 = this.mathAngle(180,r) let angObjEnd2 = this.mathAngle(eAngle,r) this.air(r,180,eAngle,color,flag) this.triangle(this.cx,this.cy,angObjStart2.x,angObjStart2.y,angObjEnd2.x,angObjEnd2.y,color,'fill') this.lines(this.cx,this.cy,angObjEnd2.x,angObjEnd2.y) } } }
得到了这样的效果
鼠标滑到 对应的区域,将返回该点的坐标 和角度