美文网首页canvas
canvas绘制仪表盘

canvas绘制仪表盘

作者: 谢炳南 | 来源:发表于2020-09-28 21:31 被阅读0次

效果图

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();

相关文章

网友评论

    本文标题:canvas绘制仪表盘

    本文链接:https://www.haomeiwen.com/subject/ypvjuktx.html