JavaScript實(shí)現(xiàn)可動的canvas環(huán)形進(jìn)度條
介紹
今天分享一個(gè)環(huán)形進(jìn)度條的寫法,當(dāng)然這只是一個(gè)可動的靜態(tài)進(jìn)度條,如果你喜歡可以加入后臺數(shù)據(jù)。這種進(jìn)度條非常簡單的寫法到處都有,只不過更多的只是寫個(gè)樣子,咱們這個(gè)可以動喲。
前提是canvas的屬性、方法和一些基礎(chǔ)的js API你都知道,當(dāng)然為了保證一些忘記的小伙伴一下想起來,我會在前面列個(gè)表。
屬性和方法 | 描述 |
---|---|
getContext() | 返回一個(gè)用于在畫布上繪圖的環(huán)境 |
strokeStyle | 畫筆(繪制圖形)顏色或者樣式的屬性 |
lineWidth | 設(shè)置線段厚度的屬性 |
save() | 保存canvas全部狀態(tài)的方法(入棧) |
beginPath() | 創(chuàng)建一個(gè)新的路徑的方法 |
arc(原點(diǎn)x,原點(diǎn)y,半徑,起始角度,結(jié)束角度,默認(rèn)false順時(shí)針) | 繪制圓弧路徑的方法 |
stroke() | 繪制路徑的方法 |
closePath() | 閉合繪制路徑 |
restore() | 恢復(fù)到最近的保存狀態(tài)的方法(出棧) |
fillStyle | 顏色和樣式的屬性 |
font | 當(dāng)前字體樣式的屬性 |
toFixed(num) | 把Number四舍五入為指定小數(shù)位數(shù)的數(shù)字 |
回顧完上表開始繪制圖形,圖形的繪制除了canvas元素之外還有以下幾個(gè)部分,我先分開把代碼按部分寫出:
1.創(chuàng)建canvas元素
先創(chuàng)建一個(gè)canvas的標(biāo)簽給出寬高,繪制環(huán)形進(jìn)度寬高一致就可以,之后獲取元素,并創(chuàng)建畫布。注意canvas元素這里起名mycanvas,繪制的畫布對象叫ctx。
<canvas id="mycanvas" width="200" height="200"></canvas> //以下為js代碼 var mycanvas = document.getElementById('mycanvas'); var ctx = mycanvas.getContext('2d');
2.繪制的準(zhǔn)備工作
繪制之前需要做一些準(zhǔn)備工作
- 找到“畫布的中心點(diǎn)”的,進(jìn)度條
- 將進(jìn)度條按照進(jìn)度的比例分成100份,按照100%完成
- 指定初始加載步長(長度),注意這是初始化后期可以改成0
//找到畫布的中心點(diǎn) var canvasX = mycanvas.width / 2; var canvasY = mycanvas.height / 2; //進(jìn)度條是100%,所以要把一圈360度分成100份 var progress = Math.PI * 2 / 100; //指定初始加載步長 var steps = 0.5;
3.繪制環(huán)形底層
先把進(jìn)度的環(huán)形底層淺灰色的環(huán)繪制出來,它是進(jìn)度的路徑。可以先把繪制的顏色和線寬指定好,這兩個(gè)屬性對下面的方法順序起不到影響。
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.繪制進(jìn)度層
進(jìn)度層繪制的顏色需要定義出來,另外進(jìn)度條的粗細(xì)與底層環(huán)形的粗細(xì)相同。這里最重要的一句是,在結(jié)束角度的時(shí)候加入了“steps progress” 步長 進(jìn)度。steps 數(shù)值越小乘成數(shù)之后增加的角度就少,steps數(shù)值大乘數(shù)之后進(jìn)度增加的就多。
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.繪制字體并指定位置
環(huán)形的進(jìn)度百分比文字顯示需要使用canvas的文字繪制,這里需要注意數(shù)字是從1位到3位的跨度,還要加入%,因此位置需要變化。當(dāng)數(shù)字到100時(shí)文字占寬就更大因此要改變繪制起點(diǎn)。
ctx.fillStyle = "#000000"; //可改 ctx.font = "bold 26px Arial"; //可改 ctx.save(); // canvasX-30, canvasY+10 中的加減的數(shù)值可改 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();
寫到這里靜態(tài)的一個(gè)進(jìn)度就會出現(xiàn),但是我們還需要讓他動起來,大家可能想到的定時(shí)器。但我們卻使用了另一種編寫循環(huán)動畫的方法。
6.進(jìn)度動畫
顯示器的刷新頻率通常是50~60hz,1000ms/60≈16.6ms,相當(dāng)于每秒鐘重繪60次,大多數(shù)瀏覽器都不會超過顯示器的重繪頻率。之前的文章我們曾經(jīng)提到過setTimeout()和setInterval()這兩種循環(huán)其實(shí)并不那么精準(zhǔn)智能,即使使用setTimeout()以自調(diào)的方式模擬循環(huán)定時(shí)器,也不能確保處理線程可以按照理想之行。
window.requestAnimationFrame()
window.requestAnimationFrame() 告訴瀏覽器——你希望執(zhí)行一個(gè)動畫,并且要求瀏覽器在下次重繪之前調(diào)用指定的回調(diào)函數(shù)更新動畫。該方法需要傳入一個(gè)回調(diào)函數(shù)作為參數(shù),該回調(diào)函數(shù)會在瀏覽器下一次重繪之前執(zhí)行。 回調(diào)函數(shù)執(zhí)行次數(shù)通常是每秒60次,但在大多數(shù)遵循W3C建議的瀏覽器中,回調(diào)函數(shù)執(zhí)行次數(shù)通常與瀏覽器屏幕刷新次數(shù)相匹配。為了提高性能和電池壽命,因此在大多數(shù)瀏覽器里,當(dāng)requestAnimationFrame() 運(yùn)行在后臺標(biāo)簽頁或者隱藏的 <iframe> 里時(shí),requestAnimationFrame() 會被暫停調(diào)用以提升性能和電池壽命。
因此為了保證平滑渲染,我們使用,window.requestAnimationFrame(),在該方法的參數(shù)一個(gè)回調(diào)函數(shù)中做幾件事:
1.判斷完成整個(gè)環(huán)形步長的結(jié)束值,如:100,其實(shí)就是走到100%的位置,75就是走到75%的位置
2.在選擇的步長范圍內(nèi)調(diào)用增長的函數(shù)
window.requestAnimationFrame(function () { //判斷步子最終走多遠(yuǎn)的邊界值,此值可以改 if (steps < 90) { //該函數(shù)在邊界內(nèi)可以調(diào)用函數(shù),增加步長并且繪制圖形給這個(gè)函數(shù)起個(gè)名字 } })
因?yàn)橛泻瘮?shù)的自調(diào)用,所以我們把這部分寫在一起,不拆分寫了。難度就在此處!
第一步:要先做,把之前所有的繪制圖形代碼放入新創(chuàng)建的函數(shù)DrawShape中,并且需要接收兩個(gè)參數(shù)。一個(gè)是要繪制的對象,因?yàn)橐粋€(gè)頁面上不止一個(gè)畫布對象。第二個(gè)參數(shù)就是每次會改變的步長。
//繪制形狀函數(shù),傳入畫布對象和每次都會改變的步長 function DrawShape(ctx,steps) { //畫圓 畫底層圓形的代碼... //畫進(jìn)度環(huán) 畫進(jìn)度條的代碼... //繪制字體并指定位置 繪制字體的代碼... }
第二步:創(chuàng)建animate函數(shù)用來執(zhí):平滑動畫、行步長的增加、繪制圖形三件重要事宜。
//初始調(diào)用動畫函數(shù) animate(); //動畫函數(shù) function animate() { //執(zhí)行平滑動畫 window.requestAnimationFrame(function () { //判斷步子最終走多遠(yuǎn)的邊界值,此值可以改 if (steps < 90) { //該函數(shù)在邊界內(nèi)可以調(diào)用 animate(); } }); //清空繪制內(nèi)容 ctx.clearRect(0, 0, mycanvas.width, mycanvas.height); //每次增加的步長,數(shù)值越大步子越大跑的越快,數(shù)值越小走的越慢 steps += 0.5;//可改 //調(diào)用繪制形狀函數(shù),傳入?yún)?shù)繪制對象,環(huán)形進(jìn)度步長 DrawShape(ctx,steps); };
以上代碼是全部代碼只是沒有合并整理格式,大家可以自己整理
到此這篇關(guān)于JavaScript實(shí)現(xiàn)可動的canvas環(huán)形進(jìn)度條的文章就介紹到這了,更多相關(guān)JavaScript canvas環(huán)形進(jìn)度條內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript?canvas繪制動態(tài)圓環(huán)進(jìn)度條
- JavaScript canvas繪制圓形加載進(jìn)度條
- 詳解JavaScript+Canvas繪制環(huán)形進(jìn)度條
- js+HTML5 canvas 實(shí)現(xiàn)簡單的加載條(進(jìn)度條)功能示例
- 環(huán)形加載進(jìn)度條封裝(Vue插件版和原生js版)
- js實(shí)現(xiàn)增加數(shù)字顯示的環(huán)形進(jìn)度條效果
- JS實(shí)現(xiàn)環(huán)形進(jìn)度條(從0到100%)效果
- javascript 進(jìn)度條的幾種方法
- js實(shí)現(xiàn)進(jìn)度條的方法
- JavaScript canvas實(shí)現(xiàn)環(huán)形漸變進(jìn)度條
相關(guān)文章
解讀input標(biāo)簽的value屬性及name屬性
這篇文章主要介紹了解讀input標(biāo)簽的value屬性,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01JavaScript中的call和apply的用途以及區(qū)別
本文主要介紹了JavaScript中的call和apply的用途以及區(qū)別。具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01使用bat打開多個(gè)cmd窗口執(zhí)行g(shù)ulp、node
本文主要介紹了使用bat打開多個(gè)cmd窗口執(zhí)行g(shù)ulp、node的方法。具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02