Clear canvas contents (point erase + line erase)

Time:2020-11-22

Empty canvas contents

1. Reset width or height

Since canvas will be emptied every time the height or width is reset, the following method can be used to empty the canvas: (this method is only applicable to the case where all contents need to be cleared)


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

Reference the globalcompositeoperation() function, which is used to combine colors on the canvas. We can use this principle to make rubber by superposition (or principle in Mathematics).

First of all, let’s see what values can be set for the globalcompositeoperation property and what the effects are

value describe
source-over Default. Displays the source image on the target image.
source-atop Displays the source image at the top of the target image. The source is the part of the image that is not visible.
source-in Displays the source image in the target image. Only the part of the source image within the target image is displayed, and the target image is transparent.
source-out Displays the source image outside the target image. Only the external image part of the target image is displayed, and the target image is transparent.
destination-over Displays the target image above the source image.
destination-atop Displays the target image at the top of the source image. Parts of the target image other than the source image are not displayed.
destination-in Displays the target image in the source image. Only the part of the target image within the source image will be displayed, and the source image is transparent.
destination-out Display the target image outside the source image. Only the part of the target image outside the source image will be displayed, and the source image is transparent.
lighter Display source image + target image.
copy Displays the source image. Ignore the target image.
xor The XOR operation is used to combine the source image and the target image.

<!DOCTYPE html>
<html>
<head>
<style>
canvas
{
border:1px solid #d3d3d3;
margin-right:10px;
margin-bottom:20px;
}
</style>
</head>
<body>

<script>

var 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("destination-in");
gco.push("destination-out");
gco.push("destination-over");
gco.push("lighter");
gco.push("copy");
gco.push("xor");
for (n=0;n<gco.length;n++)
    {
    document.write("<div id='p_" + n + "' style='float:left;'>" + gco[n] + ":<br>");
    var c=document.createElement("canvas");
    c.width=120;
    c.height=100;
    document.getElementById("p_" + n).appendChild(c);
    var ctx=c.getContext("2d");
    ctx.fillStyle="blue";
    ctx.fillRect(10,10,50,50);
    ctx.globalCompositeOperation=gco[n];
    ctx.beginPath();
    ctx.fillStyle="red";
    ctx.arc(50,50,30,0,2*Math.PI);
    ctx.fill();
    document.write("</div>");
    }

</script>

</body>
</html>

It can be seen that if it is set to destination out, the image of existing pixels in canvas can be cleared.

Clear lines drawn to the canvas (point erase, line erase)

In my recently implemented project, there is a brush function. At the same time, the lines drawn by the brush can be erased by the eraser. There are two ways of erasing: a little erasing and line erasing.

The above two methods can also be used, but if these lines are drawn more than once, and there are other operations in the middle (for example, after the drawing content is changed once), the above method is not easy to do, because it is necessary to repeatedly draw and store the data after each erasure. In order to achieve this goal, the entire canvas canvas can be converted into a Base64 encoded image When the surface is drawn again, the image data is drawn to the canvas, and the contents can be continued to be drawn and erased on the canvas. But how to do line erase function is not good!

This paper introduces another method to store the coordinates of drawing path points to realize the function of point erasing and line erasing after drawing lines.

First of all, we will introduce the data structure of storage lines. In the previous article “hash table and list of data structures for storage objects implemented by JS”, you can take a general look at the implementation of hash structure, but the advantages of quick search of key and value need to be clear. In addition, how do we know which element and line to click on when we draw various shapes and lines in canvas? “Software project technology points (4) — click on the elements on the canvas” this blog explains the implementation principle.

1. Line storage and drawing

The objects of the line hash structure I stored in the project are as follows:

The details of expanding the first line key value to “ා 8c471a” are as follows. The value values include colorkey, linecolor, linewidth, and the most important points object in the list structure. It is a list object that stores the coordinate collection of all points on the line.

The following code, the implementation of drawing the line to the canvas. Using quadratic Bessel function makes the drawn lines smooth and smooth without creases. When there is only one point, a circle point can be drawn.

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'; // there is no sharp corner when turning
                if (ctx.canvas.id == "hitCanvas")
                    ctx.lineWidth  = this.lineWidth  +Eraserradius; // expand the range of lines on hit, rubber radius
                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); // quadratic Bessel curve function
                    }
                    // 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; // expand the range of lines on hit, rubber radius
                    else
                        var radius = this.lineWidth;
                    ctx.arc(this.points.get(0).x, this.points.get(0).y, radius, 0, 2 * Math.PI);
                    ctx.fill();
                }

When drawing on hitcanvas, the linewidth is enlarged and the eraserradius is added. The following figure shows the colorkey color lines drawn on hitcanvas. The color value of each line is the key value colorkey in the above figure. In addition, the thickness of the line is obviously much thicker than the white line above. Because the eraser is a cur mouse style, its radius is very large, but the mouse click position obtained is only a pixel coordinates, so in order to expand the range of the mouse point to the line, make it thicker.

2. Line erasure and point erasure

In this way, line erasing is very easy to achieve. You only need to find the color value of the coordinate points from the eraser point to the canvas, and then delete the item from the hash set according to the colorkey, that is, to delete the entire line.

Point erasure needs to consider erasing from both ends or from the middle

if (that.isErasePoint) {
                      line.points.foreach(function (i, p) {
                          //Is the distance between the eraser and the point on the line within the radius of the eraser
                          if (Math.pow(p.x - point.x, 2) + Math.pow(p.y - point.y, 2) <= Math.pow(eraserRadius, 2)) {
                              isSeparate = true;
			      //A point within the radius of the eraser has been found and is not stored in either of the two sets
                          } else {
                              if (isSeparate)
			      //After it is found, it will be stored in another point collection points
                                  points2.add(p);
                           Else // store the points in points1 before finding them
                                 points.add(p);
                         }
                     })
                     //After traversing all the points on the line points. According to whether points1 and Points2 are null, the line after point erasure is processed
                    if (points1.length() >= 1 && points2.length() >= 1) {
		    //Point and point S2 are not empty
                         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)
		     {
		           //Erase from one end
                         line.points = points2;
                     }
		     else if (points1.length() >= 1 && points2.length() == 0) 
		     {
		         //Erase from one end
                         line.points = points1;
                     } 
		     else if (points1.length() == 0 && points2.length() == 0)
		     {
		            //All points on the line are erased. Delete the line
                            editor.bdCanvas.activeElement.delPenLine(line.colorKey);               
			    }
                     editor.courseware.currentBlackboard.draw(false, true);
               }

This article about clearing canvas content (point erasure + line erasure) is introduced here. For more relevant canvas canvas cleaning content, please search the previous articles of developeppaer or continue to browse the related articles below. I hope you can support developeppaer more in the future!

Recommended Today

Configuring Maven with IntelliJ idea (getting started)

First of all, I declare that this article is not original by eamonsec. I don’t know where it came from now. Maybe the person I transferred is not original… 1. Download maven Official address:http://maven.apache.org/download.cgi Unzip and create a new local warehouse folder 2. Configure the local warehouse path   3. Configure Maven environment variables      4. Configure […]