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 相关文章推荐
CSS超出文本指定宽度用省略号代替和文本不换行
May 05 HTML / CSS
css3中仿放大镜效果的几种方式原理解析
Dec 03 HTML / CSS
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
Jul 20 HTML / CSS
用HTML5实现手机摇一摇的功能的教程
Oct 30 HTML / CSS
HTML5中的Article和Section元素认识及使用
Mar 22 HTML / CSS
html5通过canvas实现刮刮卡效果示例分享
Jan 27 HTML / CSS
HTML5 DeviceOrientation实现手机网站摇一摇功能代码实例
Apr 24 HTML / CSS
使用HTML5 Canvas API绘制弧线的教程
Mar 22 HTML / CSS
浅谈html5与APP混合开发遇到的问题总结
Mar 20 HTML / CSS
使用html2canvas.js实现页面截图并显示或上传的示例代码
Dec 18 HTML / CSS
Html5踩坑记之mandMobile使用小记
Apr 02 HTML / CSS
老生常谈 使用 CSS 实现三角形的技巧(多种方法)
Apr 13 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
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
php adodb分页实现代码
2009/03/19 PHP
CentOS 上搭建 PHP7 开发测试环境
2017/02/26 PHP
PHP生成推广海报的方法分享
2018/04/22 PHP
PHP从零开始打造自己的MVC框架之路由类实现方法分析
2019/06/03 PHP
laravel withCount 统计关联数量的方法
2019/10/10 PHP
XML的代替者----JSON
2007/07/21 Javascript
jquery实现textarea输入框限制字数的方法
2015/01/15 Javascript
jquery模拟进度条实现方法
2015/08/03 Javascript
原生JS实现几个常用DOM操作API实例
2017/01/19 Javascript
Vue.js 单页面多路由区域操作的实例详解
2017/07/17 Javascript
Vue二次封装axios为插件使用详解
2018/05/21 Javascript
JavaScript中发出HTTP请求最常用的方法
2018/07/12 Javascript
react在安卓中输入框被手机键盘遮挡问题的解决方法
2018/09/03 Javascript
React router动态加载组件之适配器模式的应用详解
2018/09/12 Javascript
解决Vue开发中对话框被遮罩层挡住的问题
2018/11/26 Javascript
详解vue开发中调用微信jssdk的问题
2019/04/16 Javascript
JavaScript实现的联动菜单特效示例
2019/07/08 Javascript
解决vant title-active-color与title-inactive-color不生效问题
2020/11/03 Javascript
[01:00:14]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第三场
2018/04/10 DOTA
详解Python中的变量及其命名和打印
2016/03/11 Python
Python中多线程的创建及基本调用方法
2016/07/08 Python
Python实现字符串与数组相互转换功能示例
2017/09/22 Python
python购物车程序简单代码
2018/04/18 Python
浅谈django的render函数的参数问题
2018/10/16 Python
PowerBI和Python关于数据分析的对比
2019/07/11 Python
python爬取豆瓣电影排行榜(requests)的示例代码
2021/02/18 Python
CSS3实现淘宝留白的方法
2020/06/05 HTML / CSS
CSS实现fullpage.js全屏滚动效果的示例代码
2021/03/24 HTML / CSS
学生会离职感言
2014/02/11 职场文书
《鸟的天堂》教学反思
2014/02/27 职场文书
倡议书格式范文
2014/04/14 职场文书
Python中Selenium对Cookie的操作方法
2021/07/09 Python
利用Python读取微信朋友圈的多种方法总结
2021/08/23 Python
MySql重置root密码 --skip-grant-tables
2022/04/11 MySQL
golang定时器
2022/04/14 Golang