千家信息网

在前端开发中如何清除canvas画布内容

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,本篇内容主要讲解"在前端开发中如何清除canvas画布内容",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"在前端开发中如何清除canvas画布内容"吧!清空
千家信息网最后更新 2026年11月04日在前端开发中如何清除canvas画布内容

本篇内容主要讲解"在前端开发中如何清除canvas画布内容",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"在前端开发中如何清除canvas画布内容"吧!

清空canvas画布内容

1、重置宽或高

由于canvas每当高度或宽度被重设时,画布内容就会被清空,因此可以用以下方法清空:(此方法仅限需要清除全部内容的情况):

var c=document.getElementById("myCanvas");  c.width=c.width;

2、clearRect

var c=document.getElementById("myCanvas");var ctx=c.getContext("2d");ctx.fillStyle="red";ctx.fillRect(0,0,300,150);ctx.clearRect(20,20,100,50);

3、globalCompositeOperation

引用globalCompositeOperation()函数,这个函数是用来在画布上组合颜色,我们可以利用这个原理,叠加(数学上的"或"原理)来制作橡皮。

首先看看globalCompositeOperation属性可以设置的值有哪些,分别是什么效果:

值描述
source-over默认。在目标图像上显示源图像。
source-atop在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。
source-in在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。
source-out在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。
destination-over在源图像上方显示目标图像。
destination-atop在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。
destination-in在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。
destination-out在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。
lighter显示源图像 + 目标图像。
copy显示源图像。忽略目标图像。
xor使用异或操作对源图像与目标图像进行组合。

可以看出如果设置成destination-out,就可以清除canvas现有的像素点的图像。

清除绘制到画布上的线条(点擦除,线擦除)

  在我最近实现的项目中有画笔功能, 同时画笔画出的线条可以被橡皮擦擦除,有点擦除和线擦除两种方式。

  使用以上两种方法也可以,但是如果这些线条不止绘制一次的话呢,中间有其他操作(例如绘制的内容变换一次后)那上面的方法就不容易做到了,因为要反复绘制存储每次擦除后的数据,简单的为了能达到该目的,可以将整个canvas画布转化成base64编码的image,后面再次绘制的时候把这个image数据再绘制到canvas上,可以继续在这个canvas上进行绘制和擦除内容。但是怎么样也不好做到线擦除的功能了!

  下面介绍另外一种存储绘制路径点坐标的方法去实现绘制线条后的点擦除和线擦除的功能。

  首先介绍下存储线条的数据结构,之前写的一篇《js实现存储对象的数据结构hashTable和list》大家可以先大致看看hash结构的实现,但是key和value快速查找的优势需要清楚。另外在canvas画的各种形状和线条,我们是如何知道点击到哪个元素哪条线?《软件项目技术点(4)--实现点击画布上元素》这篇博客里有说明实现原理。

1. 线条存储及绘制

项目中我存储的线条hash结构的对象如下:

展开第一个线条key值为"#8c471a"的具体信息如下,value值其中有colorKey,lineColor,lineWidth,以及最重要的List结构的points对象,是一个存储了该线条所有点坐标集合的List对象。

下面的一段代码,实现了绘制该线条到画布。使用二次贝塞尔函数使得绘制出来的线条流畅平滑没有折痕,当只有一个点时可绘制出一个圆点。

var count = this.points.length();                var p: Core.Point = this.points.get(0);                if (isDrawHit) {                    ctx.strokeStyle = this.colorKey;                }                else {                    ctx.strokeStyle = this.lineColor;                }                ctx.lineCap = "round";                ctx.lineJoin = 'round';//转折的时候不出现尖角                if (ctx.canvas.id == "hitCanvas")                    ctx.lineWidth = this.lineWidth + eraserRadius;//扩大hit上线条的范围,橡皮半径                else                    ctx.lineWidth = this.lineWidth;                ctx.beginPath();                if (count >= 2) {                    ctx.moveTo(p.x, p.y);                    for (var i = 1; i < count - 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)                            continue;                        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.quadraticCurveTo(this.points.get(i).x, this.points.get(i).y, c, d); //二次贝塞曲线函数                    }                    // For the last 2 points                    if (count >= 3) {                        ctx.quadraticCurveTo(                            this.points.get(i).x,                            this.points.get(i).y,                            this.points.get(i + 1).x,                            this.points.get(i + 1).y                        );                    } else if (count >= 2) {                        ctx.lineTo(this.points.get(1).x, this.points.get(1).y);                    }                    ctx.stroke();                } else {                    if (isDrawHit) {                        ctx.fillStyle = this.colorKey;                    }                    else {                        ctx.fillStyle = this.lineColor;                    }                    if (ctx.canvas.id == "hitCanvas")                        var radius = this.lineWidth + eraserRadius;//扩大hit上线条的范围,橡皮半径                    else                        var radius = this.lineWidth;                    ctx.arc(this.points.get(0).x, this.points.get(0).y, radius, 0, 2 * Math.PI);                    ctx.fill();                }

其中绘制到hitCanvas上的时候将lineWidth扩大加上了eraserRadius(圆形橡皮擦半径),下图即为绘制到hitCanvas上的colorKey颜色线条,每个线条颜色值是上图中的key值colorKey。另外线条粗细明显比上面的白色线条要粗很多,因为橡皮擦是个cur鼠标样式它的半径很大,但获取的鼠标点击位置还只是一个像素点坐标,所以为了扩大鼠标点到线条上的范围将其变粗。

2. 线擦除和点擦除

这样线擦除就很容易实现,只需要找到橡皮擦点到画布上的坐标点的色值,就其从hash集合中根据colorKey删除掉该项,即实现了删除整条线。

点擦除就需要考虑到从两端擦除或者从中间擦除的情况:

     if (that.isErasePoint) {                      line.points.foreach(function (i, p) {                          //橡皮擦距离该线条上点的距离是否在橡皮擦半径范围内                          if (Math.pow(p.x - point.x, 2) + Math.pow(p.y - point.y, 2) <= Math.pow(eraserRadius, 2)) {                              isSeparate = true;                              //已经找到橡皮擦半径范围内的点,该点不存入两个集合中的任何一个                          } else {                              if (isSeparate)                              //找到后将之后的点存入另一个点集合points中                                  points2.add(p);                           else//找到之前将点存入点集合points1中                                 points.add(p);                         }                     })                     //遍历完线条points上的所有点后。根据points1和points2是否为空处理点擦除后的线条                    if (points1.length() >= 1 && points2.length() >= 1) {                    //points1和points2都不为空,说明从中间擦除变为两条线                         var preLine = editor.commonEditLogic.clonePenLine(line);                        line.points = points1;                         var linePen = editor.bdCanvas.elementFactory.createPenLine(point, line.lineWidth, line.lineColor);                         linePen.points = points2;                                                             editor.bdCanvas.activeElement.setPenLine(linePen.colorKey, linePen);                     }                      else if (points1.length() == 0 && points2.length() >= 1)                     {                           //从一端擦除                         line.points = points2;                     }                     else if (points1.length() >= 1 && points2.length() == 0)                      {                         //从一端擦除                         line.points = points1;                     }                      else if (points1.length() == 0 && points2.length() == 0)                     {                            //线条上的点全部被擦除,删除该线条                            editor.bdCanvas.activeElement.delPenLine(line.colorKey);                                           }                     editor.courseware.currentBlackboard.draw(false, true);               }

到此,相信大家对"在前端开发中如何清除canvas画布内容"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

线条 图像 目标 源图 画布 内容 橡皮 存储 部分 半径 方法 橡皮擦 结构 只有 对象 数据 范围 前端 开发 函数 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技名片 广州善班互联网科技 撒么互联网科技公司 互联网前沿科技 丰台科技园 互联网公司 甘肃拓世互联网科技有限公司 福州新华互联网科技学校 知乎 小米互联网科技园设置 互联网金融中的现代科技 杭州壁岐互联网科技有限公司 互联网科技创新的路径 长沙茂晟互联网科技有限公司 下一代互联网重大应用科技园 世界互联网科技成果奖 互联网高科技行业有哪些企业 湖北辰鑫科技互联网 安徽九吞吴互联网科技有限公司 科技互联网企业在行动 互联网科技快速发展优美句子 广州全民伙伴互联网科技有限公司 互联网科技公司发展 广西互联网科技公司 长亮科技互联网金融 北京大学互联网科技怎么样 汽车互联网创新科技园 有人说阿里系是互联网科技企业 南京一网一红互联网科技有限公司 绵阳真晨互联网科技有限公司 华人运通互联网科技公司 东风日产互联网科技公司叫什么
0