html5Canvas画图教程(2)—画直线与设置线条的样式
如颜⾊端点交汇点
如果你还不知道Canvas是什么,可以看看上⼀篇.
在学画画的时候,线条是最基本的了,⽽线条的连接可以组成任何图形。在Canvas中也是如此。
在开始之前我们先拿出画布和画笔:
复制代码
代码如下:
var cvs = ElementById('cvs'); //画布
var ctx = Context('2d'); // 画笔
我们画画的时候,落笔点是不固定的,随时都会变。canvas虽然不是通过⼿来决定落笔点,但也有⼀个⽅法,就是moveTo。moveTo的作⽤相当于把笔尖提离画布,然后移动到指定的点(即坐标)。
复制代码
代码如下:
此过程中不会画出任何图形,相当于你提着笔在画布上晃来晃去。
但晃来晃去是没⽤的,我们必须开始画。先画最简单的:直线
画直线的⽅法即lineTo,他的参数和moveTo⼀样的,都是⼀个点。
ctx.lineTo(x,y)当然,你画线的时候,落笔点也跟着移动了,所以lineTo之后落笔点就变成了他的⽬标点了。
复制代码
代码如下:
ctx.lineTo(200,100);
此时你刷新⽹页,会发现画布上没有预想中的线,什么也没有。因为我们还少了⼀个步骤.lineTo其实是画的⼀条“路径”,本⾝是不可见的。如果要让他显⽰出来,我们必须对他进⾏“画”的操作。
⽤过PS的同学,肯定能知道图形的两种模式,⼀种是填充,另⼀种是描边。现在我们已经画了⼀条线,相当于PS中勾了⼀条路径,此时给路径描⼀下边,就能显⽰出图形了。
canvas描边的⽅法是stroke().现在让我们把代码补全:
复制代码
代码如下:
ctx.lineTo(200,100);
ctx.stroke();此时刷新,就能看到⼀条线了。当然,你也可以连续绘制出⼏百条路径,再执⾏描边动作,即可⼀下画出⼏百条线。现在我们来⽤4条线画⼀个矩形:
复制代码
代码如下:
ctx.lineTo(200,100);
ctx.lineTo(200,200);
ctx.lineTo(100,200);
ctx.lineTo(100,100);
ctx.stroke();
这⾥我们就是先绘出全部路径,再⼀次性描边。
——–作者的抱怨:Canvas绘图有个不好的地⽅就是:基本靠猜,很不直观。
严重提⽰:canvas的绘图过程(即填充与描边)是⾮常消耗资源的,如果想节省系统资源提⾼效率,最好是绘制好所有路
径,再⼀次性填充或描边图形。
由上⾯的图形我们可以看出,默认的线条粗细是1px,⽽线条颜⾊是⿊⾊。当然我们可以设置他们,但奇怪的是设置线条宽度是lineWidth,⽽设置线条样式的却叫strokeStyle,为什么不是lineStyle呢?我也不知道。:
复制代码
代码如下:
html5颜代码ctx.lineWidth = 10;
ctx.strokeStyle = 'rgba(255,0,0,0.5)';
上⾯的代码把线条宽度设置成了10px,线条颜⾊变成了半透明的红⾊。
如图1,刷新⼀下,好像有点不对呢!怎么左上⾓缺了⼀⼩块似得?这不是错觉。原因嘛要从canvas的线条绘制⽅式说起。
问题:如果我画的矩形路径是宽⾼都是100,此时我的边线宽度是10px,那么这个描了边的矩形整体宽⾼是多少?是
100+10*2=120吗?
如果边线是完全描在路径外侧的话,那么就是120。但Canvas不是。Canvas中的线条都有⼀条“中线”,这条中线位于line的绝对中间,线条的笔画以中线向两侧扩展。⽐如你的线条宽度是1,那么中线就在0.5的位置;宽度是5,那么中线就是在2.5。canvas的图形在描边的时候,都是路径与line的中线贴合,然后描边。如图2:
所以,描边的时候线的⼀半在外侧,⼀半在内侧,即上⾯的矩形的整体宽度是100+(10/2)*2,等于110.
也正是因为这个原因,左上⾓出现缺⾓就理所当然了。因为这⾥没⼈画。
但为什么其余的⾓没有出现缺⼝呢?看你的图不是4个⾓都有缺⼝吗?
那是因为,我画线的过程中没有把画笔“提起来”,画笔是连续的,即没有moveTo过。不信我们现在来moveTo⼀下:
复制代码
代码如下:
ctx.lineTo(200,100);
ctx.lineTo(200,200);
ctx.lineTo(100,200);
ctx.lineTo(100,100);
ctx.lineWidth = 10;
ctx.strokeStyle = 'rgba(255,0,0,0.5)';
ctx.stroke();
我们再画第⼆条线之前moveTo了⼀下,⽽且moveTo连坐标都没变,还是那个点,但刷新后图形变成了这个样⼦[图3]:
明⽩了?因为我们把笔提起来了。
现在我们删掉moveTo,不要纠结他了,我们来思考⼀下如何把左上⾓那个缺⾓给补上?
⾸先问个问题,我们的路径闭合了吗?这不是废话么,我们不是已经把路径绕回原点了么?当然算是闭合了!
错!这样只是让路径最后⼀个点和起点重合了⽽已,路径本⾝却没有闭合!
Canvas怎么闭合路径?⽤closePath().
复制代码
代码如下:
ctx.lineTo(200,100);
ctx.lineTo(200,200);
ctx.lineTo(100,200);
ctx.lineTo(100,100);
ctx.closePath();//闭合路径
ctx.lineWidth = 10;
ctx.strokeStyle = 'rgba(255,0,0,0.5)';
ctx.stroke();
此时刷新,就是⼀个完美的正⽅形了。图4:
⽆论我们把线条改到多粗————越粗越有⼈喜欢是吧?————这个四⽅形的四个⾓都是规矩的直⾓,不会出现圆滑的情况。圆滑的⾓是什么情况?请看PS中的四⽅形描边,图5:
看到了吧,越粗的边线,他的⾓的圆弧越⼤。
如果我想Canvas⾥⾯的边线也和PS这种⼀样,有没有办法呢?当然有,就是lineJoin属性。
lineJoin,意思即线的交汇处,有3个属性:miter(默认,尖⾓),bevel(斜⾓),round(圆⾓),如图6:
毫⽆疑问我们⼀下就能明⽩我们的矩形⽤的是尖⾓,所以试着把他改成圆⾓看看:
图形变成了这样,图7:
有点像PS的了吧?
另外,通过前⾯图我们了解到,Canvas的线条两端是平的,可不可以改呢?毕竟平的不好看。
也是可以的,即lineCap属性,这个就是定义线条的端点。lineCap有3个值:butt(平,默认),round(圆),square(⽅),如图8
看图就能发现,其实平头跟⽅头是⼀样的,区别只是平头没有伸出去那么⼀截。圆头和⽅头都会伸出去⼀截,这⼀节是多长呢?就是线条宽度的⼀半。
你有没有想到什么?哈哈,前⾯的闭合路径的问题,如果我们把lineCap设为⽅头,效果也是⼀样的!
但为了保险起见,我们还是要把路径闭合了,切记!
我还要提醒⼀下:闭合的路径没有端点!所以闭合的路径上看不到端点的样式。
另外:lineCap与lineJoin有点相似,注意不要搞混。
如果你眼尖并且运⽓不好,你可能会发现有时候1像素的线条不是1像素宽,好像要宽⼀些,模糊⼀些。如图9:
恭喜你!你遇到了⼀个不是bug的bug。这个很特别,我把他放到下⼀篇⽂章讲吧

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。