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轻松实现清新 Loading 效果的简单实例
Jun 06 HTML / CSS
CSS3 mask 遮罩的具体使用方法
Nov 03 HTML / CSS
html5+css3之制作header实例与更新
Dec 21 HTML / CSS
html5 sessionStorage会话存储_动力节点Java学院整理
Jul 06 HTML / CSS
HTML5 Canvas渐进填充与透明实现图像的Mask效果
Jul 11 HTML / CSS
HTML5 预加载让页面得以快速呈现
Aug 13 HTML / CSS
html5使用canvas实现跟随光标跳动的火焰效果
Jan 07 HTML / CSS
HTML5中Localstorage的使用教程
Jul 09 HTML / CSS
HTML5中meta属性的使用方法
Feb 29 HTML / CSS
html2 canvas生成清晰的图片实现打印功能
Sep 23 HTML / CSS
记一次高分屏下canvas模糊问题
Feb 17 HTML / CSS
CSS实现单选折叠菜单功能
Nov 01 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
第十一节 重载 [11]
2006/10/09 PHP
在任意字符集下正常显示网页的方法一
2007/04/01 PHP
GBK的页面输出JSON格式的php函数
2010/02/16 PHP
PHP通过iconv将字符串从GBK转换为UTF8字符集
2011/07/18 PHP
PHP反向代理类代码
2014/08/15 PHP
分享一则PHP定义函数代码
2015/02/26 PHP
xtree.js 代码
2007/03/13 Javascript
jquery关于图形报表的运用实现代码
2011/01/06 Javascript
JavaScript让网页出现渐隐渐显背景颜色的方法
2015/04/21 Javascript
jQuery EasyUI基础教程之EasyUI常用组件(推荐)
2016/07/15 Javascript
Node.js 数据加密传输浅析
2016/11/16 Javascript
用headjs来管理和加载js 提高网站加载速度
2016/11/29 Javascript
利用vue + koa2 + mockjs模拟数据的方法教程
2017/11/22 Javascript
vue-cli axios请求方式及跨域处理问题
2018/03/28 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
Layer+Echarts构建弹出层折线图的方法
2019/09/25 Javascript
[02:12]2019完美世界全国高校联赛(春季赛)报名开启
2019/03/01 DOTA
详解python3实现的web端json通信协议
2016/12/29 Python
详谈python中冒号与逗号的区别
2018/04/18 Python
Python 调用 zabbix api的方法示例
2019/01/06 Python
python实时获取外部程序输出结果的方法
2019/01/12 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
Python Django实现layui风格+django分页功能的例子
2019/08/29 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
2020/02/09 Python
pytorch实现seq2seq时对loss进行mask的方式
2020/02/18 Python
python爬虫开发之PyQuery模块详细使用方法与实例全解
2020/03/09 Python
Python标准库json模块和pickle模块使用详解
2020/03/10 Python
Python基于BeautifulSoup爬取京东商品信息
2020/06/01 Python
vue.js刷新当前页面的实例讲解
2020/12/29 Python
日本最大级玩偶手办购物:あみあみ Amiami
2018/04/23 全球购物
速比涛英国官网:Speedo英国
2019/07/15 全球购物
澳大利亚最大的护发和护肤品购物网站:RY
2019/12/26 全球购物
托管代码(Managed Code)和非托管代码(Unmanaged Code)有什么区别
2014/09/29 面试题
JSP&Servlet技术面试题
2015/05/21 面试题
面试自我评价范文
2014/09/17 职场文书
SpringBoot Http远程调用的方法
2022/08/14 Java/Android