美文网首页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