Conmajia

Stop stealing sheep!

导航

< 20253 >
23 24 25 26 27 28 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 1 2 3 4 5

统计

H5 可堆叠的圆环进度条支持任意数量子进度条

by Conmajia
SN: S22-W1M
⚠️ 由于安全设置本文互动功能已失效

由来

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

▲ 原版进度条

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

特性 & Demo

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

  1. 可以堆叠任意数量子进度条
  2. 计算总进度
  3. 原生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.jsECharts.js也能轻轻松松实现这个效果比这好上一万倍

▲ 一个ECharts的例子

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

The End.

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); }());

posted on2019-02-18   Conmajia  阅读(2484)  评论(2编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2018-02-18 贝塞尔曲线控件 for .NET (EN)
2018-02-18 ASCII Art ヾ(≧∇≦*)ゝ
点击右上角即可分享
微信分享提示