canvas 餅圖動效

完成效果以下: css

動效餅圖顯示

1、繪製靜態餅圖

step1 設置圓心座標,半徑進行繪製大圓和小圓

甜甜圈🍩顯示
html

<canvas id="myCanvas" width="600" height="600"></canvas>
複製代碼

csshtml

canvas {
    border: 1px solid #ccc;
}
複製代碼

jscanvas

var canvas = document.getElementById("myCanvas");
var context = canvas.getContext('2d');
var cX = canvas.width / 2; //圓心X座標
var cY = canvas.height / 2; //圓心Y座標
var bR = 200; //設置大圓半徑
var sR = 100; //設置小圓半徑

// step1 建立大圓
context.beginPath();
context.arc(cX, cY, bR, 0, 2 * Math.PI);
context.fillStyle = 'red';
context.fill();

// step2 建立小圓
context.beginPath();
context.arc(cX, cY, sR, 0, 2 * Math.PI);
context.fillStyle = 'white';
context.fill();
複製代碼

step2 繪製45°扇形

45°扇形顯示

// step1 建立大圓
context.beginPath();
context.moveTo(cX, cY);
context.lineTo(cX + bR, cY); 
context.arc(cX, cY, bR, 0, 1 / 8 * 2 * Math.PI); //繪製45°圓
context.lineTo(cX, cY);
context.fillStyle = 'red';
context.fill();

// step2 建立小圓
context.beginPath();
context.moveTo(cX, cY);
context.lineTo(cX + sR, cY);
context.arc(cX, cY, sR, 0, 1 / 8 * 2 * Math.PI); //繪製45°圓
context.lineTo(cX, cY);
context.fillStyle = 'white';
context.fill();
複製代碼

以上代碼存在個問題(js小數點的問題),以下圖,小圓未把大圓區域所有填充徹底,邊緣存在紅色虛線 bash

45°扇形顯示
解決辦法以下:對小圓區域進行描邊

context.strokeStyle = "white";
context.stroke();
context.lineWidth = 2;
複製代碼

step3 把大圓、小圓的代碼進行封裝,目的爲了建立多個不一樣弧度的扇形時方便調用

function drawDonuts(startAngle, endAngle, color) {

    // step1 建立大圓
    context.beginPath();
    context.moveTo(cX, cY);
    context.lineTo(cX + bR * Math.cos(startAngle), cY + bR * Math.sin(startAngle));
    context.arc(cX, cY, bR, startAngle, endAngle);
    context.lineTo(cX, cY);
    context.fillStyle = color;
    context.fill();

    // step2 建立小圓
    context.beginPath();
    context.moveTo(cX, cY);
    context.lineTo(cX + sR * Math.cos(startAngle), cY + sR * Math.sin(startAngle));
    context.arc(cX, cY, sR, startAngle, endAngle);
    context.lineTo(cX, cY);
    context.fillStyle = 'pink';
    context.fill();
    // 添加如下代碼是爲 解決小圓未把大圓區域所有填充徹底的問題,如上圖所示邊緣存在紅色虛線
    context.strokeStyle = "pink";
    context.stroke();
    context.lineWidth = 2;

    }
複製代碼
// 設置每一個扇形的弧度比例以及顏色
var setArr = [{
    scale: 0.2 * 2 * Math.PI,
    color: "red"
}, {
    scale: 0.35 * 2 * Math.PI,
    color: "cyan"
}, {
    scale: 0.25 * 2 * Math.PI,
    color: "purple"
}, {
    scale: 0.1 * 2 * Math.PI,
    color: "blue"
}, {
    scale: 0.1 * 2 * Math.PI,
    color: "orange"
}];

var startAngle = 0;
var endAngle = 0;
for(var i =0;i<setArr.length;i++){
    endAngle += setArr[i].scale;
    drawDonuts(startAngle,endAngle,setArr[i].color); //調用封裝函數
    startAngle = endAngle;
}
複製代碼

2、動態實現

step1 實現純色甜甜圈動畫顯示

純色圓動效顯示

註釋該段代碼
// for(var i =0;i<setArr.length;i++){
//     endAngle += setArr[i].scale;
//     drawDonuts(startAngle,endAngle,setArr[i].color);
//     startAngle = endAngle;
// }

var speed = 5 / 360 * 2 * Math.PI; //控制動態顯示的速度
var timer1 = setInterval(function() {
    if (endAngle > 2 * Math.PI) {
        clearInterval(timer1); //優化性能,再也不繼續渲染
    }
    endAngle += speed;
    drawDonuts(startAngle, endAngle, 'cyan');
    startAngle = endAngle;
}, 1000 / 40);
複製代碼

step2 實現不一樣顏色甜甜圈動效顯示

var speed = 5 / 360 * 2 * Math.PI; //控制動態顯示的速度
var dataArr = [0];
var sum = 0;

for (var i = 0; i < setArr.length; i++) {
    sum += setArr[i].scale;
    dataArr.push(sum);
}
var timer1 = setInterval(function() {
    endAngle += speed;
    if (endAngle > 2 * Math.PI) {
        clearInterval(timer1); //優化性能,再也不繼續渲染
    }
    for (var i = 1; i < dataArr.length; i++) {
        if (endAngle >= dataArr[i - 1] && endAngle <= dataArr[i]){
            drawDonuts(startAngle, endAngle, setArr[i - 1].color);
            break;
        }
    }
    startAngle = endAngle - 0.01; //處理動效旋轉時出現的間隙問題
}, 1000 / 40);
複製代碼

大功告成 —— ending

太少寫文章,表達不大好,歡迎你們提寶貴意見~感激~函數

相關文章
相關標籤/搜索