一、矩形绘制
①rect(x,y,w,h)绘制矩形路径,不是独立路径,起点是x,y,宽是w,高是h
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); // 在(100,50)处画一个宽200,高100的矩形,描边 ctx.beginPath(); ctx.rect(100,50,200,100); ctx.stroke(); // 在(100,200)处画一个宽200,高100的矩形,填充 ctx.beginPath(); ctx.rect(100,200,200,100); ctx.fill(); </script> </body> </html>
②strokeRect(x,y,w,h)绘制描边矩形,有独立路径
③fillRect(x,y,w,h)绘制填充矩形,有独立路径
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); // 绘制一个描边矩形 ctx.strokeRect(100,100,200,100); // 绘制一个填充矩形 ctx.fillRect(100,250,200,100); </script> </body> </html>
④clear(x,y,w,h)擦除矩形区域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); ctx.fillRect(100,100,200,200); // 擦除区域 ctx.clearRect(100,100,100,100); </script> </body> </html>
⑤绘制一个颜色渐变的矩形
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); // 绘制一个线性渐变的矩形 var linearGradient=ctx.createLinearGradient(100,50,400,100); linearGradient.addColorStop(0,'red'); linearGradient.addColorStop(0.5,'green'); linearGradient.addColorStop(1,'blue'); ctx.beginPath(); ctx.fillStyle=linearGradient; ctx.fillRect(100,50,400,100); // 绘制一个径向渐变的矩形 var radialGradient=ctx.createRadialGradient(350,250,150,100,150,150); radialGradient.addColorStop(0,'red'); radialGradient.addColorStop(0.5,'green'); radialGradient.addColorStop(1,'blue'); ctx.beginPath(); ctx.fillStyle=radialGradient; ctx.fillRect(100,200,400,100); </script> </body> </html>
二、圆弧绘制
①弧度的概念:一个角度等于π/180弧度
②曲线的绘制:曲线也是由点构成的
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); // 曲线1 ctx.beginPath(); for(var i=1;i<1000;i++){ var x=i; var y=Math.pow(x-50,2); ctx.lineTo(x,y); } ctx.stroke(); // 曲线2 ctx.beginPath(); for(var i=1;i<1000;i++){ var x=i; var y=50*Math.sin(x/10)+100; ctx.lineTo(x,y); } ctx.stroke(); </script> </body> </html>
③绘制圆弧:arc(x,y,r,startAngle,endAngle,bool)
- x表示圆心横坐标,y表示圆心纵坐标,r表示圆半径
- startAngle表示开始的角度,endAngle表示结束的角度
- bool 默认是false,表示顺时针,设置成true,表示逆时针
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); var w=ctx.canvas.width; var h=ctx.canvas.height; // 四分之一圆 ctx.beginPath(); ctx.arc(w/4,h/4,150,Math.PI/2,Math.PI,false); ctx.stroke(); // 四分之三圆 ctx.beginPath(); ctx.arc(w/2,h/2,150,Math.PI/2,Math.PI,true); ctx.stroke(); </script> </body> </html>
④绘制扇形(填充)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); 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); ctx.fill(); </script> </body> </html>
⑤绘制一个分成n等分颜色随机的圆
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); // 获取宽高 var w=ctx.canvas.width; var h=ctx.canvas.height; // 分成几等分 var num=10; // 一份多少弧度 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> </body> </html>
⑥绘制根据数据占比不等分的饼图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); // 获取宽高 var w=ctx.canvas.width; var h=ctx.canvas.height; // 分成几等分 var num=10; // 一份多少弧度 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> </body> </html>
三、文本绘制
①strokeText(txt,x,y) 文本描边,txt表示文本,x和y是起始坐标(文本的左下角)
②font=‘ ’ 可以设置字体样式,字体大小(没有单位)
③fillText(txt,x,y)文本填充,txt表示文本,x和y是起始坐标(文本的左下角)
④textAlign=“ ” 可以设置left,center,right,end,start等
⑤direction 属性css(rtl ltr)start和end于此相关
⑥textBaseline=“ ” 垂直对齐方式,常用的有top,bottom,middle
⑦measureText() 获取文本宽度,obj.width
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); // 准备一段文字,确定画布的中心,画一个十字 var str='亚历山大'; var w=ctx.canvas.width; var h=ctx.canvas.height; 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(); // 绘制文本 ctx.beginPath(); var x0=w/2; var y0=h/2; ctx.font='40px Microsoft YaHei'; ctx.textAlign='center'; ctx.textBaseline='middle'; ctx.fillStyle='red'; ctx.fillText(str,x0,y0); // 绘制文本的下划线 ctx.beginPath(); console.log(ctx.measureText(str));//TextMetrics {width: 160} var width=ctx.measureText(str).width; ctx.moveTo(x0-width/2,y0+20); ctx.lineTo(x0+width/2,y0+20); ctx.strokeStyle='#000'; ctx.stroke(); </script> </body> </html>
四、饼图绘制(面向对象)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas图形绘制</title> <style> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas width="600" height="400"></canvas> <script> var myCanvas=document.querySelector("canvas"); var ctx=myCanvas.getContext('2d'); /* 饼图的构造函数 */ var PieChart=function(ctx){ // 绘制工具 this.ctx=ctx||document.querySelector('canvas').getContext('2d'); // 绘制饼图的原点和半径 this.w=this.ctx.canvas.width; this.h=this.ctx.canvas.height; this.x0=this.w/2+60;//+60为了空出左边的一些距离 this.y0=this.h/2; this.radius=150; // 伸出去线的长度 this.outLine=20; // 说明矩形的大小 this.rectW=30; this.rectH=16; this.space=20; } /* 初始化 */ PieChart.prototype.init=function(data){ // 画饼图 this.drawPie(data); }; /* 根据数据绘制一个饼图 */ PieChart.prototype.drawPie=function(){ var that=this; var angleList=this.transformAngle(data); var startAngle=0; angleList.forEach(function(item,i){ var endAngle=startAngle+item.angle; ctx.beginPath(); ctx.moveTo(that.x0,that.y0); ctx.arc(that.x0,that.y0,that.radius,startAngle,endAngle); var color=ctx.fillStyle=that.getRandomColor(); ctx.fill(); // 标题 that.drawTitle(startAngle,item.angle,color,item.title); // 说明 that.drawDesc(i,item.title); startAngle=endAngle; }); }; /* 绘制标题,从扇形的弧中心伸出一条线,再画一条横线,在横线上写上文字标题 */ PieChart.prototype.drawTitle=function(startAngle,angle,color,title){ // 计算伸出去的点的坐标 var edge=this.radius+this.outLine; var edgeX=Math.cos(startAngle+angle/2)*edge; var edgeY=Math.sin(startAngle+angle/2)*edge; var outX=this.x0+edgeX; var outY=this.y0+edgeY; // 绘制伸出去的线 this.ctx.beginPath(); this.ctx.moveTo(this.x0,this.y0); this.ctx.lineTo(outX,outY); this.ctx.strokeStyle=color; this.ctx.stroke(); // 绘制文字和下划线 this.ctx.font='14px Microsoft YaHei'; var textWidth=this.ctx.measureText(title).width; if(outX>this.x0){ this.ctx.lineTo(outX+textWidth,outY); this.ctx.textAlign='left'; }else{ this.ctx.lineTo(outX-textWidth,outY); this.ctx.textAlign='right'; } this.ctx.stroke(); this.ctx.textBaseline='bottom'; this.ctx.fillText(title,outX,outY); }; /* 在画布的左上角,绘制说明一个和扇形一样颜色的矩形,旁边是文字说明 */ PieChart.prototype.drawDesc=function(index,title){ this.ctx.fillRect(this.space,this.space+index*(this.rectH+10),this.rectW,this.rectH); this.ctx.beginPath(); this.ctx.textAlign='left'; this.textBaseline='top'; this.ctx.font='12px microsoft YaHei' this.ctx.fillText(title,this.space+this.rectW+10,this.space+index*(this.rectH+10)+15,this.rectW,this.rectH) }; /* 把数据转化弧度,并且把弧度追加到数据里 */ PieChart.prototype.transformAngle=function(data){ var total=0; data.forEach(function(item,i){ total=total+item.num; }); data.forEach(function(item,i){ var angle=item.num/total*Math.PI*2; item.angle=angle; }); return data; } PieChart.prototype.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+')'; } /* 数据 和 实例化对象 */ var data=[ {title:'10-20岁',num:5}, {title:'20-30岁',num:20}, {title:'30-40岁',num:15}, {title:'15-20岁',num:10} ] var pieChart=new PieChart(); pieChart.init(data); </script> </body> </html>