javascript - Cómo limpiar el lienzo para volver a dibujar
html5 canvas (20)
Después de experimentar con operaciones compuestas y dibujar imágenes en el lienzo, ahora estoy tratando de eliminar las imágenes y la composición. ¿Cómo hago esto?
Necesito limpiar el lienzo para volver a dibujar otras imágenes; Esto puede continuar por un tiempo, así que no creo que dibujar un nuevo rectángulo cada vez sea la opción más eficiente.
Utilice: context.clearRect(0, 0, canvas.width, canvas.height);
Esta es la forma más rápida y descriptiva de limpiar todo el lienzo.
No utilice: canvas.width = canvas.width;
Restablecer canvas.width
restablece todo el estado del lienzo (por ejemplo, transformaciones, lineWidth, strokeStyle, etc.), es muy lento (comparado con clearRect), no funciona en todos los navegadores y no describe lo que realmente estás intentando que hacer.
Tratar con coordenadas transformadas
Si ha modificado la matriz de transformación (por ejemplo, utilizando scale
, rotate
o translate
), entonces context.clearRect(0,0,canvas.width,canvas.height)
probablemente no borrará toda la parte visible del lienzo.
¿La solución? Restablecer la matriz de transformación antes de borrar el lienzo:
// 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();
Edición: Acabo de hacer algunos perfiles y (en Chrome) es aproximadamente un 10% más rápido limpiar un lienzo de 300x150 (tamaño predeterminado) sin restablecer la transformación. A medida que el tamaño de tu lienzo aumenta esta diferencia disminuye.
Eso ya es relativamente insignificante, pero en la mayoría de los casos dibujará mucho más de lo que está despejando y creo que esta diferencia de rendimiento será irrelevante.
100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear
Descubrí que en todos los navegadores que pruebo, la forma más rápida es rellenar con blanco, o el color que desee. Tengo un monitor muy grande y en modo de pantalla completa, el clearRect es extremadamente lento, pero el fillRect es razonable.
context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);
El inconveniente es que el lienzo ya no es transparente.
Esto es 2018 y aún no hay un método nativo para borrar completamente el lienzo para volver a dibujar. clearRect()
no borra completamente el lienzo. Los dibujos de tipo sin relleno no se borran (por ejemplo, rect()
)
1. Para borrar completamente el lienzo independientemente de cómo dibujes:
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.beginPath();
Pros: Preserva strokeStyle, fillStyle, etc .; Sin retraso
Contras: no es necesario si ya estás utilizando beginPath antes de dibujar algo
2.Utilizando el corte ancho / alto:
context.canvas.width = context.canvas.width;
O
context.canvas.height = context.canvas.height;
Pros: Funciona con IE Contras: restablece strokeStyle, fillStyle a negro; Laggy
Me preguntaba por qué no existe una solución nativa. En realidad, se considera que clearRect()
es la solución de una sola línea porque la mayoría de los usuarios hacen beginPath()
antes de dibujar cualquier ruta nueva. Aunque beginPath solo se debe usar al dibujar líneas y no a caminos cerrados como rect().
Esta es la razón por la cual la respuesta aceptada no resolvió mi problema y terminé perdiendo horas intentando diferentes trucos. Maldito seas mozilla
Esto es lo que uso, independientemente de los límites y las transformaciones de 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();
}
Básicamente, guarda el estado actual del contexto y dibuja un píxel transparente con copy
como globalCompositeOperation
. Luego, restaura el estado de contexto anterior.
Esto funcionó para mi pieChart en 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
Hay un montón de buenas respuestas aquí. Una nota adicional es que a veces es divertido limpiar solo parcialmente el lienzo. es decir, "desvanece" la imagen anterior en lugar de borrarla por completo. Esto puede dar buenos efectos senderos.
es fácil. Suponiendo que su color de fondo es blanco:
// 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);
Otros ya han hecho un excelente trabajo respondiendo a la pregunta, pero si un método simple clear()
en el objeto de contexto sería útil para usted (lo fue para mí), esta es la implementación que uso en base a las respuestas aquí:
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
};
Si está dibujando líneas, asegúrese de no olvidar:
context.beginPath();
De lo contrario, las líneas no se borrarán.
Si solo utiliza clearRect, si lo tiene en un formulario para enviar su dibujo, obtendrá un envío en lugar de la limpieza, o tal vez se puede borrar primero y luego cargar un dibujo vacío, por lo que deberá agregar un preventDefault al principio de la función:
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 ayude a alguien.
Todos estos son excelentes ejemplos de cómo borrar un lienzo estándar, pero si está usando paperjs, esto funcionará:
Defina una variable global en JavaScript:
var clearCanvas = false;
De su PaperScript defina:
function onFrame(event){
if(clearCanvas && project.activeLayer.hasChildren()){
project.activeLayer.removeChildren();
clearCanvas = false;
}
}
Ahora, donde sea que establezca clearCanvas en true, borrará todos los elementos de la pantalla.
Una forma rápida es hacer
canvas.width = canvas.width
Idk cómo funciona pero lo hace!
Una forma simple, pero no muy legible es escribir esto:
var canvas = document.getElementId(''canvas'');
// after doing some rendering
canvas.width = canvas.width; // clear the whole canvas
Utilice el método clearRect pasando las coordenadas x, y y la altura y anchura del lienzo. ClearRect borrará todo el lienzo como:
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
en webkit necesita establecer el ancho en un valor diferente, luego puede volver a establecerlo en el valor inicial
la manera más 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(starting width, starting height, ending width, ending height);
Ejemplo: context.clearRect(0, 0, canvas.width, canvas.height);
const context = canvas.getContext(''2d'');
context.clearRect(0, 0, canvas.width, canvas.height);
context.clearRect(0,0,w,h)
Rellene el rectángulo dado con los valores RGBA:
0 0 0 0: con Chrome
0 0 0 255: con FF y Safari
Pero
context.clearRect(0,0,w,h);
context.fillStyle = ''rgba(0,0,0,1)'';
context.fillRect(0,0,w,h);
deja que el rectángulo se llene de
0 0 0 255
¡No importa el navegador!
function clear(context, color)
{
var tmp = context.fillStyle;
context.fillStyle = color;
context.fillRect(0, 0, context.canvas.width, context.canvas.height);
context.fillStyle = tmp;
}
- Chrome responde bien a:
context.clearRect ( x , y , w , h );
como lo sugiere @ Pentium10 pero IE9 parece ignorar completamente esta instrucción. - IE9 parece responder a:
canvas.width = canvas.width;
pero no borra líneas, solo formas, imágenes y otros objetos a menos que también use la solución de @John Allsopp de cambiar primero el ancho.
Así que si tienes un lienzo y un contexto creado así:
var canvas = document.getElementById(''my-canvas'');
var context = canvas.getContext(''2d'');
Puedes usar un 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;
}