效果图
![](https://img.haomeiwen.com/i7645970/abcae0725884d53f.gif)
yym3g-438y3.gif
html添加canvas
<canvas id="canvas" width="400" height="250"></canvas>
js获取canvas
let canvas = document.getElementById('canvas');
this.ctx = canvas.getContext("2d");
this.circleX = canvas.width / 2; // 中心x坐标
this.circleY = 150; //中心y坐标
定义方法绘制圆环
/**
* 画圆环
* @param r {number} 圆环的半径
* @param w {number} 圆环的宽度
* @param c {string} 圆环的颜色
* @param angle {string} 圆环所到的角度 默认180度,半圆
*/
circle(r,w,c,angle=180){
let ctx = this.ctx;
// 画布将当前的状态保存
// canvas.save();与canvas.restore();一般结合使用,.save()函数在前,.restore()函数在后,
// 用来保证在这两个函数之间所做的操作不会对原来在canvas上所画图形产生影响
ctx.save();
// 开始一条路径,或重置当前的路径
ctx.beginPath();
// 设置线条的宽度
ctx.lineWidth = w;
// 设置线条的颜色
ctx.strokeStyle = c;
// 线条末端线帽的设置为圆形
ctx.lineCap = 'round';
// 方法创建弧/曲线(用于创建圆或部分圆)
ctx.arc(this.circleX, this.circleY, r, Math.PI, Math.PI * (1+angle/180));
ctx.stroke();
// 画布取出原来所保存的状态
ctx.restore();
},
绘制刻度线
/**
* 绘制刻度线
* @param s {number} 弧度所对应的角度
* @param span {number} 弧度间隔
* @param sl {number} 刻度线以圆心为半径的起始半径
* @param el {number} 刻度线以圆心为半径的结束半径
* @param c {string} 刻度线的颜色
*/
scale(s,span,sl,el,c){
let ctx = this.ctx;
let startA = s;
for(let i = 0; i < span; i++){
ctx.save();
ctx.beginPath();
let rad = startA * 15 * Math.PI /180;
let startX = 200 - Math.cos(rad)*sl;
let startY = 150 - Math.sin(rad)*sl;
let endX = 200 - Math.cos(rad)*el;
let endY = 150 - Math.sin(rad)*el;
// 路径移动到画布中的指定点,不创建线条
ctx.moveTo(startX, startY);
// 添加一个新点,然后创建从该点到画布中最后指定点的线条(该方法并不会创建线条)
ctx.lineTo(endX, endY);
ctx.strokeStyle = c;
// 方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
ctx.stroke();
ctx.restore();
startA ++;
}
},
绘制文字
/**
* 绘制文字
* @param text {string} 文字的内容
* @param x {number} 文字的x坐标轴
* @param y {number} 文字的y坐标轴
* @param c {string} 刻度线的颜色
* @param fontSize {number} 刻度线以圆心为半径的结束半径
*/
fillText(text,x,y,color="#333",fontSize="18"){
let ctx = this.ctx;
ctx.save();
// 根据锚点,设置或返回文本内容的当前对齐方式 水平方向
ctx.textAlign = 'center';
// 设置或返回在绘制文本时的当前文本基线 垂直方向
ctx.textBaseline = 'middle';
// 设置或返回画布上文本内容的当前字体属性
ctx.font= fontSize +"px Arial";
ctx.fillStyle = color;
// 在画布上绘制填色的文本
ctx.fillText(text,x,y);
ctx.restore();
}
绘制圆
/**
* 绘制圆
* @param x {number} 圆心的x坐标轴
* @param y {number} 圆心的y坐标轴
* @param r {number} 圆的半径
* @param fillColor {string} 圆所填充的颜色
* @param lineWidth {number} 圆的宽度
*/
round(x,y,r,fillColor="#fff",lineWidth=3){
let ctx = this.ctx;
ctx.save();
ctx.beginPath();
ctx.lineWidth = lineWidth;
ctx.strokeStyle = '#7775FD';
ctx.arc(x, y, r, 0, Math.PI * 2, false);
ctx.fillStyle = fillColor;
// 填充当前的图像(路径)。默认颜色是黑色
ctx.fill();
ctx.stroke();
ctx.restore();
},
绘制三角形
/**
* 画三角形
* @param angle {number} 弧度所对应的角度
*/
triangle(angle){
let ctx = this.ctx;
ctx.save();
ctx.beginPath();
ctx.lineWidth = 1;
let rad = angle * Math.PI /180;
let startX = this.circleX - Math.cos(rad)*40;
let startY = this.circleY - Math.sin(rad)*40;
ctx.moveTo(startX, startY);
let rad1 = (90 - angle) * Math.PI /180;
let startX1 = this.circleX - Math.cos(rad1)*11;
let startY1 = this.circleY + Math.sin(rad1)*11;
ctx.lineTo(startX1, startY1);
let rad2 = (90 - angle) * Math.PI /180;
let startX2 = this.circleX + Math.cos(rad2)*11;
let startY2 = this.circleY - Math.sin(rad2)*11;
ctx.lineTo(startX2, startY2);
ctx.closePath();
ctx.fillStyle = "#8382FF";
ctx.fill();
ctx.strokeStyle = "#8382FF";
ctx.stroke();
ctx.restore();
},
绘画图形
/**
* 绘制图形
* @param angle {number} 角度
*/
draw(angle){
this.ctx.clearRect(0, 0, this.circleX * 2, this.circleY * 2);
this.circle(120,8,"#F8F8F8");
this.circle(100,2,"#BBBAFF");
this.circle(80,12,"#F2F2F2");
this.circle(50,2,"#F8F8F8");
this.circle(30,2,"#F8F8F8");
this.scale(0,13,65,62,"#F2F2F2");
this.scale(0.5,12,65,58,"#F2F2F2");
this.fillText("正常",40,150);
this.fillText("警告",200,10);
this.fillText("高危",360,150);
this.fillText("风险项",200,180,"#9A9A9A","16");
this.fillText("企业经营正常,风险系数低",200,200,"#62C513","12");
this.round(100,150,4);
this.round(200,50,4);
this.round(300,150,4);
this.round(200,150,10,"#8382FF",1);
if(angle > 0){
this.circle(80,12,"#7775FD",angle);
}
this.triangle(angle);
this.round(200,150,4);
},
设置定时器
timer(){
setTimeout(()=>{
this.angle++;
if(this.angle < 90){
this.draw(this.angle);
}else if(this.angle < 150){
this.draw(180 - this.angle);
}else if(this.angle < 165){
this.draw(this.angle - 120);
}else if(this.angle > 170){
return
}
this.timer();
},20)
},
最后调用定时器方法即可
this.draw(0);
this.timer();
网友评论