zoukankan      html  css  js  c++  java
  • 基于canvas的仪表盘效果

    概述

    基于Canvas实现的仪表盘及效果。通过配置参数,可以任意修改仪表盘颜色,刻度,动画过渡时间等,满足不同场景下的使用。同时使用原生的Canvas,也是学习Canvas的很好的例子。

    详细

    一、演示效果

    仪表盘效果如下:

    gauge_demo_pic.gif

    二、项目结构截图

    1525181010416072643.png

    gauge.js文件是canvas仪表盘的主逻辑,demo.html中是使用的方法。

    注:本例子只有2个文件,如上图所示。

    三、使用方法

    在html中,加入一个canvas的元素,设置宽高为510。

    <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)

    仪表盘通过一系列的配置参数来实现各种颜色,动画时间,刻度多少等的自定义

    * 配置参数
     * 颜色配置
        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文件中

    1525181641652041379.png

    1.初始化

    首先properties中放置了所有配置的默认值。

    1525181838251009046.png

    然后将传入的配置值和默认的配置值就行合并。合并完之后进行一下初始化值的设置。

    初始化时,设置一下每一个刻度需要旋转的角度:

    总的刻度角度 / (刻度条的个数 - 1) * Math.PI / 180

    2.绘制每一帧

        // 计算一下最初始的角度,也就开始的刻度线相对于水平线的角度
        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 函数,绘制出不一样的刻度亮/暗图。

          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刻度逐渐变亮的效果。

    注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

  • 相关阅读:
    Asp.net Treeview 客户端选中效果实现 (初级)
    MYSQL生成日历表,通常在做报表的时候需要用来生成一个临时表,用来左连接等。
    写了一个抽奖类,感觉还不错,可以适合各种变化
    将系统的内部类:HttpValueCollection 移到自己的系统中,使其能方便的解析id=1&name=张三&sex=男这样的字符串参数 querystring
    指定某个文件的创建 修改 访问时间
    Reqeust["keyname"] 的读取顺序
    pku1463 Strategic game
    pku1947 Rebuilding Roads
    pku1848 Tree
    pku1056 IMMEDIATE DECODABILITY
  • 原文地址:https://www.cnblogs.com/demodashi/p/9452939.html
Copyright © 2011-2022 走看看