JavaScript實現可動的canvas環形進度條
介紹
今天分享一個環形進度條的寫法,當然這隻是一個可動的靜態進度條,如果你喜歡可以加入後臺數據。這種進度條非常簡單的寫法到處都有,隻不過更多的隻是寫個樣子,咱們這個可以動喲。
前提是canvas的屬性、方法和一些基礎的js API你都知道,當然為瞭保證一些忘記的小夥伴一下想起來,我會在前面列個表。
屬性和方法 | 描述 |
---|---|
getContext() | 返回一個用於在畫佈上繪圖的環境 |
strokeStyle | 畫筆(繪制圖形)顏色或者樣式的屬性 |
lineWidth | 設置線段厚度的屬性 |
save() | 保存canvas全部狀態的方法(入棧) |
beginPath() | 創建一個新的路徑的方法 |
arc(原點x,原點y,半徑,起始角度,結束角度,默認false順時針) | 繪制圓弧路徑的方法 |
stroke() | 繪制路徑的方法 |
closePath() | 閉合繪制路徑 |
restore() | 恢復到最近的保存狀態的方法(出棧) |
fillStyle | 顏色和樣式的屬性 |
font | 當前字體樣式的屬性 |
toFixed(num) | 把Number四舍五入為指定小數位數的數字 |
回顧完上表開始繪制圖形,圖形的繪制除瞭canvas元素之外還有以下幾個部分,我先分開把代碼按部分寫出:
1.創建canvas元素
先創建一個canvas的標簽給出寬高,繪制環形進度寬高一致就可以,之後獲取元素,並創建畫佈。註意canvas元素這裡起名mycanvas,繪制的畫佈對象叫ctx。
<canvas id="mycanvas" width="200" height="200"></canvas> //以下為js代碼 var mycanvas = document.getElementById('mycanvas'); var ctx = mycanvas.getContext('2d');
2.繪制的準備工作
繪制之前需要做一些準備工作
- 找到“畫佈的中心點”的,進度條
- 將進度條按照進度的比例分成100份,按照100%完成
- 指定初始加載步長(長度),註意這是初始化後期可以改成0
//找到畫佈的中心點 var canvasX = mycanvas.width / 2; var canvasY = mycanvas.height / 2; //進度條是100%,所以要把一圈360度分成100份 var progress = Math.PI * 2 / 100; //指定初始加載步長 var steps = 0.5;
3.繪制環形底層
先把進度的環形底層淺灰色的環繪制出來,它是進度的路徑。可以先把繪制的顏色和線寬指定好,這兩個屬性對下面的方法順序起不到影響。
ctx.strokeStyle = '#dddddd'; ctx.lineWidth = 20; ctx.save(); ctx.beginPath(); ctx.arc(canvasX, canvasY, 90, 0, Math.PI * 2, false) ctx.stroke(); ctx.closePath(); ctx.restore();
4.繪制進度層
進度層繪制的顏色需要定義出來,另外進度條的粗細與底層環形的粗細相同。這裡最重要的一句是,在結束角度的時候加入瞭“steps progress” 步長 進度。steps 數值越小乘成數之後增加的角度就少,steps數值大乘數之後進度增加的就多。
ctx.strokeStyle = "#47cab0"; ctx.lineWidth = 20; ctx.save(); ctx.beginPath(); ctx.arc(canvasX,canvasY,90, -Math.PI/2, -Math.PI/2+steps*progress,false); ctx.stroke(); ctx.closePath(); ctx.restore();
5.繪制字體並指定位置
環形的進度百分比文字顯示需要使用canvas的文字繪制,這裡需要註意數字是從1位到3位的跨度,還要加入%,因此位置需要變化。當數字到100時文字占寬就更大因此要改變繪制起點。
ctx.fillStyle = "#000000"; //可改 ctx.font = "bold 26px Arial"; //可改 ctx.save(); // canvasX-30, canvasY+10 中的加減的數值可改 if (steps.toFixed(0).length == 3) { ctx.fillText(steps.toFixed(0) + '%', canvasX - 30, canvasY + 10); } else { ctx.fillText(steps.toFixed(0) + '%', canvasX - 20, canvasY + 10); } ctx.restore();
寫到這裡靜態的一個進度就會出現,但是我們還需要讓他動起來,大傢可能想到的定時器。但我們卻使用瞭另一種編寫循環動畫的方法。
6.進度動畫
顯示器的刷新頻率通常是50~60hz,1000ms/60≈16.6ms,相當於每秒鐘重繪60次,大多數瀏覽器都不會超過顯示器的重繪頻率。之前的文章我們曾經提到過setTimeout()和setInterval()這兩種循環其實並不那麼精準智能,即使使用setTimeout()以自調的方式模擬循環定時器,也不能確保處理線程可以按照理想之行。
window.requestAnimationFrame()
window.requestAnimationFrame() 告訴瀏覽器——你希望執行一個動畫,並且要求瀏覽器在下次重繪之前調用指定的回調函數更新動畫。該方法需要傳入一個回調函數作為參數,該回調函數會在瀏覽器下一次重繪之前執行。 回調函數執行次數通常是每秒60次,但在大多數遵循W3C建議的瀏覽器中,回調函數執行次數通常與瀏覽器屏幕刷新次數相匹配。為瞭提高性能和電池壽命,因此在大多數瀏覽器裡,當requestAnimationFrame() 運行在後臺標簽頁或者隱藏的 <iframe> 裡時,requestAnimationFrame() 會被暫停調用以提升性能和電池壽命。
因此為瞭保證平滑渲染,我們使用,window.requestAnimationFrame(),在該方法的參數一個回調函數中做幾件事:
1.判斷完成整個環形步長的結束值,如:100,其實就是走到100%的位置,75就是走到75%的位置
2.在選擇的步長范圍內調用增長的函數
window.requestAnimationFrame(function () { //判斷步子最終走多遠的邊界值,此值可以改 if (steps < 90) { //該函數在邊界內可以調用函數,增加步長並且繪制圖形給這個函數起個名字 } })
因為有函數的自調用,所以我們把這部分寫在一起,不拆分寫瞭。難度就在此處!
第一步:要先做,把之前所有的繪制圖形代碼放入新創建的函數DrawShape中,並且需要接收兩個參數。一個是要繪制的對象,因為一個頁面上不止一個畫佈對象。第二個參數就是每次會改變的步長。
//繪制形狀函數,傳入畫佈對象和每次都會改變的步長 function DrawShape(ctx,steps) { //畫圓 畫底層圓形的代碼... //畫進度環 畫進度條的代碼... //繪制字體並指定位置 繪制字體的代碼... }
第二步:創建animate函數用來執:平滑動畫、行步長的增加、繪制圖形三件重要事宜。
//初始調用動畫函數 animate(); //動畫函數 function animate() { //執行平滑動畫 window.requestAnimationFrame(function () { //判斷步子最終走多遠的邊界值,此值可以改 if (steps < 90) { //該函數在邊界內可以調用 animate(); } }); //清空繪制內容 ctx.clearRect(0, 0, mycanvas.width, mycanvas.height); //每次增加的步長,數值越大步子越大跑的越快,數值越小走的越慢 steps += 0.5;//可改 //調用繪制形狀函數,傳入參數繪制對象,環形進度步長 DrawShape(ctx,steps); };
以上代碼是全部代碼隻是沒有合並整理格式,大傢可以自己整理
到此這篇關於JavaScript實現可動的canvas環形進度條的文章就介紹到這瞭,更多相關JavaScript canvas環形進度條內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- JS前端以輕量fabric.js實現示例理解canvas
- 微信小程序使用canvas繪制鐘表
- JavaScript實現環繞鼠標旋轉效果
- JavaScript+Canvas實現帶跳動效果的粒子動畫
- JavaScript Canvas繪制六邊形網格