Jak wyczyścić płótno w celu przerysowania

Po eksperymentowaniu z operacjami kompozytowymi i rysowaniem obrazów na płótnie próbuję teraz usunąć obrazy i komponować. Jak to zrobić?

Muszę wyczyścić płótno do przerysowania innych obrazów; może to trwać przez jakiś czas, więc nie sądzę, że rysowanie nowego prostokąta za każdym razem będzie najbardziej efektywną opcją.

Author: Sohaib Mohammed, 2010-01-26

20 answers

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

context.clearRect(0, 0, canvas.width, canvas.height);
 1004
Author: Pentium10,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-13 11:22:28

Użycie: context.clearRect(0, 0, canvas.width, canvas.height);

Jest to najszybszy i najbardziej opisowy sposób wyczyszczenia całego płótna.

Nie stosować: canvas.width = canvas.width;

Resetowanie canvas.width resetuje cały stan płótna (np. transformacje, liniowość, strokeStyle itp.), jest bardzo powolny (w porównaniu do clearRect), nie działa we wszystkich przeglądarkach i nie opisuje tego, co naprawdę próbujesz zrobić.

Zajmowanie się przekształceniami współrzędnych

Jeśli zmodyfikowałeś macierz transformacji (np. używając scale, rotate, lub translate) wtedy context.clearRect(0,0,canvas.width,canvas.height) prawdopodobnie nie wyczyści całej widocznej części płótna.

Rozwiązanie? Reset macierzy transformacji przed wyczyszczeniem płótna:

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

Edit: Właśnie zrobiłem profilowanie i (w Chrome) jest o 10% szybciej wyczyścić płótno 300x150 (domyślny rozmiar) bez resetowania transformacji. Wraz ze wzrostem rozmiaru płótna ta różnica spada.

To już stosunkowo mało znaczące, ale w większości sprawy, które będziesz rysować znacznie więcej niż rozliczasz i uważam, że ta różnica w wydajności jest nieistotna.

100000 iterations averaged 10 times:
1885ms to clear
2112ms to reset and clear
 669
Author: Prestaul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-30 19:19:00

Jeśli rysujesz linie, upewnij się, że nie zapomnisz:

context.beginPath();

W przeciwnym razie linie nie zostaną wyczyszczone.

 194
Author: trembl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-13 07:12:09

Inni wykonali już świetną robotę odpowiadając na pytanie, ale jeśli prosta metoda clear() na obiekcie context byłaby dla Ciebie przydatna (była dla mnie), to jest to implementacja, której używam w oparciu o odpowiedzi tutaj:

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

Użycie:

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-29 05:17:35
  • Chrome dobrze reaguje na: context.clearRect ( x , y , w , h ); zgodnie z sugestią @ Pentium10, ale IE9 zdaje się całkowicie ignorować tę instrukcję.
  • IE9 wydaje się odpowiadać na: canvas.width = canvas.width; ale nie usuwa linii, tylko kształty, obrazy i inne obiekty, chyba że użyjesz również rozwiązania @John Allsopp ' s pierwszej zmiany szerokości.

Więc jeśli masz płótno i kontekst utworzony w ten sposób:

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

Możesz użyć takiej metody:

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-03 10:02:07

Użyj metody clearRect, przekazując współrzędne x, y oraz wysokość i szerokość płótna. ClearRect wyczyści całe płótno jako:

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
 19
Author: Vishwas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-10 04:54:14

Jest tu mnóstwo dobrych odpowiedzi. jeszcze jedna uwaga jest taka, że czasami fajnie jest tylko częściowo wyczyścić płótno. oznacza to, że" zanikają " poprzedni obraz zamiast całkowicie go kasować. może to dać ładne efekty szlaków.

To proste. przypuśćmy, że twój kolor tła jest biały:
// 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-04 04:36:42

Jest rok 2018 i nadal nie ma natywnej metody, aby całkowicie wyczyścić płótno do ponownego rysowania. clearRect() czy nie wyczyści płótna całkowicie. Rysunki typu bez wypełnienia nie są usuwane (np. rect())

1.To CAŁKOWICIE Wyczyść płótno niezależnie od tego, jak rysujesz:

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

Plusy: zachowuje strokeStyle, fillStyle itp.; No lag;

Wady: niepotrzebne, jeśli używasz już beginPath przed rysowaniem czegokolwiek

2.Korzystanie z szerokości / wysokości hack:

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

Lub

context.canvas.height = context.canvas.height;

Plusy: współpracuje z IE Wady: resetuje strokeStyle, fillStyle do czarnego; Laggy;

Zastanawiałem się, dlaczego natywne rozwiązanie nie istnieje. W rzeczywistości, {[3] } jest uważane za rozwiązanie jednoliniowe, ponieważ większość użytkowników robi beginPath() przed narysowaniem nowej ścieżki. Chociaż beginPath może być używany tylko podczas rysowania linii, a nie zamkniętej ścieżki jak rect().

To jest powód, dla którego przyjęta odpowiedź nie rozwiązała mojego problemu i skończyło się na marnowaniu godzin próbuję różnych hacków. Curse you mozilla

 6
Author: sziraqui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-29 06:24:00

W webkit musisz ustawić szerokość na inną wartość, następnie możesz ustawić ją z powrotem na wartość początkową

 4
Author: John Allsopp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-02 04:50:02

Odkryłem, że we wszystkich przeglądarkach, które testuję, najszybszym sposobem jest wypełnienie białym, lub jakimkolwiek innym kolorem. Mam bardzo duży monitor i w trybie pełnoekranowym clearRect jest strasznie powolny, ale fillRect jest rozsądny.

context.fillStyle = "#ffffff";
context.fillRect(0,0,canvas.width, canvas.height);
Wadą jest to, że płótno nie jest już przezroczyste.
 4
Author: John Page,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-11 11:39:15

To zadziałało dla mojego piecharta w 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
 4
Author: Sanal S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-26 12:36:33

Szybki sposób to zrobić

canvas.width = canvas.width

Idk jak to działa, ale działa!

 4
Author: Jacob Morris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-08 16:56:54

Najszybszy sposób:

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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-13 18:32:05

Tego używam, niezależnie od granic i przekształceń macierzy:

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

Zasadniczo zapisuje bieżący stan kontekstu i rysuje przezroczysty piksel z copy jako globalCompositeOperation. Następnie przywraca poprzedni stan kontekstu.

 2
Author: superruzafa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-28 15:34:46

Prostym, ale niezbyt czytelnym sposobem jest napisanie tego:

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

// after doing some rendering

canvas.width = canvas.width;  // clear the whole canvas
 1
Author: Chang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-24 21:34:50
context.clearRect(0,0,w,h)   

Wypełnij podany prostokąt wartościami RGBA:
0 0 0 0: z chromem
0 0 0 255: z FF & Safari

Ale

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

Niech prostokąt wypełniony
0 0 0 255
bez względu na przeglądarkę !

 0
Author: Philippe Oceangermanique,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 09:53:44

Jeśli używasz tylko clearRect, jeśli masz go w formularzu do przesłania rysunku, otrzymasz submit zamiast wyczyszczenia, a może można go najpierw wyczyścić, a następnie przesłać pusty rysunek, więc musisz dodać preventDefault na początku funkcji:

   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);">
Mam nadzieję, że to komuś pomoże.
 0
Author: JoelBonetR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-10 18:14:56
Context.clearRect(starting width, starting height, ending width, ending height);

Przykład: context.clearRect(0, 0, canvas.width, canvas.height);

 0
Author: Gavin T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-30 16:00:04

To wszystko są świetne przykłady jak wyczyścić standardowe płótno, ale jeśli używasz paperjs, to zadziała:]}

Zdefiniuj zmienną globalną w JavaScript:

var clearCanvas = false;

Z twojego PaperScript zdefiniuj:

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

Teraz gdziekolwiek ustawisz clearCanvas na true, wyczyści wszystkie elementy z ekranu.

 -1
Author: Robert Ogle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-21 03:03:19