canvas清除上一次画的,canvas 清除
清空canvas画布内容
1、重置宽或高
因为每当画布的高度或宽度被重置时,画布内容将被清空,所以它可以通过以下方式被清空:(该方法限于所有内容都需要被清除的情况)
var c=document . getelementbyid( my canvas );c .宽度=c .宽度;2、clearRect
var c=document . getelementbyid( my canvas );var CTX=c . get context( 2d );ctx.fillStyle= redctx.fillRect(0,0,300,150);ctx.clearRect(20,20,100,50);
3、globalCompositeOperation
引用globalCompositeOperation()函数,该函数用于在画布上组合颜色。我们可以利用这个原理,叠加原理(数学上的‘或’原理)来做橡皮擦。
首先,看看globalCompositeOperation属性可以设置的值,以及它们各自的效果:
值描述来源-超过默认值。在目标图像上显示源图像。源-顶部在目标图像的顶部显示源图像。目标图像之外的源图像部分是不可见的。Source-in显示目标图像中的源图像。目标图像中只有源图像的部分会被显示,目标图像是透明的。Source-out除了显示目标图像外,还显示源图像。仅显示目标图像的外部图像部分,并且目标图像是透明的。目标上方在源图像上方显示目标图像。目标-顶部在源图像的顶部显示目标图像。源图像以外的目标图像部分将不显示。目标输入显示源图像中的目标图像。只有源图像中目标图像的部分会被显示,源图像是透明的。目标输出显示源图像外部的目标图像。只有源图像之外的目标图像部分会被显示,源图像是透明的。打火机显示源图像和目标图像。复制显示源图像。忽略目标图像。源图像和目标图像通过异或运算进行合并。
!DOCTYPE htmlhtmlheadstylecavan { border:1px solid # d3d 3d 3;右边距:10px边距-底部:20px}/style/headsodyscriptvar gco=new Array();gco . push( source-atop );gco . push(“source-in”);gco . push(“source-out”);gco . push(“source-over”);gco . push( destination-atop );gco.push(目的地输入);gco . push(“destination-out”);gco.push(目的地结束);gco.push(打火机);gco . push( copy );gco . push( xor );for(n=0;ngco .长度;n){ document . write( div id= p _ n style= float:left; gco[n]:br );var c=document . createelement( canvas );c .宽度=120;c.height=100document.getElementById(p_ n)。appendChild(c);var CTX=c . get context( 2d );ctx.fillStyle= bluectx.fillRect(10,10,50,50);CTX . globalcompositeoperation=gco[n];CTX . begin path();ctx.fillStyle= redctx.arc(50,50,30,0,2 *数学。PI);CTX . fill();document . write(/div );}/脚本/正文/html
可以看出,如果将其设置为destination-out,则可以清除画布现有像素的图像。
清除绘制到画布上的线条(点擦除,线擦除)
在我最近实现的项目中,有一个笔刷功能,笔刷画出的线条可以用橡皮擦擦掉。有两种方法:一点擦除和线擦除。
以上两种方法也是可以的,但是如果这些线不止画一次,中间还有其他操作(比如画的内容改了一次之后),上面的方法就不好做了,因为每次都要反复画,还要保存擦除的数据。简单来说,为了达到这个目的,你可以将整个画布转换成一个base64编码的图像,然后在以后再次绘制的时候,在画布上绘制这个图像数据,并且可以继续绘制和擦除这个画布上的内容。但是无论如何也很难做到线条擦除的功能!
下面是另一种存储画线路径坐标的方法,实现画线后的点擦除和线擦除功能。
首先,介绍一下存储行的数据结构。可以大致看一下之前文章《js实现存储对象的数据结构hashTable和list》中hash结构的实现,但是快速查找键和值的优势需要明确。另外,在canvas绘制的各种形状和线条中,我们如何知道应该点击哪个元素和线条呢?055-79000实现原理在这个博客里有解释。
1. 线条存储及绘制
我存储在项目中的行散列结构的对象如下:
第一个扩展行“#8c471a”的键值详情如下。这些值包括colorKey、lineColor、lineWidth和最重要的列表结构的points对象,该列表结构是一个存储线所有点的坐标集的列表对象。
下面的代码实现了在画布上画线。二次贝塞尔函数用于使绘制的线条平滑无折痕。当只有一个点时,可以画一个点。
var count=this . points . length();var p:核心。point=this . points . get(0);if(isDrawHit){ CTX . stroke style=this . color key;} else { CTX . stroke style=this . line color;} ctx.lineCap= roundctx.lineJoin= round//转弯时没有尖角if(CTX . canvas . id== hit canvas )CTX . line width=this . line width橡皮擦半径;//扩大hit上线条的范围,橡皮半径elsectx . line width=this . line width;CTX . begin path();if (count=2) { ctx.moveTo(p.x,p . y);for(var I=1;我数-2;I){//p=this . points . get(I);//ctx.lineTo(p.x,p . y);if (this.points.get(i)。x==this.points.get(i 1)。x this.points.get(i)。y==this.points.get(i 1)。y)继续;var c=(this.points.get(i)。x this.points.get(i 1)。x)/2;var d=(this.points.get(i)。y this.points.get(i 1)。y)/2;CTX . quadratic curveto(this . points . get(I))。x,this.points.get(i)。y,c,d);//二次贝塞尔曲线函数}//对于最后2个点if (count=3) {CTX。二次曲线to (this.points.get (i))。x,this.points.get (i)。y,this.points.get (i 1)。x,this . points . } else if(count=2){ CTX . line to(this . points . get(1)。x,this.points.get(1)。y);} ctx.stroke()。} else { if(isDrawHit){ CTX . fill style=this . color key;} else { CTX . fill style=this . line color;} if(CTX . canvas . id== hit canvas )var radius=this . line width eraser radius;//在hit上扩大线条范围,rubber radius else var radius=this . line width;ctx.arc(this.points.get(0))。x,this.points.get(0)。y,半径,0,2 *数学。PI);CTX . fill();}在hitCanvas上绘图时,线宽放大,加入eraserRadius。下图是hitCanvas上绘制的colorKey线条,每条线条的颜色值就是上图中colorKey的键值。另外,线条的粗细明显要比上面的白线粗很多,因为橡皮擦是cur鼠标样式,半径很大,但是得到的鼠标点击位置只是一个像素坐标,所以为了扩大鼠标点到线条的范围而加粗。
2. 线擦除和点擦除
这样,行擦除很容易实现。你只需要找到橡皮擦点到画布上坐标点的颜色值,然后根据colorKey从hash集中删除该项,也就是删除整行。
擦除点需要考虑从两端或中间擦除:
如果(那个。iserasepoint){ line . points . foreach(function(I,p){//是橡皮擦与橡皮擦半径内直线上的点之间的距离if (math.pow (p.x-point.x,2) math.pow (p.y-point.y,)//橡皮擦半径内的点已经找到,这个点不存储在两个集合中的任何一个集合中} else {if (isSeparate) //找到后,下面的点将存储在另一个点集合points2.add(p)中;Else//在找到它之前,将点存储到points.add(p)中的点集points1} })//遍历完线上所有点后。根据points1和points2是否为空,擦除行if(points 1 . length()=1 points2 . length()=1){//points 1和points 2不为空,表示中间擦除改为两行varpreline=editor . common edit logic . clone penline(line);line.points=points1var line pen=editor . BD canvas . element factory . create penline(point,line.lineWidth,line . line color);line pen . points=points 2;editor . BD canvas . active element . set penline(line pen . color key,line pen);} else if(points 1 . length()==0 points 2 . length()=1){//从一端擦除line.points=points2} else if(points 1 . length()=1 points 2 . length()==0){//从一端擦除line.points=points1} else if(points 1 . length()==0 points 2 . length()==0){//线上所有点都被擦除,删除line editor . BD canvas . active element . delpenline(line . color key);} editor .课件. currentBlackboard.draw(false,true);}就是这样。这里介绍一下这篇关于清除画布内容(用点擦除线擦除)的文章。更多相关画布清理内容,请搜索以前的文章或继续浏览下面的相关文章。希望你以后能支持我!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。