Hoe het canvas te wissen om opnieuw te tekenen

Na te hebben geëxperimenteerd met composietbewerkingen en afbeeldingen op het canvas te hebben getekend, probeer ik nu afbeeldingen te verwijderen en compositie te maken. Hoe doe ik dit?

Ik moet het canvas wissen om andere afbeeldingen opnieuw te tekenen; dit kan een tijdje doorgaan, dus ik denk niet dat het de meest efficiënte optie is om elke keer een nieuwe rechthoek te tekenen.


Antwoord 1, autoriteit 100%

Aangezien canvaseen canvaselement is of een OffscreenCanvas-object,

const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);

Antwoord 2, autoriteit 51%

Gebruik: context.clearRect(0, 0, canvas.width, canvas.height);

Dit is de snelste en meest beschrijvende manier om het hele canvas leeg te maken.

Niet gebruiken: canvas.width = canvas.width;

Het resetten van canvas.widthstelt alle canvasstatussen opnieuw in (bijv. transformaties, lineWidth, strokeStyle, enz.), het is erg traag (vergeleken met clearRect), het werkt niet in alle browsers en het beschrijft niet wat u werkelijk probeert te doen.

Omgaan met getransformeerde coördinaten

Als u de transformatiematrix heeft gewijzigd (bijvoorbeeld met behulp van scale, rotateof translate), dan context.clearRect(0,0,canvas.width,canvas.height)zal waarschijnlijk niet het volledige zichtbare gedeelte van het canvas wissen.

De oplossing? Reset de transformatiematrix voordat u het canvas opruimt:

// Store the current transformation matrix
context.save();
// Use the identity matrix while clearing the canvas
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, canvas.width, canvas.height);
// Restore the transform
context.restore();

bewerken:
Ik heb net een profilering gedaan en (in chroom) het is ongeveer 10% sneller om een ​​canvas van 300×150 (standaardgrootte) te wissen zonder de transformatie opnieuw in te stellen. Omdat de grootte van uw canvas dit verschil verhoogt, druppels.

Dat is al relatief onbelangrijk, maar in de meeste gevallen zal u aanzienlijk meer tekenen dan u opruimt en ik geloof dat dit prestatieverschil irrelevant is.

100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear

3, Autoriteit 16%

Als u lijnen tekent, moet u ervoor zorgen dat u het niet vergeten:

context.beginPath();

Anders worden de lijnen niet gewist.


4, Autoriteit 8%

Andere hebben al een uitstekende baan gedaan die de vraag beantwoordt, maar als een eenvoudige clear()methode op het contextobject nuttig zou zijn (het was voor mij), dit is de implementatie die ik gebruik Gebaseerd op antwoorden hier:

CanvasRenderingContext2D.prototype.clear = 
  CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
    if (preserveTransform) {
      this.save();
      this.setTransform(1, 0, 0, 1, 0, 0);
    }
    this.clearRect(0, 0, this.canvas.width, this.canvas.height);
    if (preserveTransform) {
      this.restore();
    }           
};

Gebruik:

window.onload = function () {
  var canvas = document.getElementById('canvasId');
  var context = canvas.getContext('2d');
  // do some drawing
  context.clear();
  // do some more drawing
  context.setTransform(-1, 0, 0, 1, 200, 200);
  // do some drawing with the new transform
  context.clear(true);
  // draw more, still using the preserved transform
};

5, Autoriteit 2%

  • Chrome reageert goed op: context.clearRect ( x , y , w , h );zoals gesuggereerd door @ Pentium10 maar IE9 lijkt deze instructie volledig te negeren.
  • IE9 lijkt te reageren op: canvas.width = canvas.width;maar het maakt geen lijnen, alleenvormen, afbeeldingen en andere objecten, tenzij je @John allsopp’s oplossing van het eerste veranderende verandering ook gebruikt de breedte.

Dus als u een canvas en context hebt gemaakt als volgt:

var canvas = document.getElementById('my-canvas');
var context = canvas.getContext('2d');

U kunt een methode zoals deze gebruiken:

function clearCanvas(context, canvas) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  var w = canvas.width;
  canvas.width = 1;
  canvas.width = w;
}

6

Gebruik Clearrect-methode door X, Y-coördinaten en hoogte en breedte van canvas door te geven. Clearrect zal heel canvas wissen als:

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);

7

Een snelle manier is om te doen

canvas.width = canvas.width

idk hoe het werkt, maar het doet!


8

Er zijn hier een ton goede antwoorden.
Een nieuwe opmerking is dat het soms leuk is om het canvas slechts gedeeltelijk te wissen.
Dat wil zeggen, “fade” de vorige afbeelding in plaats van het volledig te wissen.
Dit kan mooie paden-effecten geven.

Het is gemakkelijk. Het veronderstellen van uw achtergrondkleur is wit:

// assuming background color = white and "eraseAlpha" is a value from 0 to 1.
myContext.fillStyle = "rgba(255, 255, 255, " + eraseAlpha + ")";
myContext.fillRect(0, 0, w, h);

Antwoord 9

Dit is wat ik gebruik, ongeacht grenzen en matrixtransformaties:

function clearCanvas(canvas) {
  const ctx = canvas.getContext('2d');
  ctx.save();
  ctx.globalCompositeOperation = 'copy';
  ctx.strokeStyle = 'transparent';
  ctx.beginPath();
  ctx.lineTo(0, 0);
  ctx.stroke();
  ctx.restore();
}

Kortom, het slaat de huidige staat van de context op en tekent een transparante pixel met copyals globalCompositeOperation. Herstelt vervolgens de vorige contextstatus.


Antwoord 10

Dit werkte voor mijn cirkeldiagram in chart.js

<div class="pie_nut" id="pieChartContainer">
    <canvas id="pieChart" height="5" width="6"></canvas> 
</div>
$('#pieChartContainer').html(''); //remove canvas from container
$('#pieChartContainer').html('<canvas id="pieChart" height="5" width="6"></canvas>'); //add it back to the container

Antwoord 11

Ik heb ontdekt dat in alle browsers die ik test, de snelste manier is om Rect daadwerkelijk te vullen met wit, of welke kleur je maar wilt. Ik heb een zeer grote monitor en in de modus volledig scherm is de clearRect tergend langzaam, maar de fillRect is redelijk.

context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);

Het nadeel is dat het canvas niet langer transparant is.


12

De kortste manier:

canvas.width += 0

13

Ik gebruik altijd

cxt.fillStyle = "rgb(255, 255, 255)";
cxt.fillRect(0, 0, canvas.width, canvas.height);

voor een aangepaste kleur en

ctx.clearRect(0, 0, canvas.width, canvas.height);

Voor het transparant van het canvas bij het opruimen van


14

In WebKit moet u de breedte instellen op een andere waarde, dan kunt u deze instellen op de initiële waarde


15

function clear(context, color)
{
    var tmp = context.fillStyle;
    context.fillStyle = color;
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    context.fillStyle = tmp;
}

16

Een eenvoudige, maar niet erg leesbare manier is om dit te schrijven:

var canvas = document.getElementId('canvas');
// after doing some rendering
canvas.width = canvas.width;  // clear the whole canvas

17

context.clearRect(0,0,w,h)   

Vul de gegeven rechthoek met RGBA-waarden:
0 0 0 0: met chrome |
0 0 0 255: Met FF & AMP; Safari

maar

context.clearRect(0,0,w,h);    
context.fillStyle = 'rgba(0,0,0,1)';  
context.fillRect(0,0,w,h);  

Laat de rechthoek gevuld met
0 0 0 255
Ongeacht de browser!


18

Context.clearRect(starting width, starting height, ending width, ending height);

Voorbeeld: context.clearRect(0, 0, canvas.width, canvas.height);


19

Ik gebruik dit altijd

ctx.clearRect(0, 0, canvas.width, canvas.height)
window.requestAnimationFrame(functionToBeCalled)

opmerking

Combineren van clearrect en een aanvragerImingFrame zorgt voor meer fluïdumanimatie als dat is waar u voor gaat


20

Snelste manier:

canvas = document.getElementById("canvas");
c = canvas.getContext("2d");
//... some drawing here
i = c.createImageData(canvas.width, canvas.height);
c.putImageData(i, 0, 0); // clear context by putting empty image data

21

Als u alleen clearrect gebruikt, als u het in een formulier hebt om uw tekening in te dienen, krijgt u een verzending in plaats daarvan de clearing of kan het eerst worden gewist en vervolgens een void-tekening uploadt, zodat u een lege tekening hebt. Om een ​​preventdefault toe te voegen aan het begin van de functie:

  function clearCanvas(canvas,ctx) {
        event.preventDefault();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }
<input type="button" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">

Ik hoop dat het iemand helpt.


22

Dit is een gratis handtekening canvas met een duidelijke canvas knop.
Bekijk dit live voorbeeldvan een canvas waarop u kunt tekenen en indien nodig ook wissen om opnieuw te tekenen clearRect()wordt gebruikt om het huidige canvas te verwijderen en fillRect()wordt gebruikt om opnieuw het oorspronkelijke canvas te tekenen dat schoon was en er geen tekeningen op stonden.

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    painting = false,
    lastX = 0,
    lastY = 0,
    lineThickness = 1;
canvas.width=canvas.height = 250;
ctx.fillRect(0, 0, 250, 250);
canvas.onmousedown = function(e) {
    painting = true;
    ctx.fillStyle = "#ffffff";
    lastX = e.pageX - this.offsetLeft;
    lastY = e.pageY - this.offsetTop;
};
canvas.onmouseup = function(e){
    painting = false;
}
canvas.onmousemove = function(e) {
    if (painting) {
        mouseX = e.pageX - this.offsetLeft;
        mouseY = e.pageY - this.offsetTop;
        // find all points between        
        var x1 = mouseX,
            x2 = lastX,
            y1 = mouseY,
            y2 = lastY;
        var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
        if (steep){
            var x = x1;
            x1 = y1;
            y1 = x;
            var y = y2;
            y2 = x2;
            x2 = y;
        }
        if (x1 > x2) {
            var x = x1;
            x1 = x2;
            x2 = x;
            var y = y1;
            y1 = y2;
            y2 = y;
        }
        var dx = x2 - x1,
            dy = Math.abs(y2 - y1),
            error = 0,
            de = dy / dx,
            yStep = -1,
            y = y1;
        if (y1 < y2) {
            yStep = 1;
        }
        lineThickness = 4;
        for (var x = x1; x < x2; x++) {
            if (steep) {
                ctx.fillRect(y, x, lineThickness , lineThickness );
            } else {
                ctx.fillRect(x, y, lineThickness , lineThickness );
            }
            error += de;
            if (error >= 0.5) {
                y += yStep;
                error -= 1.0;
            }
        }
        lastX = mouseX;
        lastY = mouseY;
    }
}
var button=document.getElementById("clear");
button.onclick=function clearcanvas(){
  canvas=document.getElementById("canvas"),
  ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 250, 250);
canvas.width=canvas.height = 250;
ctx.fillRect(0, 0, 250, 250);}
#clear{border-radius:10px;
font-size:8px !important;
position:absolute;
top:1px;}
#canvas{border-radius:10px}
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet"/>
<button id="clear" class="w3-padding w3-xxlarge w3-pink" type="button">Clear Canvas</button>
<canvas id="canvas"></canvas>

23

Dit zijn allemaal geweldige voorbeelden van hoe u een standaard canvas wist, maar als u PAPERJS gebruikt, werkt dit:

Definieer een globale variabele in JavaScript:

var clearCanvas = false;

Van uw paperscript definiëren:

function onFrame(event){
    if(clearCanvas && project.activeLayer.hasChildren()){
        project.activeLayer.removeChildren();
        clearCanvas = false;
    }
}

Waar je clearCanvas nu ook instelt op true, alle items worden van het scherm gewist.

Other episodes