html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因


Posted in HTML / CSS onJanuary 09, 2013

接上一篇canvas画线条教程
上次我们讲到,canvas有时候会出现1像素的线条模糊不清且好像更宽的情况,如下图:
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因 
这样的线条显然不是我们想要的。
这篇文章的目的就是弄清楚里面的原理,以及解决它。
大家都知道屏幕上最小的显示尺寸就是1像素,虽然小于1像素的东西可能显示不出来,但计算机可不管,他会试着画一下。
其实像素终究来说也是一个单位,假如我们把画布放大到足够大,足以看清楚每个像素,会是什么情况呢?大概是这个样子:

html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因


每个像素都有起止范围,如图所示,他们的范围从左起,跨过1像素,到右止。
如果我们画1像素线条的时候,遵循像素的起止范围,那么我们肯定能得到一个很标准的细线。如下:

html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因


但遗憾的是canvas的线条画法不一样,上一篇文章我们已经说了,canvas的每条线都有一条无限细的“中线”,线条的宽度是从中线向两侧延伸的。如果我们还是从第2个像素点画一条线,那么线条的中线就会靠齐到第2个像素的起点,然后我们开始画了,问题也就来了:Canvas 的线条以中线向两侧延伸,而不是向某一边延伸(比如这里,如果只是往右侧延伸,那么我们的问题就不再是问题了),延伸过后我们的线条实际上是这样的:

html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因


此时又有个问题:计算机不允许出现小于1px的图形,所以他做了一个折中的事:把这两个像素都绘制了。
所以,如此一来,本来1px的线条,就成了看起来2px宽的线条。
失败的原因找到了:Canvas中的line把中线与像素的起点对齐了,而不是像素的中间点。
那么我们怎么解决这个蛋疼的问题?也许有人已经想到了:既然是因为两个的起点不一样,那我们就把他们的起点变得一样吧!
我们让线条的中线和像素的中间点对齐就行了!
像素的中间点很好找,比如第2像素的中间点,依据图上的解释就是1.5像素的位置,那么x像素的中间点就是(x-0.5)px。
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
 
当然,在不很严谨的场合,你使用x+0.5也是可以的。
现在我们在canvas上试试我们的研究结果。
复制代码
代码如下:

ctx.moveTo(100.5,100.5);
ctx.lineTo(200.5,100.5);
ctx.lineTo(200.5,200.5);
ctx.lineTo(100.5,200.5);
ctx.lineTo(100.5,100.5);
ctx.closePath();
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(255,0,0,0.5)';
ctx.stroke();

html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因


看起来对了吧?
不过貌似这样一来我们画线的时候就非常纠结,难道每次都去加这个让人郁闷的0.5?当然不是,因为我们大部分时间都是用变量保存值的,就不用给每个值加0.5 了
而且,对于lineWidth>1 的线,我们也不用管它:因为只有线条宽1px的时候,这个问题才最明显。
HTML / CSS 相关文章推荐
CSS3教程(6):创建网站多列
Apr 02 HTML / CSS
CSS3教程(2):网页边框半径和网页圆角
Apr 02 HTML / CSS
css3实现的下拉菜单效果示例
Jan 22 HTML / CSS
一款CSS3实现多功能下拉菜单(带分享按)的教程
Nov 05 HTML / CSS
CSS3弹性盒模型flex box快速入门心得(必看篇)
May 24 HTML / CSS
CSS3实现的渐变幻灯片效果
Dec 07 HTML / CSS
HTML5 新事件 小结
Jul 16 HTML / CSS
HTML5 form标签之解放表单验证、增加文件上传、集成拖放的使用方法
Apr 24 HTML / CSS
HTML5 新表单类型示例代码
Mar 20 HTML / CSS
div或img图片高度随宽度自适应的方法
Feb 06 HTML / CSS
使用placeholder属性设置input文本框的提示信息
Feb 19 HTML / CSS
CSS实现多个元素在盒子内两端对齐效果
Mar 30 HTML / CSS
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
Jan 09 #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
You might like
php扩展ZF――Validate扩展
2008/01/10 PHP
PHP simple_html_dom.php+正则 采集文章代码
2009/12/24 PHP
PHP连接MongoDB示例代码
2012/09/06 PHP
php导出CSV抽象类实例
2014/09/24 PHP
创建无限极分类树型结构的简单方法
2017/06/20 PHP
js实现格式化金额,字符,时间的方法
2015/02/26 Javascript
Javascript小技能总结(推荐)
2016/06/02 Javascript
Js 获取当前函数参数对象的实现代码
2016/06/20 Javascript
ionic组件ion-tabs选项卡切换效果实例
2016/08/27 Javascript
jQuery轮播图效果精简版完整示例
2016/09/04 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
详谈js中数组(array)和对象(object)的区别
2017/02/27 Javascript
angularjs之$timeout指令详解
2017/06/13 Javascript
vue translate peoject实现在线翻译功能【新手必看】
2018/06/07 Javascript
Angular异步变同步处理方法
2018/08/13 Javascript
React项目动态设置title标题的方法示例
2018/09/26 Javascript
vue学习笔记五:在vue项目里面使用引入公共方法详解
2019/04/04 Javascript
JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作实例
2019/09/17 Javascript
vue 保留两位小数 不能直接用toFixed(2) 的解决
2020/08/07 Javascript
简单分析Python中用fork()函数生成的子进程
2015/05/04 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
pycharm debug功能实现跳到循环末尾的方法
2018/11/29 Python
pandas分组聚合详解
2020/04/10 Python
用 Python 制作地球仪的方法
2020/04/24 Python
详解使用Python写一个向数据库填充数据的小工具(推荐)
2020/09/11 Python
python 实现音频叠加的示例
2020/10/29 Python
HTML5 File接口在web页面上使用文件下载
2017/02/27 HTML / CSS
实现strstr功能,即在父串中寻找子串首次出现的位置
2016/08/05 面试题
室内设计实习自我鉴定
2013/09/25 职场文书
批评与自我批评材料
2014/02/15 职场文书
元旦联欢会主持词
2014/03/26 职场文书
社区四风存在问题及整改措施
2014/10/26 职场文书
护理工作个人总结
2015/03/03 职场文书
数据结构课程设计心得体会
2016/01/15 职场文书
OpenCV图像变换之傅里叶变换的一些应用
2021/07/26 Python
python基础之类属性和实例属性
2021/10/24 Python