HTML5 Canvas绘制环形进度条

最近比较迷恋canvas,加之做了一个个人网站,有用到环形进度条,记录下来。

canvas中没有直接绘制圆的方法,但有一个绘制弧线的context.arc方法, 
下面讲下用该方法如何绘制出图片效果。

processbar

arc()方法介绍

context.arc(x,y,r,sAngle,eAngle,counterclockwise);

参数说明:

  • x: 圆的中心的 x 坐标
  • y: 圆的中心的 y 坐标
  • r: 圆的半径
  • sAngle: 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)
  • eAngle: 结束角,以弧度计
  • counterclockwise: 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。默认false

看到这里,大家就会明白怎么画圆了把,只要让起始角和结束角度为一个圆周就可以了。

下面开始画图咯!

环形进度条

环形进度条主要两部分组成,一是灰色圆,另一是蓝色弧度。也就是说灰色圆圈和蓝色弧同圆心同半径。知道了原理大家是不是觉得瞬间简单好多。。。

第一步:画灰色圆

function Circle() {
    this.radius = 100;    // 圆环半径
    this.lineWidth = 25;  // 圆环边的宽度
    this.strokeStyle = '#ccc'; //边的颜色
    this.fillStyle = 'blue';  //填充色
    this.lineCap = 'round';
}

Circle.prototype.draw = function(ctx) {
    ctx.beginPath();
    ctx.arc(250, 250, this.radius, 0, Math.PI*2, true);  // 坐标为250的圆,这里起始角度是0,结束角度是Math.PI*2
    ctx.lineWidth = this.lineWidth;
    ctx.strokeStyle = this.strokeStyle;
    ctx.stroke();  // 这里用stroke画一个空心圆,想填充颜色的童鞋可以用fill方法
};

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

当然这样是画不出来的,我们继续往下看。

第二步:画进度条(蓝色部分)

这部分说白了就是和灰色圆圈同圆心同半径的一条蓝弧。

function Ring(startAngle, percent) {
    Circle.call(this);
    this.startAngle = startAngle || 3*Math.PI/2; //弧起始角度
    this.percent = percent;  //弧占的比例
}

Ring.prototype = Object.create(Circle.prototype);

Ring.prototype.drawRing = function(ctx) {
     this.draw(ctx);  // 调用Circle的draw方法画圈圈

     // angle
     ctx.beginPath();
     var anglePerSec = 2 * Math.PI / (100 / this.percent); // 蓝色的弧度
     ctx.arc(250, 250, this.radius, this.startAngle, this.startAngle + , false); //这里的圆心坐标要和cirle的保持一致
     ctx.strokeStyle = that.fillStyle;
     ctx.lineCap = that.lineCap;
     ctx.stroke();
     ctx.closePath();
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

canvas是不是还没定义呐?别急,咱慢慢来~

<canvas id="canvas" width="400" height="400"></canvas>
 
 
  • 1
  • 1

获取canvas的上下文context:

var canvas = document.getElementById('canvas');
var ctx =  canvas.getContext('2d');
 
 
  • 1
  • 2
  • 1
  • 2

接下来就调用下我们的drawRing

var ring = new Ring(2*Math.PI/3, 50);  // 从2*Math.PI/3弧度开始,进度为50%的环
ring.drawRing(ctx);
 
 
  • 1
  • 2
  • 1
  • 2

到这里,一个上图所示的进度环就ok了~ 
先别鼓掌太早,既然是进度条,是不是要动起来的更美呢!

动之前,我们先搞明白一个概念,我们知道,坐标分为四个象限,如果圆心是原点,那么arc方法的弧度是怎么开始的呢?先看图! 
arc(偶从w3school挖的图)

怎么样,明白了吗?是不是觉得哪里不对劲呢~上学时学的第一象限0~π/2(右上角),怎么看起来是反的呢,这就是差异啊!!细心的童鞋可能会注意到arc方法不是还有最后一个参数嘛,还是可选的,当counterclockwise参数为true时,你们猜这逆天的坐标轴会变成我们熟悉的吗?哎~摸摸头。。。人家这参数只是让弧度逆时针转了而已,坐标轴弧度还是不变滴~

好了,说了这么多,是不是该动起来了呢,直接上代码。

Ring.prototype.drawRing = function(ctx) {
    var count = 0,
        that = this,
        times = 10, // 分十次绘制蓝弧
        startAngle = this.startAngle,
        endAngle = startAngle;

    // draw background cirle
    this.draw(ctx);

    var handle = setInterval(function() {
      if (count == times) {
        clearInterval(handle);
      }

      // angle
      ctx.beginPath();
      var anglePerSec = 2 * Math.PI * (that.percent / 100) / times; // 每个间隔滑动的弧度
      ctx.arc(250, 250, that.radius, startAngle, endAngle, false); //这里的圆心坐标要和cirle的保持一致
      ctx.strokeStyle = that.fillStyle;
      ctx.lineCap = that.lineCap;
      ctx.stroke();
      ctx.closePath();

      startAngle += anglePerSec - 0.0028; // 消除每次绘环间的计算误差,防止出现空隙
      endAngle = startAngle + anglePerSec;

      count++;
    }, 60); // 这里定义每60ms绘制一次
  }
 
 
  • 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
  • 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

是的,只要把Ring.prototype.drawRing方法替换为上面的就行。 

小伙伴们自己动手画个吧~

转载:http://blog.csdn.net/chuan2009he/article/details/45065299



<!DOCTYPE html> 
<html xmlns="  http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Canvas绘图</title>
</head>
<body>
<canvas class="process" width="48px" height="48px">0%</canvas>  
</body>
<script>
$(document).ready(function() {
//drawProcess();
i = 0;
var t = setInterval("addNum()",20);
});
function addNum() {
if(i<100){
i++;
$('canvas.process').text(i+"%");
drawProcess();
}else{
clearInterval(t);
}
}

function drawProcess() {  
    $('canvas.process').each(function() {
        var text = $(this).text();
        var process = text.substring(0, text.length-1);   
        var canvas = this;  
        var context = canvas.getContext('2d');  
        context.clearRect(0, 0, 48, 48);  
        context.beginPath();  
        context.moveTo(24, 24);  
        context.arc(24, 24, 24, 0, Math.PI * 2, false);  
        context.closePath();  
        context.fillStyle = '#ddd';  
        context.fill();  
        context.beginPath();  
        context.moveTo(24, 24);    
        context.arc(24, 24, 24, 0, Math.PI * 2 * process / 100, false);  
        context.closePath();  
        context.fillStyle = '#2a2';  
        context.fill();   
        context.beginPath();  
        context.moveTo(24, 24);  
        context.arc(24, 24, 21, 0, Math.PI * 2, true);  
        context.closePath();  
        context.fillStyle = 'rgba(255,255,255,1)';  
        context.fill();  
        context.beginPath();  
        context.arc(24, 24, 18.5, 0, Math.PI * 2, true);  
        context.closePath();  
        context.strokeStyle = '#ddd';  
        context.stroke();  
        context.font = "bold 9pt Arial";  
        context.fillStyle = '#2a2';  
        context.textAlign = 'center';  
        context.textBaseline = 'middle';  
        context.moveTo(24, 24);  
        context.fillText(text, 24, 24);  
    });
}
</script>
</html>
转载:http://www.oschina.net/question/591528_116343?sort=time

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值