canvas教程

Canvas学习5:线型 Rockyxia Web技术博客

字号+ 作者:H5之家 来源:H5之家 2017-08-10 17:00 我要评论( )

写在前面 在绘制线段一文中,了解到如何在Canvas中绘制线段。虽然使用Canvas中API可以很轻松的绘制出线段,但里面还是有不少的细节需要了解。这篇文章咱们就来了

你的位置:Rockyxia Web技术博客 > 连载教程 > Canvas > Canvas学习5:线型

Canvas学习5:线型

Canvas rockyxia 2个月前 (06-19) 244浏览

写在前面

在绘制线段一文中,了解到如何在Canvas中绘制线段。虽然使用Canvas中API可以很轻松的绘制出线段,但里面还是有不少的细节需要了解。这篇文章咱们就来了解线段中的线型。

Canvas中的线型主要包括线宽、线段端点和线段连接点三个部分。那么咱们先来了解线宽。

线宽

通过前面的示例,我们不难发现,在Canvas中通过lineWidth属性来定义线段的粗细。我们可以给其明确指定一个value值,在没有显式设置lineWidth的值时,为以默认值1来确定线段的粗细。

那什么叫线宽呢?在Canvas中,线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半。因为画布的坐标并不和像素直接对应,当需要获得精确的水平或垂直线的时候要特别注意。

想要获得精确的线条,必须对线条是如何绘制出来的有所理解。比如下图,用网格来代表canvas的坐标格,每一格对应屏幕上一个像素点。在左侧图中,填充了(2,1)至5,5的矩形,整个区域的边界刚好落在像素边缘上,这样得到的矩形有着清晰的边缘。如果你想要绘制一条从(3,1)至(3,5),宽度是1.0的线条,就会得到下图中间图一样的结果。实际填充区域(深蓝色部分)仅仅延伸至路径两旁各一半像素,而这半个像素以会以近似的方式进行渲染,这意味着那些像素只是部分着色,结果就是以实际笔触颜色一半色调的颜色来填充整个区域(浅蓝和深蓝的部分)。这就是上例中为何宽度为1.0的线并不准确的原因。要解决这个问题,必须对路径施予更加精确的控制。已经知道1.0的线条会在路径两边各延伸0.5个像素,那么像下图最右侧的那样绘制的线条(从(3.5,1)至(3.5,5)),其边缘正好落在像素边界,填充出来就是准确的宽为1.0的线条。

特别注意,在Canvas中绘制1个像素的线条时,坐标位置需要错开0.5个像素。

另外在Canvas中绘制路径(线段)时,后面显式设置的lineWidth会覆盖前面的值。比如:

function drawScreen () { ctx.strokeStyle = "red"; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(30,30); ctx.lineTo(300,30); ctx.stroke(); ctx.lineWidth = 40; ctx.beginPath(); ctx.moveTo(30,60); ctx.lineTo(300,60); ctx.stroke(); }

线段端点

在绘制线段时,可以控制线段端点,这个线段端点也称为线帽。在Canvas的绘图环境中,控制线段端点绘制有一个属性叫CanvasRenderingContext2D.lineCap。

CanvasRenderingContext2D.lineCap有三个值:butt、round和square,其中默认的值是butt。

来看一个小示例:

ctx.lineWidth = 30; ctx.beginPath(); ctx.lineCap = 'butt'; ctx.moveTo(30,30); ctx.lineTo(400,30); ctx.fillText('butt', 410, 40); ctx.stroke(); ctx.beginPath(); ctx.lineCap = 'round'; ctx.moveTo(30,100); ctx.lineTo(400,100); ctx.fillText('round', 430, 110); ctx.stroke(); ctx.beginPath(); ctx.lineCap = 'square'; ctx.moveTo(30,180); ctx.lineTo(400,180); ctx.fillText('square', 430, 190); ctx.stroke();

上图中,两条蓝色线突出的部分就是在Canvas中所谓的线帽,也就是线段端点。

你可以通过下面的示例,选择表单对应的值,能看到lineCap的效果:

线段连接点

在Canvas中绘制路径(线段),它总有可能会有相连的部分,比如说绘制的一个矩形。那么每两条线段相交的点就是线段的连接点。那么在Canvas中怎么控制线段连接点效果呢?在Canvas中,可以通过CanvasRenderingContext2D.lineJoin来控制。

CanvasRenderingContext2D.lineJoin同样有三个值:round、bevel和miter,其中miter是其默认值。

来看一个小示例:

function drawScreen () { ctx.font = "24px Arial"; ctx.strokeStyle = "#f9f"; ctx.lineWidth = 30; ctx.beginPath(); ctx.lineJoin = 'miter'; ctx.moveTo(30,50); ctx.lineTo(120,50); ctx.lineTo(120,280); ctx.fillText('miter', 40, 20); ctx.stroke(); ctx.beginPath(); ctx.lineJoin = 'round'; ctx.moveTo(180,50); ctx.lineTo(280,50); ctx.lineTo(280,280); ctx.fillText('round', 200, 20); ctx.stroke(); ctx.beginPath(); ctx.lineJoin = 'bevel'; ctx.moveTo(350,50); ctx.lineTo(450,50); ctx.lineTo(450,280); ctx.fillText('bevel', 370, 20); ctx.stroke(); }

lineJoin相对于lineCap要更为复杂一点点。咱们来看下面这张图:

先来看bevel值,两条线段相交的时候,将会用一条直线来连接两个拐角外部的点,使之构成一个三角形。miter的效果和bevel有点类似,只是它还会再画一个三角形,使两个线段的接合处变为一个矩形。而round会使两个线段的拐角处就会画上一段填充好的圆弧。

来看一个动态示例:

只不过取值为miter时,还可以指定一个miterLimit属性,表示连接点(矩形的斜线)计算方式。斜线的长度与二分之一线宽的比值。如下图所示:

其实这个斜线的长度就是一个直角三角形的边长。

function drawScreen () { ctx.strokeStyle = "#f9f"; ctx.lineWidth = 30; ctx.beginPath(); ctx.moveTo(10,60); ctx.lineTo(140,60); ctx.lineTo(140,280); ctx.stroke(); ctx.beginPath(); ctx.moveTo(250,100); ctx.lineTo(450,80); ctx.lineTo(300,280); ctx.stroke(); }

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • js+canvas绘制五角星的方法

    js+canvas绘制五角星的方法

    2017-08-11 10:00

  • HTML5 Canvas API中drawImage()方法的使用实例

    HTML5 Canvas API中drawImage()方法的使用实例

    2017-08-09 11:01

  • 图片(旋转/缩放/翻转)变换效果(ccs3/滤镜/canvas)

    图片(旋转/缩放/翻转)变换效果(ccs3/滤镜/canvas)

    2017-08-08 15:04

  • H5 canvas实现贪吃蛇小游戏

    H5 canvas实现贪吃蛇小游戏

    2017-08-07 14:00

网友点评