JavaScript canvas实现环形渐变进度条

最近有个需求要做环形渐变色进度条,去网上找了半天没找到合适的,大多数渐变色都是径向渐变,所以自己用canvas写了个环形渐变的图:

这个渐变其实就是把圆环分成许多小块分别绘制的,所以小块分的越多,渐变色越均匀,但是当圆环尺寸比较小的时候,边缘特别毛糙,需要适当减少份数,代码里是用unit 这个变量手动控制的,算是一个缺陷吧。

代码在此:

<!DOCTYPE html>

<html>
    <head>
        <style>
            html,body,canvas{
                width:100%;
                height:100%;
                margin:0;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas"></canvas>
    </body>
    <script>
        const canvas = document.getElementById('canvas');
        const W = document.body.offsetWidth;
        const H = document.body.offsetHeight;
        canvas.width = W;
        canvas.height = H;

        const ctx = canvas.getContext("2d");

        /*
        // percent:圆环展示的百分比(0~1)
        // startColor:开始颜色
        // endColor:结束颜色
        */
        function paint(percent,startColor,endColor){

            // 圆环起始位置,正下方
            let startAngle = Math.PI/2;
            // 圆环结束位置,一个整圆(Math.PI*2)乘以比例 + 起始位置
            let endAngle = ((Math.PI*2)*percent + startAngle);
            // 每次绘制的弧度单位,越小颜色分布越均匀,但图形较小时边缘越糙
            const unit = 0.2;
            // 根据最小弧度单位计算整个圆弧可以切成多少小份
            let division = parseInt((endAngle-startAngle)/unit,10);
            // 生成渐变色数组
            let gradient = new gradientColor(startColor,endColor,division);
            
            let start = startAngle;
            let end = start;
            for(let i=0; i<division; i++){
                ctx.beginPath();
                ctx.lineCap = "round";
                end = start+unit;
                ctx.lineWidth = 20;
                ctx.strokeStyle = gradient[i];
                ctx.arc(W/2,H/2,90,start,end);
                ctx.stroke();
                start+=unit;
            }
        }

        /*
        // startColor:开始颜色hex
        // endColor:结束颜色hex
        // step:几个阶级(几步)
        */
        function gradientColor(startColor,endColor,step){
            startRGB = this.colorRgb(startColor);//转换为rgb数组模式
            startR = startRGB[0];
            startG = startRGB[1];
            startB = startRGB[2];

            endRGB = this.colorRgb(endColor);
            endR = endRGB[0];
            endG = endRGB[1];
            endB = endRGB[2];

            sR = (endR-startR)/step;//总差值
            sG = (endG-startG)/step;
            sB = (endB-startB)/step;

            var colorArr = [];
            for(var i=0;i<step;i++){
                //计算每一步的hex值
                var hex = this.colorHex('rgb('+parseInt((sR*i+startR))+','+parseInt((sG*i+startG))+','+parseInt((sB*i+startB))+')');
                colorArr.push(hex);
            }
            return colorArr;
        }

        // 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
        gradientColor.prototype.colorRgb = function(sColor){
            var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
            var sColor = sColor.toLowerCase();
            if(sColor && reg.test(sColor)){
                if(sColor.length === 4){
                    var sColorNew = "#";
                    for(var i=1; i<4; i+=1){
                        sColorNew += sColor.slice(i,i+1).concat(sColor.slice(i,i+1));
                    }
                    sColor = sColorNew;
                }
                //处理六位的颜色值
                var sColorChange = [];
                for(var i=1; i<7; i+=2){
                    sColorChange.push(parseInt("0x"+sColor.slice(i,i+2)));
                }
                return sColorChange;
            }else{
                return sColor;
            }
        };

        // 将rgb表示方式转换为hex表示方式
        gradientColor.prototype.colorHex = function(rgb){
            var _this = rgb;
            var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
            if(/^(rgb|RGB)/.test(_this)){
                var aColor = _this.replace(/(?:(|)|rgb|RGB)*/g,"").split(",");
                var strHex = "#";
                for(var i=0; i<aColor.length; i++){
                    var hex = Number(aColor[i]).toString(16);
                    hex = hex<10 ? 0+''+hex :hex;// 保证每个rgb的值为2位
                    if(hex === "0"){
                        hex += hex;
                    }
                    strHex += hex;
                }
                if(strHex.length !== 7){
                    strHex = _this;
                }
                return strHex;
            }else if(reg.test(_this)){
                var aNum = _this.replace(/#/,"").split("");
                if(aNum.length === 6){
                    return _this;
                }else if(aNum.length === 3){
                    var numHex = "#";
                    for(var i=0; i<aNum.length; i+=1){
                        numHex += (aNum[i]+aNum[i]);
                    }
                    return numHex;
                }
            }else{
                return _this;
            }
        }

        
        paint(0.9,'#ff6464','#3586ff');

    </script>
</html>

生成渐变色的代码是网上找的,由于那个代码好多地方都能找到,也弄不清谁是原创,这里就不贴地址了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js+HTML5 canvas 实现简单的加载条(进度条)功能示例

    本文实例讲述了js+HTML5 canvas 实现简单的加载条(进度条)功能.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>www.jb51.net canvas实现加载条动画</title> </head> <body> <canv

  • JavaScript canvas绘制动态圆环进度条

    本文实例为大家分享了JavaScript canvas绘制动态圆环进度条的具体代码,供大家参考,具体内容如下 由于使用的是vue开发,所以就展示一下绘制函数好了,上图是效果图 drawMain(drawing_elem, percent, forecolor, bgcolor) {             /*                 @drawing_elem: 绘制对象                 @percent:绘制圆环百分比, 范围[0, 100]            

  • 详解JavaScript+Canvas绘制环形进度条

    目录 效果图 思考 实现思路 具体代码实现 效果图 思考 移动端的场景里经常会出现环形进度条的功能,在实现这个功能前,我预想的解决方案大致有: echarts.antv.canvas.svg 前面两种第三方提供的解决方案当然是简单,拿到案例修整一下即可,但是需要下载依赖,而且代码量不小.有没有不需要依赖第三方包,采用原生的写法,独立封装成一个组件,降低耦合,而且性能优越? 当然,那就主要介绍canvas的使用 实现思路 可以展示整个圆.半圆以及任意角度弧形(左右对称)的进度条.整体思路如下: 1

  • JS实现环形进度条(从0到100%)效果

    最近公司项目中要用到这种类似环形进度条的效果,初始就从0开始动画到100%结束.动画结果始终会停留在100%上,并不会到因为数据的关系停留在一半. 如图 代码如下 demo.html <!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content=

  • js实现进度条的方法

    本文实例讲述了js实现进度条的方法.分享给大家供大家参考.具体实现方法如下: 1.setTimeout和clearTimeout <html> <head> <title>进度条</title> <style type="text/css"> .container{ width:450px; border:1px solid #6C9C2C; height:25px; } #bar{ background:#95CA0D; f

  • JavaScript实现可动的canvas环形进度条

    目录 介绍 1.创建canvas元素 2.绘制的准备工作 3.绘制环形底层 4.绘制进度层 5.绘制字体并指定位置 6.进度动画 介绍 今天分享一个环形进度条的写法,当然这只是一个可动的静态进度条,如果你喜欢可以加入后台数据.这种进度条非常简单的写法到处都有,只不过更多的只是写个样子,咱们这个可以动哟. 前提是canvas的属性.方法和一些基础的js API你都知道,当然为了保证一些忘记的小伙伴一下想起来,我会在前面列个表. 属性和方法 描述 getContext() 返回一个用于在画布上绘图的

  • js实现增加数字显示的环形进度条效果

    效果如下: 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <link> <meta name="page-view-size" content="640*530"> <meta http-equiv="Content-Type" content="text/

  • javascript 进度条的几种方法

    我们先看看最终效果: 第一步,基本 构建基本的代码,看效果演示: 制作进度条的两种方法 *{ margin:0; padding:0; } body{font-size:12px;}h1{font-size:15px;} .wrap{ font-size: 12px; margin:40px auto; width:400px; } /*进度条样式*/ .progressbar_1{ background-color:#eee; height:16px; width:150px; border:

  • JavaScript canvas绘制圆形加载进度条

    本文实例为大家分享了JavaScript canvas绘制圆形加载进度条的具体代码,供大家参考,具体内容如下 1.需求:通过canvas绘制一个圆形的进度条 2.实现思路: 2.1 绘制灰色底框 2.2 创建变量保存结束角度值和加载进度值 2.3 创建定时绘制进度条 2.3.1 修改结束角度2.3.2 开始新路径绘制2.3.3 绘制加载圆环 3.实现过程如下: css样式设置 body {             text-align: center;         }         can

  • 环形加载进度条封装(Vue插件版和原生js版)

    本文实例为大家分享了环形加载进度条封装代码,供大家参考,具体内容如下 1.效果预览 2.用到的知识 主要利用SVG的stroke-dasharray和stroke-dashoffset这两个属性. 在看下面文章之前,你需要了解 <!DOCTYPE html> <html> <head> <title>svg demo</title> <style type="text/css"> #line{ transition

随机推荐