HTML5画布清理,重绘,旧的线条也会出现

<!DOCTYPE html> <html> <head> <title>HTLM5</title> <meta charset="utf-8"/> </head> <body> <br/> <canvas width="500px" height="500px" id="can1" style="border:1px solid red"></canvas> <br/> <div onclick="test()">test</div> <d...展开

 

王古吉 | 浏览 1298 次  2015-01-31 19:46

2015-02-03 17:43

 

最佳答案

 

test和test2都需要重启一个路径,不然还是原来的,路径信息会先保存在内存里面,在调用stroke或者fill的时候,才会真正的绘制出来。因此,这两个方法都加上beginPath和closePath就行了,即

1
2
3
4
5
6
7
function test(){
    cxt.beginPath();
    cxt.moveTo(0,0);
    cxt.lineTo(100,100);
    cxt.stroke();
    cxt.closePath();
}

note. 一般修改canvas属性的时候,如fillStyle,先要save,绘制完成后再restore还原到初始状态,不然会影响到下一次的绘制。

html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点

作者:佚名 字体:[增加 减小] 来源:互联网 时间:01-09 11:24:25我要评论

在学画画的时候,线条是最基本的了,而线条的连接可以组成任何图形。在Canvas中也是如此,接下来为您详细介绍最简单的线条的画法
如果你还不知道Canvas是什么,可以看看上一篇
在学画画的时候,线条是最基本的了,而线条的连接可以组成任何图形。在Canvas中也是如此。 
在开始之前我们先拿出画布和画笔:

复制代码

代码如下:

var cvs = document.getElementById('cvs'); //画布 
var ctx = cvs.getContext('2d'); // 画笔 

我们画画的时候,落笔点是不固定的,随时都会变。canvas虽然不是通过手来决定落笔点,但也有一个方法,就是moveTo。moveTo的作用相当于把笔尖提离画布,然后移动到指定的点(即坐标)。

复制代码

代码如下:

ctx.moveTo(x,y) 

此过程中不会画出任何图形,相当于你提着笔在画布上晃来晃去。 
但晃来晃去是没用的,我们必须开始画。先画最简单的:直线 
画直线的方法即lineTo,他的参数和moveTo一样的,都是一个点。 
ctx.lineTo(x,y)当然,你画线的时候,落笔点也跟着移动了,所以lineTo之后落笔点就变成了他的目标点了。

复制代码

代码如下:

ctx.moveTo(100,100); 
ctx.lineTo(200,100); 

此时你刷新网页,会发现画布上没有预想中的线,什么也没有。因为我们还少了一个步骤.lineTo其实是画的一条“路径”,本身是不可见的。如果要让他显示出来,我们必须对他进行“画”的操作。 
用过PS的同学,肯定能知道图形的两种模式,一种是填充,另一种是描边。现在我们已经画了一条线,相当于PS中勾了一条路径,此时给路径描一下边,就能显示出图形了。 
canvas描边的方法是stroke().现在让我们把代码补全:

复制代码

代码如下:

ctx.moveTo(100,100); 
ctx.lineTo(200,100); 

ctx.stroke();此时刷新,就能看到一条线了。当然,你也可以连续绘制出几百条路径,再执行描边动作,即可一下画出几百条线。现在我们来用4条线画一个矩形:

复制代码

代码如下:

ctx.moveTo(100,100); 
ctx.lineTo(200,100); 
ctx.lineTo(200,200); 
ctx.lineTo(100,200); 
ctx.lineTo(100,100); 
ctx.stroke(); 

这里我们就是先绘出全部路径,再一次性描边。 
——–作者的抱怨:Canvas绘图有个不好的地方就是:基本靠猜,很不直观。 
严重提示:canvas的绘图过程(即填充与描边)是非常消耗资源的,如果想节省系统资源提高效率,最好是绘制好所有路径,再一次性填充或描边图形。 
由上面的图形我们可以看出,默认的线条粗细是1px,而线条颜色是黑色。当然我们可以设置他们,但奇怪的是设置线条宽度是lineWidth,而设置线条样式的却叫strokeStyle,为什么不是lineStyle呢?我也不知道。:

复制代码

代码如下:

ctx.lineWidth = 10; 
ctx.strokeStyle = 'rgba(255,0,0,0.5)'; 

上面的代码把线条宽度设置成了10px,线条颜色变成了半透明的红色。

如图1,刷新一下,好像有点不对呢!怎么左上角缺了一小块似得?这不是错觉。原因嘛要从canvas的线条绘制方式说起。 
问题:如果我画的矩形路径是宽高都是100,此时我的边线宽度是10px,那么这个描了边的矩形整体宽高是多少?是100+10*2=120吗? 
如果边线是完全描在路径外侧的话,那么就是120。但Canvas不是。Canvas中的线条都有一条“中线”,这条中线位于line的绝对中间,线条的笔画以中线向两侧扩展。比如你的线条宽度是1,那么中线就在0.5的位置;宽度是5,那么中线就是在2.5。canvas的图形在描边的时候,都是路径与line的中线贴合,然后描边。如图2:

所以,描边的时候线的一半在外侧,一半在内侧,即上面的矩形的整体宽度是100+(10/2)*2,等于110. 
也正是因为这个原因,左上角出现缺角就理所当然了。因为这里没人画。 
但为什么其余的角没有出现缺口呢?看你的图不是4个角都有缺口吗? 
那是因为,我画线的过程中没有把画笔“提起来”,画笔是连续的,即没有moveTo过。不信我们现在来moveTo一下:

复制代码

代码如下:

ctx.moveTo(100,100); 
ctx.lineTo(200,100); 
ctx.moveTo(200,100); //注意这里 
ctx.lineTo(200,200); 
ctx.lineTo(100,200); 
ctx.lineTo(100,100); 
ctx.lineWidth = 10; 
ctx.strokeStyle = 'rgba(255,0,0,0.5)'; 
ctx.stroke(); 

我们再画第二条线之前moveTo了一下,而且moveTo连坐标都没变,还是那个点,但刷新后图形变成了这个样子[图3]:

明白了?因为我们把笔提起来了。 
现在我们删掉moveTo,不要纠结他了,我们来思考一下如何把左上角那个缺角给补上? 
首先问个问题,我们的路径闭合了吗?这不是废话么,我们不是已经把路径绕回原点了么?当然算是闭合了! 
错!这样只是让路径最后一个点和起点重合了而已,路径本身却没有闭合! 
Canvas怎么闭合路径?用closePath().

复制代码

代码如下:

ctx.moveTo(100,100); 
ctx.lineTo(200,100); 
ctx.lineTo(200,200); 
ctx.lineTo(100,200); 
ctx.lineTo(100,100); 
ctx.closePath();//闭合路径 
ctx.lineWidth = 10; 
ctx.strokeStyle = 'rgba(255,0,0,0.5)'; 
ctx.stroke(); 

此时刷新,就是一个完美的正方形了。图4:

无论我们把线条改到多粗————越粗越有人喜欢是吧?————这个四方形的四个角都是规矩的直角,不会出现圆滑的情况。圆滑的角是什么情况?请看PS中的四方形描边,图5:

看到了吧,越粗的边线,他的角的圆弧越大。 
如果我想Canvas里面的边线也和PS这种一样,有没有办法呢?当然有,就是lineJoin属性。 
lineJoin,意思即线的交汇处,有3个属性:miter(默认,尖角),bevel(斜角),round(圆角),如图6: 
 
毫无疑问我们一下就能明白我们的矩形用的是尖角,所以试着把他改成圆角看看: 
图形变成了这样,图7: 
 
有点像PS的了吧? 
另外,通过前面图我们了解到,Canvas的线条两端是平的,可不可以改呢?毕竟平的不好看。 
也是可以的,即lineCap属性,这个就是定义线条的端点。lineCap有3个值:butt(平,默认),round(圆),square(方),如图8 
 
看图就能发现,其实平头跟方头是一样的,区别只是平头没有伸出去那么一截。圆头和方头都会伸出去一截,这一节是多长呢?就是线条宽度的一半。 
你有没有想到什么?哈哈,前面的闭合路径的问题,如果我们把lineCap设为方头,效果也是一样的! 
但为了保险起见,我们还是要把路径闭合了,切记! 
我还要提醒一下:闭合的路径没有端点!所以闭合的路径上看不到端点的样式。 
另外:lineCap与lineJoin有点相似,注意不要搞混。 
如果你眼尖并且运气不好,你可能会发现有时候1像素的线条不是1像素宽,好像要宽一些,模糊一些。如图9: 

恭喜你!你遇到了一个不是bug的bug。这个很特别,我把他放到下一篇文章讲吧

画布清理////////////////////////////zzzz的更多相关文章

  1. [置顶] 小强的HTML5移动开发之路(9)——坦克大战游戏3

    上一篇我们创建了敌人的坦克和自己的坦克,接下来就应该让坦克发子弹了,我们下面来看一下如何让我们的坦克发出子弹. 前面我们用面向对象的思想对Tank进行了封装,又利用对象冒充实现了我们的坦克和敌人的坦克 ...

  2. GDI+(Graphics Device Interface)例子

    使用SolidBrush 单色画笔 Bitmap bitmap = new Bitmap(800, 600);            Graphics graphics = Graphics.From ...

  3. Html 5 坦克大战(韩顺平县版本号)

    html 5例如,下面的代码段: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/ ...

  4. canvas烟花-娱乐

    网上看到一个释放烟花的canvas案例,很好看哦. 新建文本,把下面代码复制进去,后缀名改为html,用浏览器打开即可. 看懂注释后,可以自己修改烟花的各个效果.我试过让烟花炸成了心型.:-) < ...

  5. 小强的HTML5移动开发之路(9)——坦克大战游戏3

    来自:http://blog.csdn.net/dawanganban/article/details/17754235 上一篇我们创建了敌人的坦克和自己的坦克,接下来就应该让坦克发子弹了,我们下面来 ...

  6. 小强的HTML5移动开发之路(8)——坦克大战游戏2

    来自:http://blog.csdn.net/cai_xingyun/article/details/48629015 在上一篇文章中我们已经画出了自己的坦克,并且可以控制自己的坦克移动,我们继续接 ...

  7. 小强的HTML5移动开发之路(7)——坦克大战游戏1

    来自:http://blog.csdn.net/dawanganban/article/details/17693145 上一篇中我们介绍了关于Canvas的基础知识,用Canvas绘制各种图形和图片 ...

  8. Android 自定义View修炼-高仿猎豹清理大师自定义内存开口圆环比例进度View

    一.概述 看见猎豹清理大师的内存开口圆环比例进度 挺有意思的,于是就是想自己实现下这样的效果,于是反编译了猎豹清理 大师的app看了下,原来是有两张图,于是脑子里就过了下思路,利用上下两张图,旋转上面 ...

  9. Android 自定义控件-高仿猎豹清理大师自定义内存开口圆环控件

    技术:Android+java   概述 看见猎豹清理大师的内存开口圆环比例进度 挺有意思的,于是就是想自己实现下这样的效果,于是反编译了猎豹清理 大师的app看了下,原来是有两张图,于是脑子里就过了 ...

随机推荐

  1. 创建DOTA2本地数据库(一)

    在APP中,用本地数据库好于频繁的联网去获取相关数据.我使用SQLite作为本地的数据库,比较轻巧. 英雄 首先先建立英雄的数据库,暂时我先只设置ID,name,loaclized_name这三种,我 ...

  2. WebCrawler

    WebCrawler WebCrawler is a metasearch engine that blends the top search results from Google Search a ...

  3. ZeroMQ接口函数之 :zmq_msg_data - 返回消息内容的指针

    ZeroMQ 官方地址 :http://api.zeromq.org/4-1:zmq_msg_data zmq_msg_data(3)  ØMQ Manual - ØMQ/3.2.5 Name zmq ...

  4. Web开发流程

    知乎上关于Web开发流程豪情给予的回答 web前端开发流程是什么?进行操作会用到哪些便捷的小工具?是先用模板做好,然后在基础上改吗??正常大家说的改框架是不是指的用模板做的网站原文件?前端开发做的文件 ...

  5. Python实战2( 接上):扫描多余中文

    还是接上一篇,扫描多余中文,支持自定义忽略字段 源代码,详看   http://pan.baidu.com/s/1ntC78Zv   ScanChinese.zip

  6. 使用nginx和iptables做访问权限控制(IP和MAC)

    之前配置的服务器,相当于对整个内网都是公开的 而且,除了可以通过80端口的nginx来间接访问各项服务,也可以绕过nginx,直接ip地址加端口访问对应服务 这是不对的啊,所以我们要做一些限制 因为只 ...

  7. 【emWin】例程七:绘制基本图形

    简介:emWin 包含完整的2-D 图形库,可供大多数应用程序充分使用 本例程介绍如何使用图形API绘制基本的2-D图形 实验指导书及代码包下载: 链接:http://pan.baidu.com/s/ ...

  8. 清理session的案例

    and OPNAME ='Sort Output'; and OPNAME ='Sort Output'; and OPNAME ='Sort Output' ); select 'alter sys ...

  9. phpv6_css

    global @charset "utf-8"; /* CSS Document */ /*格式化样式*/ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3, ...

  10. JAVA(IO流)文件复制

    package com.am; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOEx ...