canvas画一个渐变色的环形进度环

本文介绍了如何使用canvas在HTML中实现环形进度条的圆锥渐变和圆环分割渐变,通过实例代码展示了两种方法的详细步骤,并提供了相关SVG和SVG环形进度条的链接作为扩展阅读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

» 介绍

之前用canvas画了一个环形进度条,想要实现从0到100颜色渐变效果,先看效果:

在这里插入图片描述
预览地址:https://code.juejin.cn/pen/7355311802202193958


» 方法一:圆锥渐变

createConicGradient(startAngle, x, y)

startAngle:起点角度
x,y:圆锥中心点坐标

注意:createConicGradient只支持chrome99以上
在这里插入图片描述

» 代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>canvas环形进度条</title>
    <style>
      body {
        margin: 30px 0;
        text-align: center;
      }

      #canvas {
        background: #f6f6f6;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="300" height="300">您的浏览器不支持 HTML5 canvas 标签。</canvas>
    <script>
      let c = document.getElementById('canvas')
      let ctx = c.getContext('2d')
      let precent = 80,
        num = 0

        const gradient = ctx.createConicGradient(-90, 150, 150);
	    gradient.addColorStop(0, "red");
		gradient.addColorStop(1, "blue");

      function options(color, x, y, radius, start, end, order) {
        ctx.save()
        ctx.beginPath()
        ctx.lineCap = 'round'
        ctx.lineWidth = 8
        ctx.strokeStyle = color

        ctx.arc(x, y, radius, start, end, order) //x坐标,y坐标,半径,起始角,结束角,顺时针/逆时针
        ctx.stroke()
        ctx.closePath()
        ctx.restore()
      }

      //绘制文字
      function drawText(num) {
        ctx.save()
        ctx.fillStyle = '#2ba0fb'
        ctx.font = '40px Helvetica'
        ctx.textAlign = 'center'
        ctx.fillText(num + '%', 150, 160)
        ctx.restore()
      }

      //动画
      (function draw() {
        num += 1
        if (num < precent) window.requestAnimationFrame(draw)
        else num = precent
        ctx.clearRect(0, 0, 300, 300)
        options('#e5f1fa', 150, 150, 100, 0, 2 * Math.PI) //绘制轨道
        options(gradient, 150, 150, 100, -Math.PI / 2, -Math.PI / 2 + ((2 * num) / 100) * Math.PI) //绘制进度环
        drawText(num)
      })()
    </script>
  </body>
</html>

» 方法二:圆环分割

原理:把圆环分成n份,计算初始颜色到终止颜色中间n份颜色的值,每一份圆环一个颜色,从而达到渐变效果。

在这里插入图片描述


» 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>canvas环形进度条</title>
    <style>
        body {
            margin: 30px 0;
            text-align: center;
        }

        #canvas {
            background: #f6f6f6;
        }
    </style>
</head>
<body>
<canvas id="canvas" width="300" height="300">您的浏览器不支持 HTML5 canvas 标签。</canvas>
<script>
    let c = document.getElementById('canvas')
    let ctx = c.getContext('2d')
    let precent = 80, num = 0
    let startColor = '#29d6b5', endColor = '#3396c7', colorArr = [];

    ctx.fillStyle="#FF0000";

    //计算渐变色数组
    (function getColorArr() {
        let startRgb = hexToRgb(startColor)
        let endRgb = hexToRgb(endColor)

        let stepR = (endRgb[0] - startRgb[0]) / precent
        let stepG = (endRgb[1] - startRgb[1]) / precent
        let stepB = (endRgb[2] - startRgb[2]) / precent

        for (let i = 0; i <= precent; i++) {
            let hex = rgbToHex(startRgb[0] + stepR * i, startRgb[1] + stepG * i, startRgb[2] + stepB * i)
            hex = hex.length == 4 ? ('00' + hex) : hex.length == 5 ? ('0' + hex) : hex
            colorArr.push('#' + hex)
        }
    }())

    function hexToRgb(hex) {
        if (hex.length == 4)
            return [parseInt('0x' + hex.slice(1, 2).repeat(2)), parseInt('0x' + hex.slice(2, 3).repeat(2)), parseInt('0x' + hex.slice(3, 4).repeat(2))]
        else if (hex.length == 7)
            return [parseInt('0x' + hex.slice(1, 3)), parseInt('0x' + hex.slice(3, 5)), parseInt('0x' + hex.slice(5, 7))]
        else
            alert('颜色错误')
    }

    function rgbToHex(r, g, b) {
        return ((r << 16) | (g << 8) | b).toString(16)
    }

    //绘制轨道
    drawTrack()
    function drawTrack() {
        ctx.save();
        ctx.beginPath()
        ctx.lineCap = 'round'
        ctx.lineWidth = 8
        ctx.strokeStyle = '#e5f1fa'
        ctx.arc(150, 150, 100, 0, 2 * Math.PI)
        ctx.stroke()
        ctx.closePath();
        ctx.restore();
    }

    //绘制进度环
    function drawProgress(num) {
        ctx.save();
        ctx.beginPath()
        ctx.lineCap = 'round'
        ctx.lineWidth = 8
        // ctx.strokeStyle = '#2ba0fb'
        ctx.strokeStyle = colorArr[num]
        // context.arc(x,y,r,sAngle,eAngle,counterclockwise);   //x坐标,y坐标,半径,起始角,结束角,顺时针/逆时针
        ctx.arc(150, 150, 100, -Math.PI / 2 + 2 * (num - 1) / 100 * Math.PI, -Math.PI / 2 + 2 * num / 100 * Math.PI)
        ctx.stroke()
        ctx.closePath();
        ctx.restore();
    }

    //绘制文字
    function drawText(num) {
        ctx.save();
        ctx.fillStyle = '#3396c7'

        ctx.font = '40px Helvetica'
        ctx.textAlign = 'center';
        ctx.fillText(num + '%', 150, 160)
        ctx.restore();
    }

    //动画
    (function draw() {
        ctx.clearRect(85, 85, 130, 130)
        drawProgress(num)
        drawText(num)
        num += 1
        if (num <= precent)
            window.requestAnimationFrame(draw)
        else
            num = precent
    }())


</script>
</body>
</html>

相关推荐:

🚀svg画一个环形进度条:https://blog.csdn.net/qq_34241004/article/details/120550831

### 创建环形渐变加载器 在 LVGL 框架中创建一个环形渐变加载器可以通过组合 `lv_arc` 和自定义样式来实现。下面是一个详细的教程以及代码示例。 #### 准备工作 确保已经按照官方文档完成了开发环境的配置[^1],并熟悉了基本的 LVGL 控件使用方法[^4]。 #### 自定义样式设置 首先需要定义一个新的风格用于绘制带有颜色渐变效果的弧线: ```c static lv_style_t style_grad; void setup_gradient_loader(void){ lv_style_init(&style_grad); /* 设置背景属性 */ lv_style_set_bg_opa(&style_grad, LV_OPA_COVER); // 完全覆盖背景 lv_style_set_bg_color(&style_grad, lv_color_make(0xff, 0xff, 0xff));// 白色底色 /* 渐变方向是从左下角到右上角 */ lv_style_set_bg_grad_dir(&style_grad, LV_GRAD_DIR_HOR); /* 起始颜色为蓝色 */ lv_style_set_bg_main_stop(&style_grad, 0); lv_style_set_bg_color(&style_grad, lv_color_hex(0x2196F3)); /* 结束颜色为红色 */ lv_style_set_bg_grad_stop(&style_grad, 255); lv_style_set_bg_grad_color(&style_grad, lv_color_hex(0xF44336)); } ``` 此部分设置了从蓝至红水平方向上的色彩过渡效果[^2]。 #### 绘制圆形进度条 接着利用上述样式的参数去实例化一个圆弧对象作为加载指示器的核心组件: ```c /* 创建一个空白布放置arc*/ lv_obj_t *loader_canvas = lv_obj_create(lv_scr_act(), NULL); lv_obj_align(loader_canvas, NULL, LV_ALIGN_CENTER, 0, 0); /* 添加arc到canvas内 */ lv_obj_t *grad_loader = lv_arc_create(loader_canvas, NULL); lv_obj_add_style(grad_loader, LV_ARC_PART_BG, &style_grad); lv_obj_add_style(grad_loader, LV_ARC_PART_INDIC, &style_grad); // 配置arc的具体尺寸和位置 lv_area_t coords; lv_obj_get_coords(loader_canvas,&coords); int width = (coords.x2-coords.x1)/2; lv_arc_set_size(grad_loader,width*2,width*2); lv_arc_set_rotation(grad_loader,-90); // 将起点调整到顶部 lv_arc_set_value(grad_loader, 0); // 初始值设为零度 lv_obj_center(grad_loader); // 居中显示 ``` 通过这段代码,在屏幕上居中的地方会显示出一个具有指定大小、旋转角度及初始状态为空转态(`0`)的环形加载动[^3]。 #### 动态更新进度 为了让这个加载器能够动态变化,还需要编写定时回调函数不断改变其数值直到达到最大值为止: ```c static uint8_t progress = 0; static void update_progress(lv_task_param_t param){ static int dir = 1; // 方向标记变量,默认顺时针增加 if(progress >= 100 || progress <= 0) { dir *= -1; // 当到达边界时反转方向 } progress +=dir; lv_arc_set_value(param,(progress>100)?100:(progress<0)?0:progress); } // 注册任务调度器每秒调用一次update_progress() lv_task_create(update_progress, 1000 / 60 , LV_TASK_PRIO_MID, grad_loader); ``` 以上就是完整的创建过程,实现了基于LVGL框架下的环形渐变加载器功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qsya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值