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实现质感细腻丝滑按钮
Mar 09 HTML / CSS
CSS3教程(7):CSS3嵌入字体
Apr 02 HTML / CSS
收集的7个CSS3代码生成工具
Apr 17 HTML / CSS
纯CSS3实现8组超炫酷鼠标滑过图片动画
Mar 16 HTML / CSS
css3 矩阵的使用详解
Mar 20 HTML / CSS
CSS实现雨滴动画效果的实例代码
Oct 08 HTML / CSS
CSS3 新增选择器的实例
Nov 13 HTML / CSS
纯CSS3+DIV实现小三角形边框效果的示例代码
Aug 03 HTML / CSS
CSS3 实现倒计时效果
Nov 25 HTML / CSS
使用css如何制作时间ICON方法实践
Nov 12 HTML / CSS
使用html2canvas.js实现页面截图并显示或上传的示例代码
Dec 18 HTML / CSS
HTML5图片层叠的实现示例
Jul 07 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验证码
2015/05/04 PHP
php+ajax简单实现全选删除的方法
2016/12/06 PHP
PHP以json或xml格式返回请求数据的方法
2018/05/31 PHP
Code:findPosX 和 findPosY
2006/12/20 Javascript
JavaScript 学习技巧
2010/02/17 Javascript
关于onScroll事件在IE6下每次滚动触发三次bug说明
2011/09/21 Javascript
javascript 兼容所有浏览器的DOM扩展功能
2012/08/01 Javascript
$.each与$().each的区别示例介绍
2014/03/20 Javascript
js获取视频时长代码
2014/04/10 Javascript
在HTML代码中使用JavaScript代码的例子
2014/10/16 Javascript
jQuery解析XML文件同时动态增加js文件的方法
2015/06/01 Javascript
整理JavaScript创建对象的八种方法
2015/11/03 Javascript
JavaScript中的操作符类型转换示例总结
2016/05/30 Javascript
将List对象列表转换成JSON格式的类实现方法
2016/07/04 Javascript
JS实现title标题栏文字不间断滚动显示效果
2016/09/07 Javascript
vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据
2017/04/22 Javascript
Avalonjs双向数据绑定与监听的实例代码
2017/06/23 Javascript
node+express+ejs使用模版引擎做的一个示例demo
2017/09/18 Javascript
基于Vue实现图片在指定区域内移动的思路详解
2018/11/11 Javascript
JavaScript面向对象中接口实现方法详解
2019/07/24 Javascript
layer插件实现在弹出层中弹出一警告提示并关闭弹出层的方法
2019/09/24 Javascript
vscode调试node.js的实现方法
2020/03/22 Javascript
jQuery 实现DOM元素拖拽交换位置的实例代码
2020/07/14 jQuery
ubuntu环境下python虚拟环境的安装过程
2018/01/07 Python
Numpy中stack(),hstack(),vstack()函数用法介绍及实例
2018/01/09 Python
python实现最大子序和(分治+动态规划)
2019/07/05 Python
Python散点图与折线图绘制过程解析
2019/11/30 Python
老海军美国官网:Old Navy
2016/09/05 全球购物
2014学习优秀共产党员先进事迹思想汇报
2014/09/14 职场文书
市场营销计划书
2015/01/17 职场文书
慈善献爱心倡议书
2015/04/27 职场文书
初一年级组工作总结
2015/08/12 职场文书
《中国古代诗歌散文欣赏》高中语文教材
2019/08/20 职场文书
mybatis使用oracle进行添加数据的方法
2021/04/27 Oracle
Matlab如何实现矩阵复制扩充
2021/06/02 Python
MySQL的全局锁和表级锁的具体使用
2021/08/23 MySQL