<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
行動端的場景裡經常會出現環形進度條的功能,在實現這個功能前,我預想的解決方案大致有: echarts、antv、canvas、svg
前面兩種第三方提供的解決方案當然是簡單,拿到案例修整一下即可,但是需要下載依賴,而且程式碼量不小。有沒有不需要依賴第三方包,採用原生的寫法,獨立封裝成一個元件,降低耦合,而且效能優越?
當然,那就主要介紹canvas的使用
可以展示整個圓、半圓以及任意角度弧形(左右對稱)的進度條。整體思路如下:
1.先確定展示的形狀,是整個圓、半圓還是一般的弧形
2.把確定好形狀的圓弧均分100等份,計算出每一份所佔的弧度
3.灰色圓弧佔100份,紅色圓弧最終佔的份數由引數確定
4.設定setInterval定時器,重複執行畫圖操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>Canvas</title> </head> <body> <canvas id="canvas" width="300" height="300"></canvas> <script> draw(66); /** * [順時針方向畫圖,起始點在左側] * @param {[number]} percent [所佔的進度百分比,比如66%,則傳66即可,0 <= percent <= 100] * @param {[number]} sR [圓弧起始角度,可不傳,預設是π/2,Math.PI/2 <= sR < 3/2 * Math.PI] */ function draw(percent, sR) { if (percent < 0 || percent > 100) { return; } if (sR < Math.PI/2 || sR >= 3/2 * Math.PI) { return; } var canvas = document.querySelector('#canvas'), cxt = canvas.getContext('2d'), cWidth = canvas.width, cHeight = canvas.height, baseColor = '#e1e1e1', coverColor = '#fe4d43', PI = Math.PI, sR = sR || 1/2 * PI; // 預設圓弧的起始點弧度為π/2 var finalRadian = sR + ((PI + (PI - sR) * 2) * percent / 100); // 紅圈的終點弧度 var step = (PI + (PI - sR) * 2)/100; // 一個1%對應的弧度大小 var text = 0; // 顯示的數位 var timer = setInterval(function() { cxt.clearRect(0, 0, cWidth, cHeight); var endRadian = sR + text * step; // 畫灰色圓弧 drawCanvas(cWidth/2, cHeight/2, 80, sR, sR + (PI + (PI - sR) * 2), baseColor, 2); // 畫紅色圓弧 drawCanvas(cWidth/2, cHeight/2, 80, sR, endRadian, coverColor, 2); // 畫紅色圓頭 // 紅色圓頭其實就是一個圓,關鍵的是找到其圓心,涉及到三角函數知識,自己畫個圖一看就明瞭 var angle = 2*PI - endRadian; // 轉換成逆時針方向的弧度(三角函數中的) xPos = Math.cos(angle) * 80 + cWidth/2; // 紅色圓 圓心的x座標 yPos = -Math.sin(angle) * 80 + cHeight/2; // 紅色圓 圓心的y座標 drawCanvas(xPos, yPos, 2, 0, 2*PI, coverColor, 2); // 數位 cxt.fillStyle = coverColor; cxt.font = '40px PT Sans'; var textWidth = cxt.measureText(text+'%').width; cxt.fillText(text+'%', cWidth/2 - textWidth/2, cHeight/2 + 15); text++; if (endRadian.toFixed(2) >= finalRadian.toFixed(2)) { clearInterval(timer); } }, 30); function drawCanvas(x,y,r,sRadian,eRadian,color,lineWidth) { cxt.beginPath(); cxt.lineCap = "round"; cxt.strokeStyle = color; cxt.lineWidth = lineWidth; cxt.arc(x, y, r, sRadian, eRadian, false); cxt.stroke(); } } </script> </body> </html>
關於動畫部分,可以使用requestAnimationFrame
做優化,函數改寫如下:
function draw(percent, sR) { if (percent < 0 || percent > 100) { return; } if (sR < Math.PI/2 || sR >= 3/2 * Math.PI) { return; } var canvas = document.querySelector('#canvas'), cxt = canvas.getContext('2d'), cWidth = canvas.width, cHeight = canvas.height, baseColor = '#e1e1e1', coverColor = '#fe4d43', PI = Math.PI, sR = sR || 1/2 * PI; // 預設圓弧的起始點弧度為π/2 var finalRadian = sR + ((PI + (PI - sR) * 2) * percent / 100); // 紅圈的終點弧度 var step = (PI + (PI - sR) * 2)/100; // 一個1%對應的弧度大小 var text = 0; // 顯示的數位 window.requestAnimationFrame(paint); function paint() { cxt.clearRect(0, 0, cWidth, cHeight); var endRadian = sR + text * step; // 畫灰色圓弧 drawCanvas(cWidth/2, cHeight/2, 80, sR, sR + (PI + (PI - sR) * 2), baseColor, 2); // 畫紅色圓弧 drawCanvas(cWidth/2, cHeight/2, 80, sR, endRadian, coverColor, 2); // 畫紅色圓頭 // 紅色圓頭其實就是一個圓,關鍵的是找到其圓心,涉及到三角函數知識,自己畫個圖一看就明瞭 var angle = 2*PI - endRadian; // 轉換成逆時針方向的弧度(三角函數中的) xPos = Math.cos(angle) * 80 + cWidth/2; // 紅色圓 圓心的x座標 yPos = -Math.sin(angle) * 80 + cHeight/2; // 紅色圓 圓心的y座標 drawCanvas(xPos, yPos, 2, 0, 2*PI, coverColor, 2); // 數位 cxt.fillStyle = coverColor; cxt.font = '40px PT Sans'; var textWidth = cxt.measureText(text+'%').width; cxt.fillText(text+'%', cWidth/2 - textWidth/2, cHeight/2 + 15); text++; if (endRadian.toFixed(2) < finalRadian.toFixed(2)) { window.requestAnimationFrame(paint); } } function drawCanvas(x,y,r,sRadian,eRadian,color,lineWidth) { cxt.beginPath(); cxt.lineCap = "round"; cxt.strokeStyle = color; cxt.lineWidth = lineWidth; cxt.arc(x, y, r, sRadian, eRadian, false); cxt.stroke(); }
到此這篇關於詳解JavaScript+Canvas繪製環形進度條的文章就介紹到這了,更多相關JavaScript Canvas環形進度條內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45