html5基础入门教程之canvas绘制图形

canvas绘制图形

在正式开始讲如何利用canvas绘制图形前,先介绍下canvas的网格。

在上面的例子中,最后一个例子里绘制了两个正方形,拿其中的红色正方形来讲。运行代码后,会发现它离左上角有一定的距离。这个距离是由传进的参数来决定的,是(10,10)。这表示这个正方形的原点的坐标。在canvas网格中,原点定在左上角的位置(坐标(0,0))。所有canvas里所绘制的图形的位置都是相对这个原点的。看下图,这个蓝色的方块的位置就是距离左边x像素,距离上边y像素,即它的坐标是(x,y)。实际上,是(x-0,y-0),由于canvas定原点坐标为(0,0)所以便是(x,y)。

canvas_default_grid
(素材来源:Canvas Tutorial 中文, Mozilla )

绘制矩形

有三个函数可以用于绘制矩形,分别是:

fillRect(x,y,width,height) //填充一个矩形
strokeRect(x,y,width,height) //绘制一个矩形的边框(但不填充矩形的内部)
clearRect(x,y,width,height) //擦出了指定的矩形,并且用一个透明的颜色填充

以上三个函数都有四个参数,其中x,y表示矩形左上角的坐标,即相对于原点的位置;width,height指定了矩形的宽高。

其中,fillRect()方法用fillStyle属性所指定的颜色、渐变和模式来填充指定的矩形;strokeRect()方法所绘制的矩形边框,线条的颜色和线条宽度由strokeStyle和lineWidth属性指定。矩形边角的形状由lineJoin属性指定。

绘制矩形示例:

rectangle

function draw(){
     var canvas=document.getElementById('testRectangle');
	 if(canvas.getContext){
	    var ctx=canvas.getContext('2d');
		ctx.fillRect(25,25,100,100);
		ctx.clearRect(45,45,60,60);
		ctx.strokeRect(50,50,50,50);
	 }
  }

这个例子,fillRect()方法绘制了一个100X100的黑色矩形(没有使用fillStyle设置填充色的话,默认的都是黑色的背景),它左上角的坐标为(25,25);接着,clearRect()方法在原先的基础上,清除了一个60×60的矩形,它左上角的坐标是(45,45);最后,利用strokeRect()方法,绘制了一个50×50大小的矩形边框,它左上角的坐标为(50,50)。

绘制路径

与绘制路径相关的函数有:

beginPath()
closePath()
stroke()
fill()

beginPath()丢弃任何当前定义的路径并且开始一条新的路径。它把当前的点设置为(0,0)。当一个画布的环境第一次创建时,beginPath()方法会被显示地调用。

closePath()创建从当前点到开始点的路径。

stroke()方法绘制当前路径的边框。它意味着画轮廓,但是线条的可视化取决于strokeStyle、lineWidth、lineJoin、lineCap和miterLimit等属性。

fill()方法用于填充路径,默认是黑色。fill()方法使用fillStyle属性所指定的颜色、渐变和模式来填充当前路径。当调用该方法时,开放的路径会自动闭合。

绘制路径需要经过下面四个步骤:

第一步:用beginPath创建一条路径。

第二步:实际绘制路径的部分。

第三步:调用closePath方法关闭路径。如果图形已闭合或者它只是一个点,那么这个方法将什么也不会做。这一步不是必须的

第四步:调用stroke或fill方法,绘制边框或者填充路径。

绘制路径示例:

path

function draw(){
	  var canvas=document.getElementById('testPath');
	  if(canvas.getContext){
	     var cxt=canvas.getContext('2d');
		 cxt.beginPath();
		 cxt.moveTo(75,50);
		 cxt.lineTo(100,75);
		 cxt.lineTo(100,25);
		 cxt.fill();
	  }
	}

上面这个例子,绘制了一个三角形。首先,利用beginPath()方法创建一条路径;moveTo()方法将点移动到坐标(75,50)(moveTo()方法接下来就会讲到);lineTo()方法画了两条直线;最后调用fill()方法填充路径,调用了这个方法后,路径就自然闭合了,所以不必再调用closePath()方法来闭合路径。

moveTo()方法

上面的例子有用到moveTo()这个方法,这边就来说说moveTo()方法。语法如下:

moveTo(x,y)

moveTo()方法用于定位绘画的位置,即将点移动到参数x,y所指定的坐标位置。

canvas初始化或者调用了beginPath()方法时,绘画开始的位置即原点(0,0),使用moveTo()方法,我们可以将起始位置移动到任何我们想要的地方。

moveTo()的使用实例:

moveTo

function draw(){
	 var canvas=document.getElementById('test_moveTo');
	 if(canvas.getContext){
	    var cxt=canvas.getContext('2d');
		cxt.beginPath();
		cxt.arc(75,75,50,0,Math.PI*2,true);
		cxt.moveTo(100,75);
		cxt.arc(75,75,35,0,Math.PI,false);
		cxt.moveTo(65,65);
		cxt.arc(60,65,5,0,Math.PI*2,true);
		cxt.moveTo(95,65);
		cxt.arc(90,65,5,0,Math.PI*2,true);
		cxt.stroke();
	 }
   }

绘制各种线条

用lineTo()方法来画直线。

lineTo()方法接受终点的坐标(x,y)作为参数。起始坐标取决于前一路径的终点坐标。当然,起始坐标也可以通过前面介绍的moveTo()方法来设置。

绘制线条示例:

lineTo

function draw(){
	 var canvas=document.getElementById('test_lineTo');
	 if(canvas.getContext){
	    var cxt=canvas.getContext('2d');
		cxt.beginPath();
		cxt.moveTo(25,25);
		cxt.lineTo(105,25);
		cxt.lineTo(25,105);
		cxt.fill(); //fill填充路径,会自动闭合路径。
		cxt.beginPath();
		cxt.moveTo(125,125);
		cxt.lineTo(125,45);
		cxt.lineTo(45,125);
		cxt.closePath();
		cxt.stroke(); //stroke不会闭合路径,所以再描边先要先闭合路径
	 }
   }

上面的例子利用lineTo()方法绘制了两个三角形。从这个例子也可以看出fill和stroke的区别。

绘制弧线

用arc方法来绘制弧线或圆。

arc(x, y, radius, startAngle, endAngle, anticlockwise)

该方法接受五个参数。其中,x,y是圆心坐标;radius是圆的半径;startAngle和endAngle分别是起末弧度(以x轴为基准);anticlockwise为true表示逆时针,反之为顺时针。

这边有一点是需要注意的,就是arc方法里的角度是以弧度为计算单位的,不是度。这么说吧,通常我们说的180度,就等价于PI。两者的计算公式是这样的:radians=(Math.PI/180)*degrees.(其中,radians代表弧度,degrees代表度)

绘制圆弧示例:

arc

function draw(){
     var canvas=document.getElementById('test_arc');
	 if(canvas.getContext){
	    var ctx=canvas.getContext('2d');
		for(var i=0; i<4; i++){       //输出4行4列的矩阵
		   for(var j=0; j<4; j++){
		      ctx.beginPath();
			  var x=25+j*50;     //圆心x坐标
			  var y=25+i*50;     //圆心y坐标
			  var radius=20;     //半径
			  var startAngle=0;  //起始弧度
			  var endAngle=Math.PI/2+(Math.PI*j)/2;  //结束弧度
			  var anticlockwise=i%2==0?false:true; //奇数行顺时针;偶数行逆时针。
			  ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise);  //循环绘制圆/圆弧
			  if(i>1){
			     ctx.fill();   //3,4行填充图案
			  }else{
			     ctx.stroke(); //1,2行仅勾勒路径
			  }
		   }
		}
	 }
  }

上面这个例子,用双层循环输出了4*4的圆弧矩阵。

贝塞尔和二次方曲线

最后,要说的是贝赛尔曲线,它可以是二次和三次的形式,一般用于绘制复杂而有规律的形状。

二次贝赛尔曲线:

quadraticCurveTo(cpx, cpy, x, y)

其中,cpx指控制点的x坐标;cpy指控制点的y坐标;x指结束点的x坐标;y指结束点的y坐标。

quadraticCurveTo

由上面的参数可以看出,二次贝赛尔曲线需要两个点:第一个点用于二次贝赛尔计算中的控制点,第二个点是曲线的结束点。曲线的开始点是当前路径中最后一个点。如果路径不存在,可使用beginPath()和moveTo()方法来定义。

一个简单的二次贝赛尔曲线实例:

quadraticCurveTo

function draw(){
     var canvas=document.getElementById('test_quadraticCurveTo');
	 if(canvas.getContext){
	    var ctx=canvas.getContext('2d');
		ctx.beginPath();
		ctx.moveTo(75,25);
		ctx.quadraticCurveTo(25,25,25,62);
		ctx.quadraticCurveTo(25,100,50,100);
		ctx.quadraticCurveTo(50,120,30,125);
		ctx.quadraticCurveTo(60,120,65,100);
		ctx.quadraticCurveTo(125,100,125,62);
		ctx.quadraticCurveTo(125,25,75,25);
		ctx.stroke();
	 }
  }

三次贝赛尔曲线:

bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)

其中,cp1x为第一个控制点的x坐标;cp1y为第一个控制点的y坐标;cp2x为第二个控制点的x坐标;cp2y为第二个控制点的y坐标;x为结束点的x坐标;y为结束点的y坐标。

bezierCurveTo

由上面可以看出,三次贝赛尔曲线需要三个点。前两个点用于三次贝赛尔计算中的控制点,第三个点是曲线结束的控制点。同上,曲线的开始点是当前路径中最后一个点。如果路径不存在,可使用beginPath()和moveTo()方法来定义。

新建一个前端学习qun438905713,在群里大多数都是零基础学习者,大家相互帮助,相互解答,并且还准备很多学习资料,欢迎零基础的小伙伴来一起交流。

使用二次方和三次方的贝塞尔曲线是相当有挑战的,因为不像在矢量绘图软件 Adobe Illustrator 里那样有即时的视觉反馈。因为用它来画复杂图形是比较麻烦的。但如果你有时间,并且最重要是有耐心,再复杂的图形都可以绘制出来的。下面我们来画一个简单而又规律的图形。

一个简单的三次贝赛尔曲线实例:

bazierCurveTo

function draw(){
     var canvas=document.getElementById('test_quadraticCurveTo');
	 if(canvas.getContext){
	    var ctx=canvas.getContext('2d');
		ctx.beginPath();
		ctx.moveTo(75,40);
		ctx.bezierCurveTo(75,37,70,25,50,25);
		ctx.bezierCurveTo(20,25,20,62.5,20,62);
		ctx.bezierCurveTo(20,80,40,102,75,120);
		ctx.bezierCurveTo(110,102,130,80,130,62);
		ctx.bezierCurveTo(130,62.5,130,25,100,25);
		ctx.bezierCurveTo(85,25,75,37,75,40);
		ctx.fill();
	 }
  }

canvas应用图像

发布了69 篇原创文章 · 获赞 33 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/webxuexi168/article/details/104365004