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实现波纹特效、H5实现动态波浪效果
Jan 31 HTML / CSS
多重CSS背景动画实现方法示例
Apr 04 HTML / CSS
CSS3 2D模拟实现摩天轮旋转效果
Nov 16 HTML / CSS
css3针对移动端卡顿问题的解决(动画性能优化)
Feb 14 HTML / CSS
html5音频_动力节点Java学院整理
Aug 22 HTML / CSS
html通过canvas转成base64的方法
Jul 18 HTML / CSS
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
Jun 03 HTML / CSS
html5中的input新属性range使用记录
Sep 05 HTML / CSS
HTML5的新特性(1)
Mar 03 HTML / CSS
Html5 Canvas动画基础碰撞检测的实现
Dec 06 HTML / CSS
html5实现点击弹出图片功能
Jul 16 HTML / CSS
HTML静态页面获取url参数和UserAgent的实现
Aug 05 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目录函数实现创建、读取目录教程实例
2011/01/13 PHP
PHP register_shutdown_function函数的深入解析
2013/06/03 PHP
PHP中执行MYSQL事务解决数据写入不完整等情况
2014/01/07 PHP
Laravel 5框架学习之Eloquent 关系
2015/04/09 PHP
php的PDO事务处理机制实例分析
2017/02/16 PHP
PHP封装cURL工具类与应用示例
2019/07/01 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
什么是cookie?js手动创建和存储cookie
2014/05/27 Javascript
js实现iframe跨页面调用函数的方法
2014/12/13 Javascript
JavaScript中的call方法和apply方法使用对比
2015/08/12 Javascript
JS中artdialog弹出框控件之提交表单思路详解
2016/04/18 Javascript
jQuery移动端日期(datedropper)和时间(timedropper)选择器附源码下载
2016/04/19 Javascript
js 连续赋值的简单实现
2016/06/13 Javascript
Node.js配合node-http-proxy解决本地开发ajax跨域问题
2016/08/31 Javascript
Java  Spring 事务回滚详解
2016/10/17 Javascript
jquery二级目录选中当前页的css样式
2016/12/08 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
AnglarJs中的上拉加载实现代码
2018/02/08 Javascript
Bootstrap 中data-[*] 属性的整理
2018/03/13 Javascript
js中时间格式化的几种方法
2018/07/22 Javascript
一步一步的了解webpack4的splitChunk插件(小结)
2018/09/17 Javascript
vue实现微信获取用户信息的方法
2019/03/21 Javascript
微信小程序实现watch监听
2020/06/04 Javascript
Python中的生成器和yield详细介绍
2015/01/09 Python
17个Python小技巧分享
2015/01/23 Python
Python中将字典转换为XML以及相关的命名空间解析
2015/10/15 Python
Python中第三方库Requests库的高级用法详解
2017/03/12 Python
pygame游戏之旅 添加键盘按键的方法
2018/11/20 Python
Django集成MongoDB实现过程解析
2020/12/01 Python
html5 figure和figcaption的使用方法
2018/09/10 HTML / CSS
医学检验专业大学生求职信
2013/11/18 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
2014社会治安综合治理工作总结
2014/12/04 职场文书
浅谈Python基础之列表那些事儿
2021/05/11 Python
利用Matlab绘制各类特殊图形的实例代码
2021/07/16 Python
数据分析数据库ClickHouse在大数据领域应用实践
2022/04/03 MySQL