基于canvas的仪表盘效果
概述
基于Canvas实现的仪表盘及效果。通过配置参数,可以任意修改仪表盘颜色,刻度,动画过渡时间等,满足不同场景下的使用。同时使用原生的Canvas,也是学习Canvas的很好的例子。
详细
一、演示效果
仪表盘效果如下:
二、项目结构截图
gauge.js文件是canvas仪表盘的主逻辑,demo.html中是使用的方法。
注:本例子只有2个文件,如上图所示。
三、使用方法
在html中,加入一个canvas的元素,设置宽高为510。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <canvas width=510 height=510 id= "gauge" ></canvas> <script src= "./gauge.js" ></script> //然后配置仪表盘 var my_canvas_obj= document.getElementById( "gauge" ); var gauge2 = new Gauge({ "tick_length" : 12, "large_tick_length" : 22, "tick_thickness" : 1, "tick_group_length" : 9, "ticks_groups_begin" : 0, "total_degrees" : 250, "total_tick" : 101, "tick_color" : "#666" , "num_font_size" : 18, "percent" : 0, "center_font_size" : 172, tick_on_color: '#f1594e' , cur_score_circle_color: '#ff5e52' , center_font_color: '#ff5e52' , center_text_unit: '%' , animation_duration: 1000, "canvas" : my_canvas_obj2 }) // 绘制初始仪表盘初始值0% gauge.render() setTimeout( function (){ //绘制目标值,90% gauge.updatePercent(90) }, 1000) |
仪表盘通过一系列的配置参数来实现各种颜色,动画时间,刻度多少等的自定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | * 配置参数 * 颜色配置 tick_color: "#555962" , // 未达到的刻度颜色 tick_on_color: "#527d98" , // 已达到的刻度颜色 on_color_gradient: // 已达到的刻度颜色,渐变效果,详细参考demo中,guage1。值为Array 例如: on_color_gradient: [ { color: "#50B517" , percent: 0 // 最开始,0% }, { color: "#000000" , percent: 100 // 结束,100% }, ] on_color_gradient 设置之后,tick_on_color则不会生效 center_font_color: '#555962' , //中间数字颜色 设置为#fff-#000时,表示从左往右渐变 bg_color: // cavans的背景色 * 尺寸配置: tick_length: 80, // 短刻度长度 large_tick_length: 110, // 长刻度长度 tick_thickness: 6, //刻度条宽度 tick_group_length: 9, //每组内的短刻度个数 ticks_groups_begin: 0, //起始点 total_degrees: 240, // 刻度的总角度 animation_duration: 550, //达到目标值的动画时间 total_tick: 101, // 刻度总个数 show_num: true , // 是否展示长刻度下的数字 show_center_num: true , // 是否显示中间大的数字 center_font_size: 200, //中间数字font-size center_num_font_family: , //中间数字font-family num_gap: 1, // 每个刻度之间的间隔值,计算显示数字时需要 num_begin: 0, // 起始刻度值 num_font_size: 24, // 刻度值字体大小 num_font_family: 'HanHei SC,PingFang SC,Helvetica Neue Thin, Helvetica, STHeitiSC-Light, Arial, sans-serif' // 刻度数字font-family * 不建议随意修改的参数 tickmask_offset: 10 // 刻度值距离刻度的间隔, 单位px, center_offset: { x: 0, y: 0 }, // 中间数字上下位置的偏移 circle_radius: 5, // 刻度指示圆形的半径 circle_offset: 0 // 刻度指示距离刻度的空隙 gauge_scale: 1, // 缩放比例 |
四、代码实现过程
下面介绍canvas仪表盘的实现过程,代码逻辑位于gauge.js文件中
1.初始化
首先properties中放置了所有配置的默认值。
然后将传入的配置值和默认的配置值就行合并。合并完之后进行一下初始化值的设置。
初始化时,设置一下每一个刻度需要旋转的角度:
总的刻度角度 / (刻度条的个数 - 1) * Math.PI / 180
2.绘制每一帧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | // 计算一下最初始的角度,也就开始的刻度线相对于水平线的角度 var starting_deg = (180 - this .total_degrees) / 2; // 然后将整个画布旋转到初始角度。从左下角可是绘制 context.rotate(starting_deg * PIDEG); // 首先绘制刻度盘上指示刻度的小圆点 this ._drawScoreTipCircle( this ._halfCanvasWidth - this .circle_radius, this .circle_radius, 0); // 绘制刻度线,num_ticks 为总刻度线的条数。 for ( var i = 1; i <= num_ticks; i++) { //判断是刻度线是应该亮起来还是暗的 var is_on = (((i - 1) / num_ticks) * 100 < this ._percent); //判断是长刻度线还是短刻度线 var _isLargeTick = this ._isLargeTick(i) var tick_length = _isLargeTick ? this .large_tick_length : this .tick_length; //获取不同刻度线的颜色 var color = this ._getTickColor(is_on, i); //设置填充色 context.fillStyle = color; // 绘制刻度线,即一个长方形。 由于刻度线分长刻度线和短刻度线,而长刻度线和短刻度线因为长度不同,所以长方形的起点位置不同。 if (_isLargeTick) { // 绘制长刻度线,即一个长方形 context.fillRect(-1* this ._halfCanvasWidth + this .circle_radius * 2 + this .circle_offset, - this .tick_thickness/2, tick_length, this .tick_thickness); // 对于整数值的刻度线,旁边有一个示数,这里绘制示数 if ( this .show_num) { this ._drawGaugeNum(tick_length, i); } } else { // 绘制短刻度线 context.fillRect(-1* this ._halfCanvasWidth + this .circle_radius * 2 + this .circle_offset + this .delatLength, - this .tick_thickness/2, tick_length, this .tick_thickness); } //每画完一条,就旋转一下画布。旋转的角度 = 总的刻度角度 / (刻度条的个数 - 1) * Math.PI / 180 context.rotate( this ._rotation_deg); } // 全部绘制完之后,把前一个旧的canvas清除掉 this ._context.clearRect(0, 0, this ._canvas.width, this ._canvas.height); // 绘制新的图像 this ._context.drawImage( this .canvas, 0, 0); // 每次绘制完成后要回到画布的原始的状态 context.restore(); |
3.动画
通过上面的 render 函数,我们可以绘制出一个静态的仪表盘了。接下来我们需要让仪表盘的示数展示动起来。这里我们利用 requestAnimationFrame 函数,在函数回调中执行 render 函数,绘制出不一样的刻度亮/暗图。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | var lastUpdate = + new Date(); // 动画开始时已经亮起来的刻度的百分比 var start = this ._percent; // 目标百分比 var end = this ._target_percent; // 计算一下每毫秒我们需要完成多少百分比,然后后面每次执行时,根据经过了多少时间来计算出应该完成多少,即刻度应该亮起来多少 var change_per_ms = (end - start)/duration; var increasing = change_per_ms > 0 ? 1 : 0; // 首先计算一下所有刻度亮起来时应该是什么颜色的,保存到一个数组中。 // 后面动画过程中直接从数组中取值即可,不需要再次计算。 this .colorArray = this ._gradientColorArray(); // 更新逻辑 var update = function () { // 通过时间来计算应该完成的百分比 var now = + new Date(); var elapsed = now - lastUpdate; _this._percent += elapsed*change_per_ms; lastUpdate= now; //检测一下是否已经达到我们最终的百分比,如果达到了就停止动画;如果没有就继续绘制 if ((increasing && _this._percent < _this._target_percent) || (!increasing && _this._percent > _this._target_percent)) { _this.render(); _this._requestAnimFrame(update); } else { _this._percent = _this._target_percent; _this.render(); } }; _this._requestAnimFrame(update); |
这样我们的仪表盘就有一开始从0到100刻度逐渐变亮的效果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?