Como limpar a tela para redesenhar
-
22-09-2019 - |
Pergunta
Depois de experimentar operações compostas e desenhar imagens na tela, agora estou tentando remover imagens e composições. Como eu faço isso?
Preciso limpar a tela para redesenhar outras imagens; Isso pode continuar por um tempo, então não acho que desenhar um novo retângulo toda vez que será a opção mais eficiente.
Solução
const context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
Outras dicas
Usar: context.clearRect(0, 0, canvas.width, canvas.height);
Esta é a maneira mais rápida e descritiva de limpar a tela inteira.
Não use: canvas.width = canvas.width;
Redefinição canvas.width
Redefina todos os estados da tela (por exemplo, transformações, largura de linha, Strokestyle etc.), é muito lento (em comparação com o ClearRect), não funciona em todos os navegadores e não descreve o que você está realmente tentando fazer.
Lidar com coordenadas transformadas
Se você 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 limpará toda a parte visível da tela.
A solução? Redefina a matriz de transformação antes de limpar a tela:
// 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 um perfil e (no Chrome) é cerca de 10% mais rápido para limpar uma tela de 300x150 (tamanho padrão) sem redefinir a transformação. À medida que o tamanho da sua tela aumenta, essa diferença cai.
Isso já é relativamente insignificante, mas na maioria dos casos você estará atraindo consideravelmente mais do que está limpando e acredito que essa diferença de desempenho seja irrelevante.
100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear
Se você estiver desenhando linhas, certifique -se de não esquecer:
context.beginPath();
Caso contrário, as linhas não serão liberadas.
Outros já fizeram um excelente trabalho respondendo à pergunta, mas se um simples clear()
O método no objeto de contexto seria útil para você (foi para mim), esta é a implementação que eu uso com base nas 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();
}
};
Uso:
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
};
- Chrome responde bem a:
context.clearRect ( x , y , w , h );
Conforme sugerido por @pentium10, mas o IE9 parece ignorar completamente esta instrução. - IE9 parece responder a:
canvas.width = canvas.width;
Mas não limpa linhas, apenas formas, imagens e outros objetos, a menos que você também use a solução da @John Allsopp de alterar primeiro a largura.
Então, se você tem uma tela e um contexto criado assim:
var canvas = document.getElementById('my-canvas');
var context = canvas.getContext('2d');
Você pode 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;
}
Use o método ClearRect passando x, y coordenadas e altura e largura da tela. ClearRect vai limpar a tela inteira como:
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
Este é 2018 e ainda não existe um método nativo para limpar completamente a tela para redesenhar. clearRect()
não Limpe a tela completamente. Os desenhos do tipo não preenchem não são limpos (por exemplo. rect()
)
1.to completamente Limpa de tela, independentemente de como você desenha:
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.beginPath();
Prós: preserva o Strokestyle, Fillstyle etc.; Sem atraso;
Contras: desnecessário se você já está usando o BEGNATH antes de desenhar qualquer coisa
2. Usando o hack de largura/altura:
context.canvas.width = context.canvas.width;
OU
context.canvas.height = context.canvas.height;
Prós: Trabalha com o IE Contras: Redefine o Strokestyle, Fillstyle para Black; Laggy;
Eu queria saber por que uma solução nativa não existe. Na realidade, clearRect()
é considerado a solução de linha única porque a maioria dos usuários faz beginPath()
antes de desenhar qualquer novo caminho. Embora o BELKPATH seja apenas para ser usado enquanto desenham linhas e não fechado como caminho como rect().
Esta é a razão pela qual a resposta aceita não resolveu meu problema e acabei perdendo horas tentando hacks diferentes. Amaldiçoar você Mozilla
Há uma tonelada de boas respostas aqui. Uma nota adicional é que, às vezes, é divertido limpar apenas parcialmente a tela. isto é, "desaparecer" a imagem anterior, em vez de apagá -la completamente. Isso pode dar bons efeitos de trilhas.
é fácil. Supondo que sua cor de fundo seja 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);
Uma maneira rápida é fazer
canvas.width = canvas.width
Idk como funciona, mas funciona!
No webkit, você precisa definir a largura como um valor diferente, então você pode colocá -lo novamente no valor inicial
Descobri que, em todos os navegadores que testo, a maneira mais rápida é realmente preencher com a cor branca ou tudo o que você gostaria. Eu tenho um monitor muito grande e, em modo de tela inteira, o ClearRect é agonizantemente lento, mas o Fillrect é razoável.
context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);
A desvantagem é que a tela não é mais transparente.
function clear(context, color)
{
var tmp = context.fillStyle;
context.fillStyle = color;
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
context.fillStyle = tmp;
}
Isso funcionou para o meu Piechart em 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
É isso 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, salva o estado atual do contexto e desenha um pixel transparente com copy
Como globalCompositeOperation
. Em seguida, restaura o estado de contexto anterior.
Uma maneira simples, mas não muito legível, é escrever isso:
var canvas = document.getElementId('canvas');
// after doing some rendering
canvas.width = canvas.width; // clear the whole canvas
Eu sempre uso
cxt.fillStyle = "rgb(255, 255, 255)";
cxt.fillRect(0, 0, canvas.width, canvas.height);
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
context.clearRect(0,0,w,h)
Preencha o retângulo fornecido com os valores RGBA:
0 0 0: com Chrome
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);
Deixe o retângulo cheio de
0 0 0 255
Não importa o navegador!
Se você usar apenas o ClearRect, se você o tiver em um formulário para enviar seu desenho, receberá um envio em vez disso, ou talvez possa ser liberado primeiro e depois enviar um desenho vazio, para que você precise adicionar um prevenirdefault 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.
Context.clearRect(starting width, starting height, ending width, ending height);
Exemplo: context.clearRect(0, 0, canvas.width, canvas.height);
Todos esses são ótimos exemplos de como você limpa uma tela padrão, mas se você estiver usando o PaperJs, isso funcionará:
Defina uma variável global em JavaScript:
var clearCanvas = false;
Do seu documentos, defina:
function onFrame(event){
if(clearCanvas && project.activeLayer.hasChildren()){
project.activeLayer.removeChildren();
clearCanvas = false;
}
}
Agora, onde quer que você defina ClearCanvas como TRUE, ele limpará todos os itens da tela.