摘要:根据项目要求,要实现这样一个仪表盘的效果拿到图之后首先做一个拆分,分成几个小模块。其中是圆心角度数,是半径,是圆心角弧长。
根据项目要求,要实现这样一个仪表盘的效果:
拿到图之后首先做一个拆分,分成几个小模块。从里往外看,首先需要一个内环的刻度条,这个内环刻度条由若干个点构成,所以我的实现方式为:先画一根线,通过循环,旋转得到一个圆形的刻度条
//innerLineNums 为刻度数量 ctx.save(); for (var i = 0; i <= $this.innerLineNums; i++) { ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = "rgba(155,157,183,1)"; ctx.moveTo(82, 0); ctx.lineTo(80, 0); ctx.stroke(); //每个点的弧度,360°弧度为2π,即旋转弧度为 2π / 75 ctx.rotate(2*Math.PI / $this.innerLineNums); } ctx.restore();
其次再是里面的长刻度线,以及数字标志,还有中间的文字
// 内环刻度线 ctx.save(); for (var i = 0; i < 6; i++) { ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = "rgba(155,157,183,1)"; ctx.moveTo(82, 0); ctx.lineTo(78, 0); ctx.stroke(); //每10个点分一个刻度,共5个刻度,旋转角度为deg1 * 10 ctx.rotate(deg1 * 10); } ctx.restore(); //内环刻度上面数字 ctx.save(); ctx.rotate(Math.PI / 2); for (i = 0; i < 6; i++) { ctx.fillStyle = "rgba(165,180,198, .4)"; ctx.font = "10px Microsoft yahei"; ctx.textAlign = "center"; ctx.fillText(20 * i, 0, -65); ctx.rotate(deg1 * 10); } ctx.restore(); //内环文字 ctx.save(); ctx.rotate(210 * Math.PI / 180); ctx.fillStyle = "#000"; ctx.font = "44px Microsoft yahei"; ctx.textAlign = "center"; ctx.textBaseLine = "top"; ctx.fillText(process, 0, 10); var width = ctx.measureText(process).width; ctx.fillStyle = "#000"; ctx.font = "20px Microsoft yahei"; ctx.fillText("分", width / 2 + 10, 10);
好了,此时内环的效果已经有了,可以看到如下效果:
再来看外环的刻度条,外环刻度条有一个缺口,目测估算一下,算缺口为1/3,即外环的刻度线需要画120-360°,我们这里分数满分为100分,从0开始,为了方便计算就给他画50根刻度线,那么每根刻度线的角度deg1的算法为:
//弧长计算公式是一个数学公式,为L=n(圆心角度数)× π(1)× r(半径)/180(角度制),L=α(弧度)× r(半径) (弧度制)。其中n是圆心角度数,r是半径,L是圆心角弧长。 //整个运动的角度是(360-120)度,转换成弧度就是12π/9,一共分成了50个分数段,那么每一个分数段就是12π/450 = 2π / 75 //如需旋转 5 度,可规定下面的公式:5*Math.PI/180。 deg1() { return (Math.PI * 12) / (9 * this.lineNums) }
从这里我们知道了外环2/3个圆的刻度线为50根,那么内环整个圆的刻度线innerLineNums = 50 * 3 / 2 = 75根。好了,知道角度之后还是按照之前的方法,画一根线,然后循环,在旋转,跳跃画出灰色的外环刻度线:
// 细分内环刻度线 ctx.save(); for (var i = 0; i <= $this.innerLineNums; i++) { ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = "rgba(155,157,183,1)"; ctx.moveTo(82, 0); ctx.lineTo(80, 0); ctx.stroke(); //每个点的弧度,360°弧度为2π,即旋转弧度为 2π / 75 ctx.rotate(2 * Math.PI / $this.innerLineNums); } ctx.restore();
这个时候效果是这样的:
还差外环的渐变线,以及线上面的那个点,那根线是根据分数动态画的,所以长度需要计算,我打算用一个圆弧来实现,上面说过每个线之间的旋转弧度为deg1,那圆弧的长度就等于score * deg1 / 2,根据公式画出线如下:
//色彩段数与彩色刻度条保持一致,线条无间隔,所以段数 * 2 var gradient = ctx.createLinearGradient(0, 0, $this.colorLineNums * 2, 0); gradient.addColorStop("0", "rgba(252,3,44,.6)"); gradient.addColorStop("0.5", "rgba(134,37,168,.6)"); gradient.addColorStop("1.0", "rgba(54,63,255,.6)"); //外环渐变线 ctx.save(); ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = gradient; ctx.arc(0, 0, radius, 0, angle, false); ctx.stroke(); ctx.restore();
此时效果是这样的:
还有圆外环彩线上面的圆点,可以用一个小圆实现,然后改变他的x,y坐标即可实现:
ctx.save(); ctx.beginPath(); ctx.fillStyle = "rgba(255, 255, 255, 1)"; ctx.arc(this.x, this.y, 5, 0, Math.PI * 2, false); ctx.fill(); ctx.lineWidth = 1; ctx.strokeStyle = "rgba(246, 5, 51, 1)"; ctx.stroke(); ctx.restore(); ctx.save(); ctx.beginPath(); ctx.fillStyle = "rgba(246, 5, 51, 1)"; ctx.arc(this.x, this.y, 3, 0, Math.PI * 2, false); ctx.fill(); ctx.restore();
此时,还差个彩色的线,效果如下,额,这个彩色的线如何实现呢,刚开始也是不知如何下手,经过高人指点后,得出结局方案:把渐变色切割,多少根彩线就分割成多少份,然后感谢 嗑瓜子儿gf-颜色渐变的JS代码 写的博客,提供了算法
最终效果出来了:
预览组件
第一次写canvas组件,此代码仅供参考,最后感谢[masqli-canvas仿芝麻信用分仪表盘
][3],参考了前面两位博主的代码才能实现我项目的需求,所谓前人栽树,后人乘凉,今天把我写的也分享给大家,能帮到大家就更好,对我自己也算做个笔记了,在此再次感谢两位博主
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/99343.html
摘要:先上效果图这种图形大家应该都见过,俗称仪表盘,当然,上图只是个最基本的仪表盘架子,可能在实际场景中还会其他很多花里胡哨的点缀,那些暂且不管,不是关键,这东西经常见到,但还没亲自上手在代码层面实现过,最近做的一个需求恰好有这个场景,这里归先上效果图: showImg(https://user-gold-cdn.xitu.io/2019/5/23/16ae28a94cb51d3e); 这种图形大...
摘要:先上效果图这种图形大家应该都见过,俗称仪表盘,当然,上图只是个最基本的仪表盘架子,可能在实际场景中还会其他很多花里胡哨的点缀,那些暂且不管,不是关键,这东西经常见到,但还没亲自上手在代码层面实现过,最近做的一个需求恰好有这个场景,这里归先上效果图: showImg(https://user-gold-cdn.xitu.io/2019/5/23/16ae28a94cb51d3e); 这种图形大...
摘要:,这是一个仿支付宝芝麻信用分的一个,其实就是一个动画仪表盘。首先,上原图这个是在下支付宝上的截图,分低各位见笑了。 hi,这是一个仿支付宝芝麻信用分的一个canvas,其实就是一个动画仪表盘。 首先, 上原图: showImg(https://segmentfault.com/img/bVbn3D6?w=750&h=1334); 这个是在下支付宝上的截图,分低各位见笑了。然后看下我用c...
摘要:绘制表盘指针对指针的绘制,首先以原点为中心绘制一个圆,对延伸出来的指针思考了两种绘制方法第一种以轴左半边为例,点为起始点,以为控制点,为终点绘制三次贝塞尔曲线第二种以轴右半边为例,直接从点绘制直线到。 不知道大家童年时候有没有在手上画手表的经历,恰好最近在看 canvas ,于是就诞生了这个高仿表盘。 showImg(https://segmentfault.com/img/bV7y...
阅读 2283·2023-04-25 14:29
阅读 1427·2021-11-22 09:34
阅读 2684·2021-11-22 09:34
阅读 3371·2021-11-11 10:59
阅读 1761·2021-09-26 09:46
阅读 2186·2021-09-22 16:03
阅读 1900·2019-08-30 12:56
阅读 463·2019-08-30 11:12