canvas绘制路径时,什么方法用于关闭路径,canvas绘制箭头路径效果

  canvas绘制路径时,什么方法用于关闭路径,canvas绘制箭头路径效果

  在画布绘制环境中,有些绘制方法属于立即绘制图形,有些绘制方法是基于路径的。

  只有两种方法可以立即绘制图形:strokerect()和fillrect()。虽然strokeztext()和filltext()也是立即绘制的,但文本不是图形。

  基于路径的绘制系统

  大多数绘图系统,如SVG(可缩放矢量图形)和Adobe Illustrator,都是基于路径的。

  使用这些绘图系统时,需要先定义一个路径,然后描边或填充。您也可以描边和填充它,以便显示图形。

  画布中的三种绘图方法:

  

  绘制一条线段

  在画布绘制环境中,线段也是基于路径绘制的,这种路径称为线性路径。创建线性路径的方法有moveTO()和lineTo()。创建路径后,调用stroke()方法在画布中绘制线段。

  这就是我们前面提到的基于路径的绘制方法,必须是描边或者填充;

  通常两点由一条线连接,所以画线段是很简单的。通过moveTO()指定直线的起点,并通过lineTo()将其移动到另一个点。

  函数drawLine(){ cxt.moveTo(50,50);cxt.lineTo(100,100);}但是,这样一来,我们就看不到画布中的线段了。前面讲了基于路径的画法,必须是描边或者填充。所以要看到结果,还必须使用stroke()方法。

  因此,我们将方法修改如下,以便绘制一条线段。

  函数drawLine(){ cxt.moveTo(50,50);cxt.lineTo(200,200);cxt . stroke();}

  我们只能通过使用lineTo()在画布中绘制线段。我们把上面的代码改成下面的,效果是一样的。

  函数drawLine(){ cxt.lineTo(50,50);cxt.lineTo(200,200);cxt . stroke();}总结moveTo()和lineTo()的用法

  Move (x,y):将笔画移动到指定的坐标x和y,并在当前路径中添加一个子路径。此方法不会清除当前路径中的任何子路径。LineTo(x,y):从当前位置到指定的x和y位置绘制一条直线。如果当前路径中没有子路径,那么这个方法的行为类似于moveTo()。如果当前路径中有子路径,此方法会将您指定的点添加到子路径中。改变线段的样式

  更改线段的宽度

  函数=14;cxt.lineTo(50,50);cxt.lineTo(200,200);cxt . stroke();}

  改变线段的颜色

  函数drawLine(){ cxt . line width=14;cxt.strokeStyle= greencxt.lineTo(50,50);cxt.lineTo(200,200);cxt . stroke();}

  我们还可以使用CanvasGradient对象或CanvasPattern对象为线段添加渐变或图案。

  函数drawLine(){ cxt . line width=14;var gradient=cxt . createlineargradient(0,0,canvas.width/2, canvas . height/2);gradient.addColorStop(0,蓝色);gradient.addColorStop(0.5,紫色);gradient.addColorStop(1,黄色);cxt.strokeStyle=gradientcxt.lineTo(50,50);cxt.lineTo(200,200);cxt . stroke();}

  beginPath()与closePath()

  我们从上面canvas中的三种绘制方法可以看出,第二行的圆弧路径是开放路径,最后一行的圆弧路径是封闭路径。那么封闭路径是如何实现的呢?

  我们来看看画布中路径绘制的两种重要方法。

  BeginPath():清除所有当前子路径以重置当前路径并规划新路径。ClosePath():用于关闭一个开放路径。不需要。如果图形已经闭合,也就是说,当前点是起点,则此函数不执行任何操作。先画一条虚线。

  函数drawLine(){ cxt . stroke style= green ;cxt . line width=2;cxt.moveTo(50,50);cxt.lineTo(50,150);cxt.lineTo(150,150);cxt . stroke();}

  修改上面示例中的代码,将beginPath()和closePath()方法添加到代码中。

  函数drawLine(){ //笔画三角形cxt.strokeStyle= greencxt . line width=2;cxt . begin path();cxt.moveTo(50,50);cxt.lineTo(50,150);cxt . stroke();cxt . begin path();cxt.lineTo(150,150);cxt.lineTo(150,250);cxt . stroke();cxt . close path();}

  你可以看到我们在画布上画了两条路径。

  注意:调用beginPath()后,或者第一次构建canvas时,第一个路径构造命令通常被认为是moveTo()。所以我们在画图形的时候首先要用beginPath()。

  我们继续修改我们的代码。

  函数drawLine(){ //笔画三角形cxt.strokeStyle= greencxt . line width=2;cxt . begin path();cxt.moveTo(50,50);cxt.lineTo(50,150);cxt.lineTo(150,150);cxt . close path();cxt . stroke();//polyline cxt.translate(150,0);cxt.strokeStyle= redcxt . line width=2;cxt . begin path();cxt.moveTo(50,50);cxt.lineTo(50,150);cxt.lineTo(150,150);cxt . stroke();cxt . close path();//绿色填充三角形cxt.translate(150,0);cxt.fillStyle= greencxt . line width=2;cxt . begin path();cxt.moveTo(50,50);cxt.lineTo(50,150);cxt.lineTo(150,150);cxt . fill();cxt . close path();//红色填充三角形cxt.translate(150,0);cxt.fillStyle= redcxt . line width=2;cxt . begin path();cxt.moveTo(50,50);cxt.lineTo(50,150);cxt.lineTo(150,150);cxt . close path();cxt . fill();}

  从上面的例子可以看出,closePath()的位置不同也会影响我们的图形。

  注意:调用fill()函数时,所有未闭合的形状都会自动闭合,所以此时不需要closePath()函数。

  但是调用stroke():如果在stroke()方法之前只使用closePath(),就会形成一个封闭的路径。如果在stroke()方法之后调用closePath()方法,图形已经绘制完成,当前绘制路径已经闭合,那么closePath()方法不起作用。

  线段与像素边界

  我们先来看一个例子。

  函数drawLine(){ //笔画三角形cxt . line width=1;cxt . begin path();cxt.moveTo(50,50);cxt.lineTo(450,50);cxt . stroke();cxt . begin path();cxt.moveTo(50.5,150.5);cxt.lineTo(450.5,150.5);cxt . stroke();}

  从图中我们可以看到,我们将两条线段的线宽设置为1个像素,但是上面的线段画了两个像素。

  如果在某个2像素的边界处画一条1像素宽的线段,该线段实际会占用2像素的宽度;

  因为当你在一个像素的边界处画一条宽度为1个像素的垂直线段时,canvas的绘图环境对象会尝试在边界中心线的右侧画一半的像素,在边界中心线的左侧画另一半的像素。

  但是不可能在整个像素范围内画出半个像素宽的线段,所以把左右方向的一半像素扩展为一个像素。

  另一方面,它被绘制在两个像素之间。这样中线左右两端的半个像素就不会延伸,组合起来正好占据1个像素的宽度。所以,如果你想画一个1像素宽的线段,你必须画两个像素之间的线段。

  网格的绘制

  现在我们知道了如何画一个真正的1像素线段,让我们开始画一个网格。

  函数drawLine(stepx,stepy){ cxt . line width=0.5;cxt.strokeStyle= green//画垂直线为(var i=stepx 0.5I cxt . canvas . width;I=stepx){ cxt . begin path();cxt.moveTo(i,0);cxt.lineTo(i,cxt . canvas . height);cxt . stroke();}//为(var i=stepy 0.5画一条水平线;I cxt . canvas . height;I=stepy){ cxt . begin path();cxt.moveTo(0,I);cxt.lineTo(cxt.canvas.width,I);cxt . stroke();}}drawLine(10,10);

  在上面的例子中,我们在两个像素之间的像素上画线段,画出的线段只有0.5个像素宽。

  虽然canvas规范中没有明文规定,但是所有浏览器的Canvas实现都使用了反走样技术来创建亚像素线段的绘制效果。

  总结

  本节主要讲解canvas中直线路径的绘制方法,主要使用moveTo()定义起点,lineTo()定义终点,stroke()描绘当前路径。这三种方法画线段。

  在canvas中绘制路径有两种重要的方法,beginPath()和closePath()。在绘制一个图之前调用beginPath()是绘制多个图的必要步骤。

  使用fill()时可以省略ClosePath(),还要注意closePath()方法的调用位置。

  在画线段的时候,我们可以用lineWidth来改变线段的宽度,用strokeStyle来改变线段的颜色。

  弄清楚线段的像素边界,这样我们就可以画出线宽为1个像素的真实线段。

  对画布绘制图形感兴趣的同学,请随时关注后续更新,如有错误,请指出,多交流。

  这就是本文的全部内容。希望对大家的学习和支持有帮助。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: