亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

canvas怎么實現環形進度條效果

發布時間:2021-05-12 13:58:35 來源:億速云 閱讀:266 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關canvas怎么實現環形進度條效果,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

canvas怎么實現環形進度條效果

這里就選canvas來簡單寫一下 先上代碼,然后在說一說需要注意的點:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>canvas環形進度條</title>
 <style>
 body{
 background-color:#000;
 text-align: center;
 }
 .canvas1{
 margin-top: 100px;
 display: inline-block;
 background-color: #FFF;
 }
 </style>
</head>
<body>
 <canvas id="circle_process" class="canvas1"></canvas>
 <script>
 /*
 需求:環形、一周分為10個片段,根據進度去走的一個狀態
 技術選型:canvas (挑戰加熟悉)
 思路:
 01 首先中間的文字部分不用說,使用canvas的畫文字。
 02 圓形是個規則圖形,那么為了避免畫不規則圖形,我們可以用圓和矩形來重疊出效果。
 a. 大的灰色背景圓
 b. 小一圈的白色背景圓
 c. 以同心圓的圓心為圓心,小圓為半徑為半徑復制畫10個小的矩形
 */
 //初始化動畫變量
 var requestAnimationFrame = window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
 var cancelAnimationFrame = window.cancelAnimationFrame || window.msCancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelRequestAnimationFrame;
 //初始化當前進度數
 var curPercentCount = 0;
 //獲取canvas對象,設置畫布大小
 var oC = document.querySelector('#circle_process');
 oC.width = 300;
 oC.height = 300;
 //獲取canvas執行上下文
 var ctx = oC.getContext('2d');
 //定義小矩形的個數
 var miniRectCount = 10;
 //定義圓心位置
 var cirCenter = {
 x:oC.width/2,
 y:oC.height/2
 };
 //定義小矩形的大小rectSize
 var rectSize = {
 width:0,
 height:0
 };
 //圓對象構造函數
 function Circle(center,radius){
 this.center = center;
 this.radius = radius;
 }
 //小矩形對象構造函數
 function MiniRect(length,width){
 this.length = length;
 this.width = width;
 }
 //角度轉換成弧度的函數
 function d2a(angleInt){
 return angleInt*Math.PI / 180;
 }
 //百分比轉換角度函數(這里減90因為arc0度是從右側開始的)
 function percentTurn(percentFloat){
 return percentFloat * 360 / 100 - 90;
 }
 //畫當前百分比扇形的方法
 function drawFanForPercent(percentFloat){
 ctx.beginPath();
 ctx.moveTo(cirCenter.x,cirCenter.y);
 ctx.lineTo(oC.width/2,(oC.height-baseCircle.radius*2)/2);
 ctx.arc(cirCenter.x,cirCenter.y,baseCircle.radius,d2a(-90),d2a(percentTurn(percentFloat)));
 ctx.fillStyle = 'aqua';
 ctx.fill();
 ctx.closePath();
 }
 //畫圓的函數
 function drawArc(center,radius,start,end,type,color){
 start = start || 0;
 end = end || 360;
 ctx.beginPath();
 ctx.arc(center.x,center.y,radius,d2a(start),d2a(end));
 ctx.fillStyle = color;
 ctx.strokeStyle = color;
 if(!!type){
 (type === 'fill') && ctx.fill();
 (type === 'stroke') && ctx.stroke();
 }
 ctx.closePath();
 }
 //畫文字的函數
 function drawPercentText(text,percentInt){
 ctx.beginPath();
 ctx.fillStyle = 'aqua';
 ctx.font="italic small-caps bold 40px Calibri";
 ctx.textAlign = 'center';
 ctx.fillText(text,cirCenter.x,cirCenter.y-18,100);
 ctx.closePath();
 ctx.beginPath();
 ctx.fillStyle = 'aqua';
 ctx.font="italic small-caps bold 60px Calibri";
 ctx.textAlign = 'center';
 ctx.fillText(percentInt+'%',cirCenter.x,cirCenter.y+40,100);
 ctx.closePath();
 }
 //畫小方塊的方法
 function drawMiniRect(startPoint,width,height,axisPoint,rotateAngle){
 /*
 ctx.beginPath();
 //平移,畫出第一個
 ctx.save();
 ctx.translate(startPoint.x,startPoint.y);
 ctx.fillStyle = '#FFF';
 ctx.fillRect(0,0,rectSize.width,rectSize.height);
 ctx.restore();
 ctx.closePath();
 //這種先平移畫出在旋轉的思路是錯的,畫之后就不能轉了
 ctx.save();
 ctx.translate(axisPoint.x,axisPoint.y);
 ctx.rotate(rotateAngle);
 ctx.restore();
 */
 ctx.save();
 ctx.translate(axisPoint.x,axisPoint.y); /*畫布平移到圓的中心*/
 ctx.rotate(d2a(rotateAngle)); /*旋轉*/
 /*畫*/
 ctx.beginPath();
 ctx.fillStyle = '#FFF';
 ctx.fillRect(startPoint.x,startPoint.y,rectSize.width,rectSize.height);
 ctx.closePath();
 ctx.restore();
 }
 //畫整體
 function draw(curPercent){
 //底部灰色圓
 drawArc(baseCircle.center,baseCircle.radius,null,null,'fill','#CCC');
 //進度扇形
 drawFanForPercent(curPercent);
 //內部白色遮擋圓
 drawArc(innerCircle.center,innerCircle.radius,null,null,'fill','#FFF');
 //畫文字
 drawPercentText('當前進度',curPercent);
 //十個小的矩形
 for(var i=0; i<miniRectCount; i++){
 drawMiniRect(startPoint,rectSize.width,rectSize.height,cirCenter,i*360/miniRectCount);
 }
 }
 //實例化底圓和內圓
 var baseCircle = new Circle(cirCenter,130);
 var innerCircle = new Circle(cirCenter,100);
 //設置rectSize數值
 rectSize.width = 15;
 rectSize.height = baseCircle.radius - innerCircle.radius + 5;
 //設置第一個小矩形的起始點 (這里有誤差)
 // var startPoint = {
 // x: oC.width /2 - 7.5,
 // y: (oC.height - baseCircle.radius*2) / 2
 // };
 //由于平移到中心點之后畫的位置是在畫布外的,所以重新定義
 var startPoint = {
 x:-7.5,
 y:-baseCircle.radius - 2
 };
 //這里開定時去顯示當前是百分之幾的進度
 var raf = null;
 var percent = 0;
 function actProcess(percentFloat){
 percentFloat = percentFloat || 100;
 percent = Math.round(percentFloat);
 console.log(percent);
 curPercentCount++;
 raf = requestAnimationFrame(function(){
 actProcess(percentFloat);
 });
 draw(curPercentCount);
 if(curPercentCount >= percent){
 cancelAnimationFrame(raf);
 return;
 }
 }
 actProcess(50);
 // cancelAnimationFrame(raf);
 //這里沒搞懂為什么percent會加 ?
 //解: requestAnimationFrame中方法還是需要有參數,這里就用匿名函數回調的執行體去指定。
 /*
 //setInterval的方式
 function actProcess(percentFloat){
 if(curPercentCount >= percentFloat){
 clearInterval(timer);
 return;
 }
 curPercentCount++;
 draw(curPercentCount);
 }
 clearInterval(timer);
 var timer = setInterval(function(){
 actProcess(50);
 },16.7);
 */
  //直接畫弧形的測試:
 //drawArc(innerCircle.center,innerCircle.radius,0,260,'fill','red');
 /*
 用到的技術點:
 01 canvas平移
 02 canvas畫布狀態保存于恢復
 03 canvas旋轉
 04 canvas clearRect配合動畫requestAnimationFrame
 05 canvas寫文字
 */
 </script>
</body>
</html>

接下來說一些注意點和我寫的過程中碰到的疑問:

疑問:

01 整體代碼沒有封裝成一個組件,感興趣的同學可以封裝一下。 我這有時間也會封裝。

02 畫文字的時候只能單獨畫一行文字么? 怎樣進行換行?

03 canvas怎樣處理響應式?

注意點:

01 畫布平移之后,畫布上的點也會被平移,所以我在定義第一個小矩形的起始點的時候才會重新定義一個負值。

02 直接畫弧形來控制進度不準確,因為arc會自動closePath(),最終形成這樣的一個效果。

canvas怎么實現環形進度條效果

03 默認圓的0度起始位置是從3點鐘方向開始的(見上圖),那么想從12點鐘位置開始走進度,需要減去90度的角度。

04 requestAnimationFrame的回調函數在有參數的情況下還是需要傳參數的,需要借助匿名函數回調,在執行體里面去執行想要loop的函數內容(可傳參數)。否者會出現注釋中寫道的pecent不規則增加的問題。

先就這樣,之后可能會結合一個上傳圖片的小功能嘗試把它封裝成一個組件。

關于“canvas怎么實現環形進度條效果”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汉阴县| 丰城市| 准格尔旗| 荥经县| 罗源县| 永靖县| 建阳市| 宜章县| 舟山市| 闸北区| 格尔木市| 乐东| 衡阳县| 灵丘县| 湘乡市| 藁城市| 恩平市| 泽普县| 灵宝市| 临夏县| 鄢陵县| 北海市| 高雄市| 博爱县| 河南省| 宣汉县| 稻城县| 定结县| 外汇| 孝义市| 江都市| 安溪县| 衡阳县| 谷城县| 梁山县| 吉水县| 合肥市| 博爱县| 买车| 仁化县| 玛纳斯县|