1. 程式人生 > >HTML5 Canvas繪製環形進度條

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