northwindx 2020-04-25
有关canvas之前有写过两篇文章
在绘制饼状图之前,我们先要理解什么是圆弧,如何在画布中绘制文字等等。所以这里将绘制饼状图理解拆分成以下几个步骤:
1、理解圆弧 2、绘制一段圆弧 3、绘制一个扇形 4、绘制一个六等圆 5、绘制一个根据数据的饼图 6、绘制在画布中心的一段文字 7、绘制完整饼状图
什么是弧度
弧度是一种长度的描述单位, 一个半径的长度就表示一弧度,所以一个圆有2*π个弧度。
效果
代码
<!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指定了规则
所以上面 Math.PI/2 到 Math.PI,且是 顺时针 的。由这两点最终绘制的就是上面的效果了。
效果
代码
<!-- 上面部分代码和上面一致,这里就不重复写了 --> <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; }); //2、计算每个数据所占的弧度 var angleList = []; data.forEach(function (item, i) { var angle = Math.PI * 2 * (item/total); angleList.push(angle); }); /* 3、获取随机颜色*/ 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)