Como limpar a tela para redesenhar

Depois de experimentar com operações compostas e desenhar imagens na tela, estou agora a tentar remover imagens e composição. Como faço isto?

Preciso de limpar a área de desenho para redesenhar outras imagens; isto pode continuar por um tempo, por isso não me parece que desenhar um novo rectângulo cada vez seja a opção mais eficiente.

Author: Sohaib Mohammed, 2010-01-26

20 answers

const context = canvas.getContext('2d');

context.clearRect(0, 0, canvas.width, canvas.height);
 1004
Author: Pentium10, 2018-04-13 11:22:28

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

Esta é a maneira mais rápida e descritiva de limpar toda a tela.

Não utilize: canvas.width = canvas.width;

Reiniciar canvas.width reinicia todo o estado da tela (por exemplo, transformações, lineWidth, strokeStyle, etc.), é muito lento (comparado com clearRect), não funciona em todos os navegadores, e não descreve o que você está realmente tentando fazer.

Lidar com coordenadas transformadas

Se modificou a matriz de transformação (por exemplo, usando scale, rotate, ou translate) então context.clearRect(0,0,canvas.width,canvas.height) provavelmente não irá limpar toda a parte visível da tela.

A solução? Reiniciar a matriz de transformação antes de limpar a área de desenho:
// 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();

Editar: Acabei de fazer alguns perfis e (no Chrome) é cerca de 10% mais rápido para limpar uma área de 300x150 (tamanho padrão) sem reiniciar a transformação. À medida que o tamanho da sua tela aumenta esta diferença cai.

Isso já é relativamente insignificante., mas, na maioria dos casos, o Senhor Comissário vai desenhar consideravelmente mais do que aquilo que está a limpar e creio que esta diferença de desempenho é irrelevante.
100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear
 669
Author: Prestaul, 2015-03-30 19:19:00

Se está a desenhar linhas, certifique-se de que não se esquece:

context.beginPath();
Caso contrário, as linhas não serão desimpedidas.
 194
Author: trembl, 2011-01-13 07:12:09

Outros já fizeram um excelente trabalho respondendo à pergunta, mas se um método simples clear() sobre o objeto de contexto seria útil para você (foi para mim), esta é a implementação que eu uso com base em Respostas aqui:

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();
    }           
};

Utilização:

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
};
 109
Author: JonathanK, 2013-03-29 05:17:35
  • O Chrome responde bem a: context.clearRect ( x , y , w , h ); como sugerido por @Pentium10, mas o IE9 parece ignorar completamente esta instrução.
  • O IE9 parece responder a: canvas.width = canvas.width; mas não desimpede linhas, apenas formas, imagens e outros objectos, a não ser que use também a solução de @John Allsopp para mudar primeiro a largura.
Então, se você tem uma tela e um contexto criados assim:
var canvas = document.getElementById('my-canvas');
var context = canvas.getContext('2d');

Podes usar um método como este:

function clearCanvas(context, canvas) {
  context.clearRect(0, 0, canvas.width, canvas.height);
  var w = canvas.width;
  canvas.width = 1;
  canvas.width = w;
}
 33
Author: grenade, 2010-11-03 10:02:07

Usar o método clearRect passando por coordenadas x, y e altura e largura da área de desenho. O ClearRect irá limpar toda a área de desenho como:

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
 19
Author: Vishwas, 2014-01-10 04:54:14
Há muitas boas respostas aqui. uma nota adicional é que às vezes é divertido apenas parcialmente limpar a tela. ou seja," desvanecer " a imagem anterior em vez de apagá-la completamente. isto pode dar bons efeitos de trilhas. É fácil. supondo que a sua cor de fundo é branca:
// 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);
 13
Author: orion elenzil, 2012-05-04 04:36:42
Este é 2018 e ainda não há nenhum método nativo para limpar completamente a tela para redesenhar. clearRect() não limpa completamente a tela. Os desenhos do tipo não preenchido não são eliminados (por exemplo. rect())

1.To completamente limpar a tela independentemente de como desenhar:

context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.beginPath();

Prós: preserva o strokeStyle, o fillStyle, etc.; Sem lag;

Cons: desnecessário se já estiver a utilizar beginPath antes de desenhar qualquer coisa

2.Usar a largura/altura hack:

context.canvas.width = context.canvas.width;

Ou

context.canvas.height = context.canvas.height;
Prós: trabalha com IE Cons: repõe o strokeStyle, o fillStyle no preto; Laggy; Estava a pensar porque é que uma solução nativa não existe. Na verdade, clearRect() é considerado como a solução de linha única porque a maioria dos utilizadores faz beginPath() antes de desenhar qualquer novo caminho. Embora o beginPath só deva ser usado ao desenhar linhas e não fechar caminho como rect(). Esta é a razão pela qual a resposta aceite não resolveu o meu problema e acabei por perder horas. a tentar golpes diferentes. Maldito mozilla.
 6
Author: sziraqui, 2018-06-29 06:24:00

Na webkit você precisa definir a largura para um valor diferente, então você pode configurá-la de volta para o valor inicial

 4
Author: John Allsopp, 2010-08-02 04:50:02
Descobri que em todos os navegadores que testo, a maneira mais rápida é preencher o branco ou a cor que quiser. Eu tenho um monitor muito grande e em Modo de tela cheia o clearRect é agonizingly lento, mas o fillRect é razoável.
context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);

A desvantagem é que a tela já não é transparente.

 4
Author: John Page, 2013-03-25 22:29:13
function clear(context, color)
{
    var tmp = context.fillStyle;
    context.fillStyle = color;
    context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    context.fillStyle = tmp;
}
 4
Author: Imagine Breaker, 2014-04-11 11:39:15
Isto funcionou para o meu pieChart no gráfico.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
 4
Author: Sanal S, 2016-02-26 12:36:33

Uma maneira rápida é fazer

canvas.width = canvas.width

Imagina como funciona, mas funciona!

 4
Author: Jacob Morris, 2018-05-08 16:56:54

A maneira mais rápida:

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
 2
Author: elser, 2012-08-13 18:32:05

Isto é o que eu uso, independentemente dos limites e transformações da matriz:

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();
}

Basicamente, ele guarda o estado actual do contexto, e desenha um pixel transparente com copy Como globalCompositeOperation. Então, restaura o estado de contexto anterior.

 2
Author: superruzafa, 2018-05-28 15:34:46

Uma maneira simples, mas não muito legível é escrever isto:

var canvas = document.getElementId('canvas');

// after doing some rendering

canvas.width = canvas.width;  // clear the whole canvas
 1
Author: Chang, 2017-08-24 21:34:50
context.clearRect(0,0,w,h)   

Preencha o rectângulo indicado com os valores de RGBA:
0 0 0 0: com cromo
0 0 0 255: com FF & Safari

Mas

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

Deixar o rectângulo cheio de
0 0 0 255
não importa o navegador !

 0
Author: Philippe Oceangermanique, 2016-12-12 09:53:44

Se usar o clearRect apenas, se o tiver num formulário para enviar o seu desenho, irá obter um submit em vez da compensação, ou talvez possa ser limpo primeiro e depois enviar um desenho vazio, por isso terá de adicionar um salto preventivo no início da função:

   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);">
Espero que ajude alguém.
 0
Author: JoelBonetR, 2017-01-10 18:14:56
Context.clearRect(starting width, starting height, ending width, ending height);
Exemplo: context.clearRect(0, 0, canvas.width, canvas.height);
 0
Author: Gavin T, 2017-09-30 16:00:04

Todos estes são grandes exemplos de como você limpa uma tela padrão, mas se você está usando paperjs, então isso vai funcionar:

Defina uma variável global em JavaScript:

var clearCanvas = false;

A partir do teu programa define:

function onFrame(event){
    if(clearCanvas && project.activeLayer.hasChildren()){
        project.activeLayer.removeChildren();
        clearCanvas = false;
    }
}
Agora, onde quer que defina o clearCanvas como verdadeiro, ele irá limpar todos os itens da tela.
 -1
Author: Robert Ogle, 2012-07-21 03:03:19