canvas锥形渐变进度条
从一个渐变圆角进度条浅出画一个圆
开始
这一切需要从一个(简单)的需求开始,在最开始对设计第一眼看到这张图的时候,感觉挺简单的嘛,直接用echarts饼图模拟出来一个就好了

echarts
然后上echarts试了一下发现实现不出来了

设计图这边采用的是锥形渐变,而echarts只有线性渐变和径向渐变。
css
然后准备换种方案,css就有锥形渐变,然后通过conic-gradient加上mask画出了一个渐变的环形然后可以再通过剪裁实现出进度的展示。
但是存在两个问题,一个是conic-gradient属性兼容性不好ie和火狐都不支持,二个是后来发现了还存在一个需求进度条的两端需要有圆角,然后这种实现方式就不行了。
其实在写这篇文章的时候才想到一个方法就是在两端加上两个半圆形,不过得计算半圆形的位置。
Canvas & SVG
在我的理解中在页面上作图总共有四种方式。
- dom+css
- Canvas
- SVG
- WebGL
WebGL是一头雾水还是试试Canvas和SVG吧,因为更熟悉Canvas一些,我这边就采用Canvas来试试。
Canvas可以轻松的实现圆角和环形,但是他的api里面居然没有锥形渐变
然后就想着尝试手动来实现一个锥形渐变,然后查阅资料看到了一篇文章手把手教你画圆锥渐变,就是相当于画圆嘛,我们可以通过一条线一条线的画从而画出一个圆,然后把两端渐变的颜色通过计算找到中间画圆的每一条线的颜色组合起来就是一个渐变的效果了。
然后问题就是给你两个色值怎么计算中间的线段的颜色,其实对于rgba的颜色我们可以看到他是由四个数字组成的,那我把这四个数字分别求出四组长度相同且组内间隔相同的中间值那就可以得到颜色的中间值了,然后在搭配上张老师硬核的色值转换JS HEX十六进制与RGB,HSL颜色的相互转换那就可以实现出我们想要的效果了。
通过一个开始颜色和一个结束颜色,默认是rgba的颜色,num是分段数,就可以求出中间每一段的颜色了
// 把颜色分段
const beginColor = begin.slice(5, -1).split(',').map(item => Number(item))
const endColor = end.slice(5, -1).split(',').map(item => Number(item))
// 分段后的颜色储存在这个数组
const middleColor = [[], [], [], []]
// 循环rgba四种
beginColor.forEach((item, index) => {
// 当前的值每段颜色之间的间隔
const differ = (endColor[index] - item) / (num - 1)
// 循环分段数的次数
for(let i = 0; i< num; i++) {
// 每次加上这个间隔
middleColor[index].push((item + differ * i).toFixed(2))
}
})
console.log(middleColor)
console.log(num)
然后绘制的话就是一段一段的画了,麻烦的地方就是计算每次从多少的角度画到多少的角度
for(let i = 0; i< num; i++) {
ctx.beginPath()
// 这里是每次绘制的过程
// 每次绘制一段小圆弧
// 最后一段只需要画一段就好
if(i === num - 1)
ctx.arc( 150 * dpr,150 * dpr, 100 * dpr, (Math.PI * 2 * value) / num * i, (Math.PI * 2 * value) / num * (i + 1));
else
ctx.arc( 150 * dpr,150 * dpr, 100 * dpr, (Math.PI * 2 * value) / num * i, (Math.PI * 2 * value) / num * (i + 2));
ctx.lineWidth = 60;
// ctx.lineCap = "round";
ctx.strokeStyle= `rgba(${middleColor[0][i]}, ${middleColor[1][i]}, ${middleColor[2][i]}, ${middleColor[3][i]})`;
ctx.stroke();
ctx.closePath()
}
结果非常的顺利,就是自己想要的结果,具体怎么一段一段的画,怎么求出颜色的中间值看这里
优化
其实把绘制的过程放慢看

就是这个过程,每次画一段,每段不同的颜色组合起来就是一个渐变色,然后分段数再加多一点就会靠上去很流畅。
在完成后发现了几个问题,首先是在分段数很少的时候就会出现一块一块的间隔

就像这样,我大概分析了一下,猜测这个间隔出现的原因应该是我计算每一段的角度的时候肯定有除不尽的,我就四舍五入了,应该就会产生一些小间隔。
然后我就觉得把分段数提高应该就会好一些,然后就发现分段数高间隔会生成类似于摩尔纹的东西

然后就开始思考怎么去消除,最后想到了一种方案就是在每次绘制的时候绘制两段的长度,然后移动只移动一段的长度,就会下一段覆盖在上一段,就不会有间隔了,然后颜色渐变也还是一段一段的不会有影响。

然后还有一个问题就是有锯齿,不清楚,解决方案也很简单,就是把你的画布放大指定倍数,然后半径也放大同样的倍数,最后dom的高宽不变,就会让绘制的图形更加的清晰。
总结
到此这个问题就算是解决了,然后我还顺便写了一个库,大家有兴趣的可以去使用一下,我还加上了数字,动画也可以支持多段渐变gradient-ring-progress
通过这次的需求我收获到了,做东西需要完全的去了解了需求再去确定实现方案然后再动手,实现方案其实有非常多种,我们需要找到的是最合适的解决方案。最后抄袭张老师的一句话
然而一个人的积累总是有限,而创意总是无限的,因此一定还有其他更好更妙更简单的实现,欢迎分享欢迎指教!
参考资料
canvas锥形渐变进度条的更多相关文章
- 自定义控件之圆形颜色渐变进度条--SweepGradient
前几天在群里面有人找圆形可颜色渐变进度条,其中主要的知识点是SweepGradient: mSweepGradient = new SweepGradient(240, 360, new int[] ...
- html5 canvas绘制环形进度条,环形渐变色仪表图
html5 canvas绘制环形进度条,环形渐变色仪表图 在绘制圆环前,我们需要知道canvas arc() 方 ...
- 【iOS】环形渐变进度条实现
之前有人在找渐变进度条的效果,闲来无事就顺手写了一个,然后画了视图层级,方便讲解. 环境信息: Mac OS X 10.10.3 Xcode 6.3.1 iOS 8.3 效果图: 源码下载地址: ht ...
- canvas绘制圆形进度条(或显示当前已浏览网页百分比)
使用canvas绘制圆形进度条,或者是网页加载进度条 或者是显示你浏览了本网页多少-- 由于个浏览器的计算差异,打开浏览器时 初始值有所不同,但是当拉倒网页底部时,均显示100%. 兼容性:测试浏览器 ...
- Canvas实现环形进度条
Canvas实现环形进度条 直接上代码: <canvas width="200" height="200" >60%</canvas> ...
- iOS圆弧渐变进度条的实现
由于项目需要一个环形渐变进度条显示课程,这方便网上的确有很多相关资料但是,都是比较零散的而且,大多数只是放一堆代码就算完了.这里我想详细写一篇我自己实现这个进度条的过程. 实现一个圆弧进度条主要分为三 ...
- android自己定义渐变进度条
项目中须要用到一个弧形渐变的进度条,通过android自带是不能实现的.我是没有找到实现的方法,有大神知道的能够指点.效果图是以下这种 这是通过继承VIew来绘制出来的,网上也有相似的,可是代码那是相 ...
- iOS 渐变进度条
#import <UIKit/UIKit.h> @interface JianBianView : UIView //为了增加一个表示进度条的进行,可们可以使用mask属性来屏蔽一部分 @ ...
- canvas绘制环形进度条
<!DOCTYPE html> <html > <head> <meta http-equiv="content-type" conten ...
随机推荐
- python requests 接口测试
1.get方法请求接口 url:显而易见,就是接口的地址url啦 headers:请求头,例如:content-type = application/x-www-form-urlencoded par ...
- 大富翁 线段树+二分 +dfs
https://csustacm.fun/problem/2033 这个题目还是比较简单的,但是比赛的时候没有像清楚,用了一个不太熟悉的数据结构主席树, 所以出现了bug,主席树的bug是真的难找. ...
- tp5中提示错误A non well formed numeric value encountered
问题因为自动完成时间导致的 原来我的数据库是这样的 修改成下面这样就好了
- HC32F003C4PA GPIO Output
1.打开启动文件,找到并跳转至SystemInit函数 void SystemInit(void) { stc_clk_systickcfg_t stcCfg; // TODO load trim f ...
- 【Hadoop离线基础总结】CDH版本的zookeeper环境搭建
CDH版本的zookeeper环境搭建 下载 下载地址 http://archive.cloudera.com/cdh5/cdh/5/ 修改配置文件 创建ZooKeeper数据存放目录 mkdir - ...
- RHCSA 第一题 修改root密码
题目要求 请修改系统的root帐号密码为redhat,确保能够使用root帐号登录系统.说明:server0 的IP为172.25.0.11/24desktop0的IP为172.25.0.10/24 ...
- flink优化总结
一.高性能Flink SQL优化技巧 1.Group Aggregate优化技巧 开启MicroBatch或MiniBatch(提升吞吐) MicroBatch和MiniBatch都是微批处理,只是微 ...
- Codeforces 832D(Misha, Grisha and Underground,LCA)
题意:在一棵生成树上,给出了三个点,求三个点之间最大的相交点数,CF难度1900. 题解:求出三个lca,并取深度最大的那个,就是我们要的三岔路口K,然后分别求出K到a,b,c三点的路径长度,取最大值 ...
- 你了解C#的协变和逆变吗
从C# 4.0开始,泛型接口和泛型委托都支持协变和逆变,由于历史原因,数组也支持协变. 里氏替换原则:任何基类可以出现的地方,子类一定可以出现. 协变(out) 协变:即自然的变化,遵循里氏替换原则, ...
- 浅谈产品模型(Profile)在程序设计中的作用
引言:物联网平台的一个重要功能就是资产管理,产品或者设备都可以看成是资产中组成部分,所以有时候说物联网平台可以进行产品管理和设备管理.通常应用物联网平台开发一套具有产品或者设备管理功能的系统的时候,必 ...