有關canvas以前有寫過兩篇文章html
一、Canvas(1)---概述+簡單示例canvas
二、Canvas(2)---繪製折線圖dom
在繪製餅狀圖以前,咱們先要理解什麼是圓弧,如何在畫布中繪製文字等等。因此這裏將繪製餅狀圖理解拆分紅如下幾個步驟:字體
一、理解圓弧 二、繪製一段圓弧 三、繪製一個扇形 四、繪製一個六等圓 五、繪製一個根據數據的餅圖 六、繪製在畫布中心的一段文字 七、繪製完整餅狀圖
什麼是弧度
弧度是一種長度的描述單位, 一個半徑的長度就表示一弧度,因此一個圓有2*π個弧度。code
效果
htm
代碼
blog
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> canvas { border: 1px solid #00CED1; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas = document.querySelector('canvas'); var ctx = myCanvas.getContext('2d'); /*參數*/ /*座標 x y 肯定圓心 */ /*肯定圓半徑 r */ /*肯定起始繪製的位置和結束繪製的位置 Math.PI=π 也就是180度*/ /*取得繪製的方向 direction 默認是順時針 false 逆時針 true */ var w = ctx.canvas.width; var h = ctx.canvas.height; ctx.arc(w/2,h/2,150,Math.PI/2,Math.PI,false); ctx.stroke(); </script> </body> </html>
思考
爲何這裏四分之一的弧度是這個方向的,那是由於canvas指定了規則ip
因此上面 Math.PI/2 到 Math.PI,且是 順時針 的。由這兩點最終繪製的就是上面的效果了。get
效果
it
代碼
<!-- 上面部分代碼和上面一致,這裏就不重複寫了 --> <script> var myCanvas = document.querySelector('canvas'); var ctx = myCanvas.getContext('2d'); /*在中心位置畫一個半徑150px的圓弧右上角 扇形 邊 填充 */ var w = ctx.canvas.width; var h = ctx.canvas.height; /*把起點放到圓心位置*/ ctx.moveTo(w/2,h/2); ctx.arc(w/2,h/2,150,0,-Math.PI/2,true); //注意這裏採用的是填充 ,而不是閉合 ctx.closePath() ctx.fill(); </script>
效果
代碼
<!-- 上面部分代碼和上面一致,這裏就不重複寫了 --> <script> var myCanvas = document.querySelector('canvas'); var ctx = myCanvas.getContext('2d'); var w = ctx.canvas.width; var h = ctx.canvas.height; /*分紅幾等分*/ var num = 6; /*一份多少弧度*/ var angle = Math.PI * 2 / num; /*原點座標*/ var x0 = w / 2; var y0 = h / 2; /*獲取隨機顏色*/ var getRandomColor = function () { var r = Math.floor(Math.random() * 256); var g = Math.floor(Math.random() * 256); var b = Math.floor(Math.random() * 256); return 'rgb(' + r + ',' + g + ',' + b + ')'; } /*上一次繪製的結束弧度等於當前次的起始弧度*/ for (var i = 0; i < num; i++) { var startAngle = i * angle; var endAngle = (i + 1) * angle; ctx.beginPath(); ctx.moveTo(x0, y0); ctx.arc(x0, y0, 150, startAngle, endAngle); /*隨機顏色*/ ctx.fillStyle = getRandomColor(); ctx.fill(); } </script>
上面是平均分紅了6等分,這裏是根據具體的數據來按比例分紅若干份。
效果
代碼
<!-- 上面部分代碼和上面一致,這裏就不重複寫了 --> <script> var myCanvas = document.querySelector('canvas'); var ctx = myCanvas.getContext('2d'); //數據 var data = [5, 10, 15, 20]; /*1.須要把數據轉出弧度 先計算總數*/ var total = 0; data.forEach(function (item, i) { total += item; }); //二、計算每一個數據所佔的弧度 var angleList = []; data.forEach(function (item, i) { var angle = Math.PI * 2 * (item/total); angleList.push(angle); }); /* 三、獲取隨機顏色*/ var getRandomColor = function () { var r = Math.floor(Math.random() * 256); var g = Math.floor(Math.random() * 256); var b = Math.floor(Math.random() * 256); return 'rgb(' + r + ',' + g + ',' + b + ')'; } /*4.根據弧度繪製扇形*/ var w = ctx.canvas.width; var h = ctx.canvas.height; var x0 = w/2; var y0 = h/2; var startAngle = 0; angleList.forEach(function (item,i) { /*上一次繪製的結束弧度等於當前次的起始弧度*/ var endAngle = startAngle + item; ctx.beginPath(); ctx.moveTo(x0,y0); ctx.arc(x0,y0,150,startAngle,endAngle); ctx.fillStyle = getRandomColor(); ctx.fill(); /*記錄當前的結束位置做爲下一次的起始位置*/ startAngle = endAngle; }); </script>
效果
代碼
<html lang="en"> <head> <meta charset="UTF-8"> <style> canvas { border: 1px solid #00CED1; display: block; margin: 100px auto; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas = document.querySelector('canvas'); var ctx = myCanvas.getContext('2d'); /*1.在畫布的中心繪製一段文字*/ /*2.申明一段文字*/ var str = '武漢加油'; /*3.肯定畫布的中心*/ var w = ctx.canvas.width; var h = ctx.canvas.height; /*4.畫一個十字架在畫布的中心*/ ctx.beginPath(); ctx.moveTo(0, h / 2); ctx.lineTo(w, h / 2); ctx.moveTo(w / 2, 0); ctx.lineTo(w / 2, h); ctx.strokeStyle = '#eee'; ctx.stroke(); /*5.繪製文本*/ ctx.beginPath(); ctx.strokeStyle = '#000'; var x0 = w/2; var y0 = h/2; /*注意:起點位置在文字的左下角*/ /*有文本的屬性 尺寸 字體 左右對齊方式 垂直對齊的方式*/ ctx.font = '40px Microsoft YaHei'; /*左右對齊方式 (center left right start end) 基準起始座標*/ ctx.textAlign = 'center'; /*垂直對齊的方式 基線 baseline(top,bottom,middle) 基準起始座標*/ ctx.textBaseline = 'middle'; //ctx.direction = 'rtl'; //ctx.strokeText(str,x0,y0); ctx.fillText(str,x0,y0); /*6.畫一個下劃線和文字同樣長*/ ctx.beginPath(); /*獲取文本的寬度*/ console.log(ctx.measureText(str)); var width = ctx.measureText(str).width; ctx.moveTo(x0-width/2,y0 + 20); ctx.lineTo(x0+width/2,y0 + 20); ctx.stroke(); </script> </body> </html>
上面所作的都是爲了整個餅狀圖作鋪墊的。
效果
代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> canvas { border: 1px solid #00CED1; display: block; margin: 100px auto; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas = document.querySelector('canvas'); var ctx = myCanvas.getContext('2d'); /*1.在畫布的中心繪製一段文字*/ /*2.申明一段文字*/ var str = '武漢加油'; /*3.肯定畫布的中心*/ var w = ctx.canvas.width; var h = ctx.canvas.height; /*4.畫一個十字架在畫布的中心*/ ctx.beginPath(); ctx.moveTo(0, h / 2); ctx.lineTo(w, h / 2); ctx.moveTo(w / 2, 0); ctx.lineTo(w / 2, h); ctx.strokeStyle = '#eee'; ctx.stroke(); /*5.繪製文本*/ ctx.beginPath(); ctx.strokeStyle = '#000'; var x0 = w/2; var y0 = h/2; /*注意:起點位置在文字的左下角*/ /*有文本的屬性 尺寸 字體 左右對齊方式 垂直對齊的方式*/ ctx.font = '40px Microsoft YaHei'; /*左右對齊方式 (center left right start end) 基準起始座標*/ ctx.textAlign = 'center'; /*垂直對齊的方式 基線 baseline(top,bottom,middle) 基準起始座標*/ ctx.textBaseline = 'middle'; //ctx.direction = 'rtl'; //ctx.strokeText(str,x0,y0); ctx.fillText(str,x0,y0); /*6.畫一個下劃線和文字同樣長*/ ctx.beginPath(); /*獲取文本的寬度*/ console.log(ctx.measureText(str)); var width = ctx.measureText(str).width; ctx.moveTo(x0-width/2,y0 + 20); ctx.lineTo(x0+width/2,y0 + 20); ctx.stroke(); </script> </body> </html>
別人罵我胖,我會生氣,由於我內心認可了我胖。別人說我矮,我就會以爲可笑,由於我內心知道我不可能矮。這就是咱們爲何會對別人的攻擊生氣。 攻我盾者,乃我心裏之矛(11)