zoukankan      html  css  js  c++  java
  • H5 可堆叠的圆环进度条,支持任意数量子进度条

    by Conmajia
    SN: S22-W1M

    由来

    看到一篇帖子《vue实用组件——圆环百分比进度条》,让我想起了很多年前我在WinForm下仿制过的Chrome进度条。

    ▲ 原版进度条

    那时候我经常半夜接着酒劲儿用我的小破电脑跟GDI+ 较真儿,一转眼都快10年了。这日子过得还真是让人唏嘘呢。本来想翻出来纪念一下,可是以前的东西早他妈不知扔哪儿了,有点儿遗憾。再看看上边儿那进度条是Vue的,我现在还没本事玩儿,可是又手痒痒,先用H5做一个凑合吧。反正也是打发时间,少打几圈儿麻将呗。

    特性 & Demo

    说实在的,单进度条非做一圆,别的屁功能没有,真的没意思,不如来点儿添头,把一堆进度条都给揉里边儿。我相信一定有人能用上,别客气。

    1. 可以堆叠任意数量子进度条
    2. 计算总进度
    3. 原生H5
    ▲ 新版进度条(静态演示)

    最后的效果就上边儿那图的把式。如果你的浏览器支持H5,那么你应该可以看到下面这个动态演示。你可以点击按钮试试看用在网页上的实际效果。

    准备中…
    亲手试试:
     
    ▲ 新版进度条(实时演示,需要浏览器支持)

    代码

    全是基础的东西。

    非常简单,略去了一些不重要的东西(我讨厌整页整页都是代码的文章)。最最基础的H5动画,没啥可说的,我写了点儿注释。

    // ctx 为 canvas context
    var ctx = g.getContext('2d');
    // (x, y) 中心点
    var x = g.width / 2, y = g.height / 2;
    // p 保存所有子进度条,value 0-100%
    var p = [{
      value: 0,
      color: 'orange'
    }, 
    ...
    {
      value: 0,
      color: 'blue'
    }];
    
    // 演示专用(略):随机更新各个进度条 value,模拟走进度
    function inc(a) {
    ...
    }
    
    // 计算总进度
    function getTotal(a) {
      var t = 0;
      for(var i = 0; i < a.length; i++) {
        t += a[i].value;
      }
      return t / a.length;
    }
    
    // 画圆环。start、stop 起止点,以 scale 划分 360 度
    function drawBand(start, stop, color = 'silver', scale = 100) {
      var div = Math.PI * 2 / scale;
      ctx.save();
      ctx.strokeStyle = color;
      ctx.lineWidth = 30;
      ctx.beginPath();
      ctx.arc(x, y, 100, start * div, stop * div, false);
      ctx.stroke();
      ctx.closePath();
      ctx.restore();
    }
    
    // 画所有子进度条
    function drawProg(a) {
      for (var i = 0; i < a.length; i++) {
        var s = 0;
        // 计算起点
        for (var j = 0; j < i; j++) {
          s += a[j].value;
        }
        s /= a.length;
        drawBand(s, s + a[i].value / a.length, a[i].color);
        s = s + a[i].value;
      }
    }
    
    // 中心总进度文字
    function drawLabel(n) {
    ...
    }
    
    // 动画循环
    (function drawFrame() {
      window.requestAnimationFrame(drawFrame);
      ctx.clearRect(0, 0, g.width, g.height); // 清空绘图区
      drawBand(0, 100); // 画底环(0-100 刻度,默认色)
      drawLabel(total(p)); // 画进度文字
      drawProg(p); // 画所有进度条
      inc(p); // 模拟更新,演示专用
    }());
    

    代码就这么简单。老实说,其实这挺无聊的,bootstrap自带的进度条就能堆叠(当然那个是直线型的);随便用个Chart.js、ECharts.js,也能轻轻松松实现这个效果,比这好上一万倍

    ▲ 一个ECharts的例子

    まあ,就当练手了呗,反正我的H5连门儿都还没入,弄出来也算熟悉熟悉,挺好的。

    The End. (Box)

    var c = ['Navy', 'Blue', 'Aqua', 'Teal', 'Green', 'Lime', 'Yellow', 'Orange', 'Red', 'Maroon', 'Fuchsia']; var auto = true; var g = document.getElementById('canvas1'); var ctx = g.getContext('2d'); var x = g.width / 2; var y = g.height / 2; var rad = Math.PI * 2 / 100; var p = [{ speed: 0.2, value: 0, color: 'orange' }, { speed: 0.1, value: 0, color: 'blue' }, { speed: 0.2, value: 0, color: 'green' }, { speed: 0.4, value: 0, color: 'red' }]; $('#add').click(function(e) { e.preventDefault(); auto = true; add(); }); $('#remove').click(function(e) { e.preventDefault(); auto = true; remove(); }); $('#shuffle').click(function(e) { e.preventDefault(); auto = true; shuffle(); }); function add() { p.push({ speed: Math.random(), value: 0, color: c[Math.floor(Math.random() * (c.length))] }); } function remove() { p.pop(); } function shuffle() { for (var i = 0; i < p.length; i++) { p[i].value = Math.floor(Math.random() * 100); p[i].speed = Math.random(); } p=_.shuffle(p); } function inc(a) { if (!auto) return false; for (var i = 0; i < a.length; i++) { if (a[i].value <= 100) a[i].value += a[i].speed; } if (total(a) >= 100) { for (var i = 0; i < a.length; i++) { a[i].value = 0; } } } function total(a) { var t = 0; for (var i = 0; i < a.length; i++) { t += a[i].value; } return t / a.length; } function draw(s, l, p) { ctx.save(); ctx.strokeStyle = p.color; ctx.lineWidth = 30; ctx.beginPath(); ctx.arc(x, y, 100, Math.PI / 2 + s * rad, Math.PI / 2 + (s + p.value / l) * rad, false); ctx.stroke(); ctx.closePath(); ctx.restore(); } function drawProg(a) { for (var i = 0; i < a.length; i++) { var s = 0; for (var j = 0; j < i; j++) { s += a[j].value; } s /= a.length; draw(s, a.length, a[i]); s = s + a[i].value; } } function drawBand() { ctx.save(); ctx.lineWidth = 30; ctx.strokeStyle = "silver"; ctx.beginPath(); ctx.arc(x, y, 100, 0, Math.PI * 2, false); ctx.stroke(); ctx.closePath(); ctx.restore(); } function drawLabel(n) { ctx.save(); ctx.strokeStyle = "silver"; ctx.font = "40px Arial"; ctx.textAlign = "center"; ctx.fillText(n ? numeral(n).format("0.0") + "%" : "N/A", x, y + 15); ctx.stroke(); ctx.restore(); }(function drawFrame() { window.requestAnimationFrame(drawFrame); ctx.clearRect(0, 0, g.width, g.height); drawBand(); inc(p); drawLabel(total(p)); drawProg(p); }());
  • 相关阅读:
    Oracle 恢复[rman全备份集+当期归档日志]
    将ping结果输出到txt文件
    诗经 硕鼠 注释
    DIV里Table的宽度设置为100%后页面出现滚动条的解决办法;DIV下移的解决办法 IE 和 FireFox 都通过
    2007春节上海南站买火车票实录
    GG和baidu网络广告真的那么好做吗菜鸟不要被人忽悠了。做站长两个月总结
    iframe 自适应高度 IE Firefox 通过
    飘云QQ宣布终止后续开发 称不懂游戏规则玩不起
    我的小站:诗词在线 http://www.chinapoesy.com 欢迎大家测试速度。特别是网通的。
    丑奴儿欣赏 辛弃疾 诗词在线
  • 原文地址:https://www.cnblogs.com/conmajia/p/stackable-circular-progress-bar.html
Copyright © 2011-2022 走看看