html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点


Posted in HTML / CSS onJanuary 09, 2013

如果你还不知道Canvas是什么,可以看看上一篇.
在学画画的时候,线条是最基本的了,而线条的连接可以组成任何图形。在Canvas中也是如此。
在开始之前我们先拿出画布和画笔:

复制代码
代码如下:

var cvs = document.getElementById('cvs'); //画布
var ctx = cvs.getContext('2d'); // 画笔

我们画画的时候,落笔点是不固定的,随时都会变。canvas虽然不是通过手来决定落笔点,但也有一个方法,就是moveTo。moveTo的作用相当于把笔尖提离画布,然后移动到指定的点(即坐标)。
复制代码
代码如下:

ctx.moveTo(x,y)

此过程中不会画出任何图形,相当于你提着笔在画布上晃来晃去。
但晃来晃去是没用的,我们必须开始画。先画最简单的:直线
画直线的方法即lineTo,他的参数和moveTo一样的,都是一个点。
ctx.lineTo(x,y)当然,你画线的时候,落笔点也跟着移动了,所以lineTo之后落笔点就变成了他的目标点了。
复制代码
代码如下:

ctx.moveTo(100,100);
ctx.lineTo(200,100);

此时你刷新网页,会发现画布上没有预想中的线,什么也没有。因为我们还少了一个步骤.lineTo其实是画的一条“路径”,本身是不可见的。如果要让他显示出来,我们必须对他进行“画”的操作。
用过PS的同学,肯定能知道图形的两种模式,一种是填充,另一种是描边。现在我们已经画了一条线,相当于PS中勾了一条路径,此时给路径描一下边,就能显示出图形了。
canvas描边的方法是stroke().现在让我们把代码补全:
复制代码
代码如下:

ctx.moveTo(100,100);
ctx.lineTo(200,100);

ctx.stroke();此时刷新,就能看到一条线了。当然,你也可以连续绘制出几百条路径,再执行描边动作,即可一下画出几百条线。现在我们来用4条线画一个矩形:
复制代码
代码如下:

ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.lineTo(200,200);
ctx.lineTo(100,200);
ctx.lineTo(100,100);
ctx.stroke();

这里我们就是先绘出全部路径,再一次性描边。
——–作者的抱怨:Canvas绘图有个不好的地方就是:基本靠猜,很不直观。
严重提示:canvas的绘图过程(即填充与描边)是非常消耗资源的,如果想节省系统资源提高效率,最好是绘制好所有路径,再一次性填充或描边图形。
由上面的图形我们可以看出,默认的线条粗细是1px,而线条颜色是黑色。当然我们可以设置他们,但奇怪的是设置线条宽度是lineWidth,而设置线条样式的却叫strokeStyle,为什么不是lineStyle呢?我也不知道。:
复制代码
代码如下:

ctx.lineWidth = 10;
ctx.strokeStyle = 'rgba(255,0,0,0.5)';

上面的代码把线条宽度设置成了10px,线条颜色变成了半透明的红色。

html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点

如图1,刷新一下,好像有点不对呢!怎么左上角缺了一小块似得?这不是错觉。原因嘛要从canvas的线条绘制方式说起。
问题:如果我画的矩形路径是宽高都是100,此时我的边线宽度是10px,那么这个描了边的矩形整体宽高是多少?是100+10*2=120吗?
如果边线是完全描在路径外侧的话,那么就是120。但Canvas不是。Canvas中的线条都有一条“中线”,这条中线位于line的绝对中间,线条的笔画以中线向两侧扩展。比如你的线条宽度是1,那么中线就在0.5的位置;宽度是5,那么中线就是在2.5。canvas的图形在描边的时候,都是路径与line的中线贴合,然后描边。如图2:

html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点


所以,描边的时候线的一半在外侧,一半在内侧,即上面的矩形的整体宽度是100+(10/2)*2,等于110.
也正是因为这个原因,左上角出现缺角就理所当然了。因为这里没人画。
但为什么其余的角没有出现缺口呢?看你的图不是4个角都有缺口吗?
那是因为,我画线的过程中没有把画笔“提起来”,画笔是连续的,即没有moveTo过。不信我们现在来moveTo一下:
复制代码
代码如下:

ctx.moveTo(100,100);
ctx.lineTo(200,100);
ctx.moveTo(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]:

html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点


明白了?因为我们把笔提起来了。
现在我们删掉moveTo,不要纠结他了,我们来思考一下如何把左上角那个缺角给补上?
首先问个问题,我们的路径闭合了吗?这不是废话么,我们不是已经把路径绕回原点了么?当然算是闭合了!
错!这样只是让路径最后一个点和起点重合了而已,路径本身却没有闭合!
Canvas怎么闭合路径?用closePath().
复制代码
代码如下:

ctx.moveTo(100,100);
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:

html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点


无论我们把线条改到多粗————越粗越有人喜欢是吧?————这个四方形的四个角都是规矩的直角,不会出现圆滑的情况。圆滑的角是什么情况?请看PS中的四方形描边,图5:

html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点


看到了吧,越粗的边线,他的角的圆弧越大。
如果我想Canvas里面的边线也和PS这种一样,有没有办法呢?当然有,就是lineJoin属性。
lineJoin,意思即线的交汇处,有3个属性:miter(默认,尖角),bevel(斜角),round(圆角),如图6:
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点 
毫无疑问我们一下就能明白我们的矩形用的是尖角,所以试着把他改成圆角看看:
图形变成了这样,图7:
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点 
有点像PS的了吧?
另外,通过前面图我们了解到,Canvas的线条两端是平的,可不可以改呢?毕竟平的不好看。
也是可以的,即lineCap属性,这个就是定义线条的端点。lineCap有3个值:butt(平,默认),round(圆),square(方),如图8
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点 
看图就能发现,其实平头跟方头是一样的,区别只是平头没有伸出去那么一截。圆头和方头都会伸出去一截,这一节是多长呢?就是线条宽度的一半。
你有没有想到什么?哈哈,前面的闭合路径的问题,如果我们把lineCap设为方头,效果也是一样的!
但为了保险起见,我们还是要把路径闭合了,切记!
我还要提醒一下:闭合的路径没有端点!所以闭合的路径上看不到端点的样式。
另外:lineCap与lineJoin有点相似,注意不要搞混。
如果你眼尖并且运气不好,你可能会发现有时候1像素的线条不是1像素宽,好像要宽一些,模糊一些。如图9:
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
恭喜你!你遇到了一个不是bug的bug。这个很特别,我把他放到下一篇文章讲吧
HTML / CSS 相关文章推荐
纯CSS3实现质感细腻丝滑按钮
Mar 09 HTML / CSS
CSS3中31种选择器使用方法教程
Dec 05 HTML / CSS
CSS Grid布局教程之浏览器开启CSS Grid Layout汇总
Dec 30 HTML / CSS
CSS3中线性颜色渐变的一些实现方法
Jul 14 HTML / CSS
CSS3 transforms应用于背景图像的解决方法
Apr 16 HTML / CSS
HTML5之web workers_动力节点Java学院整理
Jul 17 HTML / CSS
HTML5 贪吃蛇游戏实现思路及源代码
Sep 03 HTML / CSS
基于html5实现的图片墙效果
Oct 16 HTML / CSS
浅谈HTML5 服务器推送事件(Server-sent Events)
Aug 01 HTML / CSS
Html5 webview元素定位工具的实现
Aug 07 HTML / CSS
HTML5中外部浏览器唤起微信分享功能的代码
Sep 15 HTML / CSS
移动端HTML5 input常见问题(小结)
Sep 28 HTML / CSS
html5 Canvas画图教程(1)—画图的基本常识
Jan 09 #HTML / CSS
使用html5+css3来实现slider切换效果告别javascript+css
Jan 08 #HTML / CSS
几个解决兼容IE6\7\8不支持html5标签的几个方法
Jan 07 #HTML / CSS
html5 canvas-2.用canvas制作一个猜字母的小游戏
Jan 07 #HTML / CSS
html5 canvas-1.canvas介绍(hello canvas)
Jan 07 #HTML / CSS
html5指南-1.html5全局属性(html5 global attributes)深入理解
Jan 07 #HTML / CSS
html5指南-2.如何操作document metadata
Jan 07 #HTML / CSS
You might like
PHP网上调查系统
2006/10/09 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
2011/10/29 PHP
PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)
2017/05/26 PHP
PHP 7安装调试工具Xdebug扩展的方法教程
2017/06/17 PHP
PHP7 参数处理机制修改
2021/03/09 PHP
只需一行代码,轻松实现一个在线编辑器
2013/11/12 Javascript
jQuery调用WebMethod(PageMethod) NET2.0的方法
2016/04/15 Javascript
KnockoutJS 3.X API 第四章之数据控制流if绑定和ifnot绑定
2016/10/10 Javascript
使用jQuery,Angular实现登录界面验证码详解
2017/04/27 jQuery
几个你不知道的技巧助你写出更优雅的vue.js代码
2018/06/11 Javascript
微信小程序wxs实现吸顶效果
2020/01/08 Javascript
JS前端广告拦截实现原理解析
2020/02/17 Javascript
python list使用示例 list中找连续的数字
2014/01/27 Python
运动检测ViBe算法python实现代码
2018/01/09 Python
Python线程创建和终止实例代码
2018/01/20 Python
django自带的server 让外网主机访问方法
2018/05/14 Python
用Python shell简化开发
2018/08/08 Python
利用Python将每日一句定时推送至微信的实现方法
2018/08/13 Python
Python数据预处理之数据规范化(归一化)示例
2019/01/08 Python
matplotlib绘制多个子图(subplot)的方法
2019/12/03 Python
利用matplotlib实现根据实时数据动态更新图形
2019/12/13 Python
python实现超级马里奥
2020/03/18 Python
浅谈matplotlib中FigureCanvasXAgg的用法
2020/06/16 Python
Python pip使用超时问题解决方案
2020/08/03 Python
python产生模拟数据faker库的使用详解
2020/11/04 Python
CSS3 transition 实现通知消息轮播条
2020/10/14 HTML / CSS
英国No.1体育用品零售商:SportsDirect.com
2019/10/16 全球购物
军校大学生个人的自我评价
2014/02/17 职场文书
函授毕业个人自我评价
2014/02/20 职场文书
杭州西湖英语导游词
2015/02/03 职场文书
工作自我推荐信范文
2015/03/25 职场文书
525心理健康活动总结
2015/05/08 职场文书
《包身工》教学反思
2016/02/23 职场文书
python 统计代码耗时的几种方法分享
2021/04/02 Python
Flask搭建一个API服务器的步骤
2021/05/28 Python
MySQL示例讲解数据库约束以及表的设计
2022/06/16 MySQL