html5新增的canvas標(biāo)簽允許腳本語言動(dòng)態(tài)渲染位圖像,在基于Web的圖像顯示方面比Flash更加立體二驰,也更加精巧.現(xiàn)在我們先來用canvas標(biāo)簽實(shí)現(xiàn)一個(gè)簡(jiǎn)單的餅狀圖.
最終效果圖:
-
基礎(chǔ)
canvas標(biāo)簽本身不具有繪圖功能,我們必須借助js在網(wǎng)頁上繪制圖像,所以我們?cè)趆tml中添加一個(gè)canvas標(biāo)簽,并加上一個(gè)id值,以便我們能夠獲取這個(gè)標(biāo)簽做下一步操作:
html:
<canvas id="canvas" width="900" height="600" style="border: 1px solid #000;">你
的瀏覽器不支持canvas,請(qǐng)升級(jí)瀏覽器.(瀏覽器不支持,顯示此行文本)</canvas>
.................................................................................
<script>
//1.獲取canvas標(biāo)簽
var canvas = document.getElementById('canvas');
//2.獲取上下文(當(dāng)前是2d)
var ctx = canvas.getContext('2d');
</script>
幾個(gè)注意點(diǎn):
①canvas是一張畫布,本身沒有內(nèi)容.我們需要用js代碼在上面''畫畫'';
②畫布的大小必須是如上的行內(nèi)設(shè)置width和height屬性,不能使用css設(shè)置畫布的大小(css設(shè)置會(huì)使畫布拉升,使得我們得不到對(duì)應(yīng)像素的圖片,畫出的圖片也會(huì)變形);
③js獲取canvas標(biāo)簽之后,需要先初始化一個(gè)執(zhí)行環(huán)境canvas.getContext('2d')是畫2d圖片,canvas.getContext('webgl')為3d圖片,所有的線條圖片都是基于這個(gè)'ctx'環(huán)境來畫的;
④canvas只兼容ie9及以上版本瀏覽器,所以要在標(biāo)簽中設(shè)置版本不兼容提示語句.
-
畫弧(圓)準(zhǔn)備工作
ctx.beginPath():開始一段新路徑(告訴瀏覽器要開始畫畫了);
ctx.moveTo():繪制的初始位置;
ctx.lineWidth:繪制線條寬度;
ctx.strokeStyle:繪制線條顏色(color值);
ctx.fillStyle:圖塊填充顏色(color值);
ctx.fill():執(zhí)行圖塊填充(需放在所有屬性設(shè)置的后面);
ctx.stroke():執(zhí)行繪制(需放在所有屬性設(shè)置的后面);
Math.PI: 數(shù)學(xué)中的π弧度(換算公式deg*Math.PI/180);
ctx.font:繪制文字設(shè)置字號(hào),字體;
ctx.fillText(text, textX, textY):文字內(nèi)容與位置設(shè)置;
ctx.arc(x0,y0,r,beginAngel,endAngel,counterclockwise):弧的一些屬性設(shè)置;
x0:圓心的x值(相對(duì)于畫布); y0:圓心的y值(相對(duì)于畫布);
r:圓的半徑;
beginAngel:開始角度; endAngel:結(jié)束角度;
counterclockwise:true(逆時(shí)針)/ false(順時(shí)針,默認(rèn)屬性);
- 案例分析
此餅狀圖分為5份,每份都有自己的屬性(所屬城市,顏色,所占比例),所以我們首先應(yīng)該定義一個(gè)數(shù)據(jù)包(數(shù)組),根據(jù)數(shù)據(jù)包中城市所占的比例值,我們計(jì)算出每個(gè)城市圓的角度,通過角度來渲染對(duì)應(yīng)的顏色;整體思路就是這樣.
- 實(shí)現(xiàn)代碼
var canvas=document.getElementById('canvas');
var ctx=canvas.getContext('2d');
//1.創(chuàng)建數(shù)據(jù)包(信息)
var infoArr = [
{name:'北京', color:'yellow', value:0.3},
{name:'上海', color:'red', value:0.2},
{name:'廣州', color:'green', value:0.1},
{name:'深圳', color:'purple', value:0.15},
{name:'天津', color:'blue', value:0.25}
];
//2.定義圓心
var x0 = canvas.width * 0.5, y0 = canvas.height * 0.5;//顯示在畫布中間
//2.1定義半徑
var radius = 150;
//2.2定義起始角度
var beginAngle = -90 *Math.PI/180;(定義初始角度為-90deg)
//3.遍歷,繪制扇形
for (var i = 0; i < dataArr.length; i++) {
//3.1扇形角度
var tempAngle = dataArr[i].value * 360 *Math.PI/180;
//3.2結(jié)束角度
var endAngle = beginAngle + tempAngle;
//3.3開啟路徑
ctx.beginPath();
//3.4起點(diǎn)
ctx.moveTo(x0, y0);
//3.5繪制弧度
ctx.arc(x0, y0, radius, beginAngle, endAngle);
//3.6設(shè)置顏色
ctx.fillStyle = dataArr[i].color;
//3.7填充
ctx.fill();
//4.繪制文字
//4.1常量
var textAngle = beginAngle + tempAngle * 0.5; //角度
var text = dataArr[i].name + dataArr[i].value * 100 + '%';
console.log(text);
//4.2文字坐標(biāo)
var textX = x0 + (radius + 30) * Math.cos(textAngle);
var textY = y0 + (radius + 30) * Math.sin(textAngle);
//4.3文字字號(hào)和字體
ctx.font = "20px '微軟雅黑'";
//4.4判斷文字是否在左邊
if((textAngle > 90 *Math.PI/180) && (textAngle < 270 *Math.PI/180) ) {
ctx.textAlign = 'end';//文字的右側(cè)在基線的左端
}
//4.5 繪制文字
ctx.fillText(text, textX, textY);
//5.更新起始角度, 將當(dāng)前扇形的結(jié)束角度作為下一個(gè)扇形的起始角度
beginAngle = endAngle;
}
代碼每一步驟都有對(duì)應(yīng)分析,最重要的是整個(gè)過程的思路分析,有不明白的歡迎簡(jiǎn)信我,有不足之處也歡迎指正,O(∩_∩)O謝謝大家!