Как очистить холст для перерисовки

После экспериментов с композитными операциями и рисования изображений на холсте я теперь пытаюсь удалить изображения и компоновку. Как это сделать?

Мне нужно очистить холст для перерисовки других изображений; это может продолжаться некоторое время, поэтому я не думаю, что каждый раз лучший выбор будет рисовать новый прямоугольник.

Ответы

Ответ 1

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

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

Ответ 2

Использование: context.clearRect(0, 0, canvas.width, canvas.height);

Это самый быстрый и описательный способ очистки всего холста.

Не использовать: canvas.width = canvas.width;

Сброс canvas.width сбрасывает все состояние холста (например, преобразования, lineWidth, strokeStyle и т.д.), он очень медленный (по сравнению с clearRect), он не работает во всех браузерах, и он не описывает, что вы на самом деле пытаются сделать.

Работа с преобразованными координатами

Если вы изменили матрицу преобразования (например, используя scale, rotate или translate), тогда context.clearRect(0,0,canvas.width,canvas.height), скорее всего, не очистит всю видимую часть холста.

Решение? Reset матрица преобразования до очистки холста:

// 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: Я только что сделал профилирование и (в Chrome) он на 10% быстрее очищает холст размером 300x150 (размер по умолчанию) без сброса преобразования. По мере увеличения размера вашего холста это различие падает.

Это уже относительно незначительно, но в большинстве случаев вы будете рисовать значительно больше, чем вы очищаете, и я считаю, что разница в производительности не имеет значения.

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

Ответ 3

Если вы рисуете строки, убедитесь, что вы не забыли:

context.beginPath();

В противном случае строки не будут очищены.

Ответ 4

Другие уже сделали отличную работу, отвечая на вопрос, но если бы простой метод clear() для контекстного объекта был бы вам полезен (это было для меня), это реализация, которую я использую на основе ответов здесь:

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

Использование:

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

  • Chrome хорошо реагирует на: context.clearRect ( x , y , w , h );, как это было предложено компанией @Pentium10, но IE9, похоже, полностью игнорирует эту инструкцию.
  • Кажется, что IE9 отвечает на: canvas.width = canvas.width;, но он не очищает строки, только фигуры, изображения и другие объекты, если вы также не используете решение @John Allsopp с первой заменой ширины.

Итак, если у вас есть холст и контекст, созданные следующим образом:

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

Вы можете использовать такой способ:

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

Ответ 6

Используйте метод clearRect, передавая координаты x, y, а также высоту и ширину холста. ClearRect очистит весь холст как:

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

Ответ 7

Это 2018 год, и до сих пор нет собственного способа полностью очистить холст для перерисовки. clearRect() не очищает холст полностью. Чертежи незаполненного типа не очищаются (например, rect())

1. Чтобы полностью очистить холст, независимо от того, как вы рисуете:

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

Плюсы: сохраняет инсульты, fillStyle и т.д.; Нет лагов;

Минусы: не нужны, если вы уже используете beginPath перед рисованием чего-либо

2. Используя хак ширины/высоты:

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

ИЛИ ЖЕ

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

Плюсы: Работает с IE. Минусы: Сбрасывает strokeStyle, fillStyle в черный; лаг;

Мне было интересно, почему родного решения не существует. На самом деле, clearRect() рассматривается как однострочное решение, потому что большинство пользователей делают beginPath() перед рисованием любого нового пути. Хотя beginPath должен использоваться только при рисовании линий, а не с закрытым путем, как rect().

Это причина, по которой принятый ответ не решил мою проблему, и я потратил часы, пытаясь использовать различные способы взлома. Проклинаю тебя мозилла

Ответ 8

здесь есть тонна хороших ответов. еще одно замечание состоит в том, что иногда это забавно лишь частично очистить холст. то есть "выцветать" предыдущее изображение, а не стирать его полностью. это может дать хорошие эффекты трасс.

Это легко. Предположим, что цвет фона белый:

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

Ответ 9

Быстрый способ сделать

canvas.width = canvas.width

ИДК, как это работает, но это делает!

Ответ 10

в webkit вам нужно установить ширину на другое значение, после чего вы можете вернуть ее к исходному значению

Ответ 11

Я обнаружил, что во всех браузерах, которые я тестирую, самым быстрым способом является на самом деле fillRect с белым или любым желаемым цветом. У меня очень большой монитор, и в полноэкранном режиме clearRect мучительно медленный, но fillRect разумен.

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

Недостаток в том, что холст уже не прозрачен.

Ответ 12

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

Ответ 13

Это сработало для моего pieChart в 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

Ответ 14

Это то, что я использую, независимо от границ и матричных преобразований:

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

По сути, он сохраняет текущее состояние контекста и рисует прозрачный пиксель с copy как globalCompositeOperation. Затем восстанавливает предыдущее состояние контекста.

Ответ 15

Самый быстрый способ:

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

Ответ 16

Простой, но не очень читаемый способ заключается в следующем:

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

// after doing some rendering

canvas.width = canvas.width;  // clear the whole canvas

Ответ 17

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

заполнить данный прямоугольник значениями RGBA:
0 0 0 0: с Chrome
0 0 0 255: с FF и Safari

Но

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

пусть прямоугольник заполнен с помощью 0 0 0 255
независимо от браузера!

Ответ 18

Если вы используете clearRect только, если у вас есть в форме, чтобы отправить свой рисунок, вы получите отправку, а затем очистку, или, возможно, ее можно сначала очистить, а затем загрузить рисунок пустоты, так что вам понадобится для добавления функции preventDefault в начале функции:

   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);">

Надеюсь, что это поможет кому-то.

Ответ 19

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

Пример: context.clearRect(0, 0, canvas.width, canvas.height);

Ответ 20

Я всегда использую

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

Ответ 21

Все это отличные примеры того, как вы очищаете стандартный холст, но если вы используете paperjs, то это будет работать:

Определите глобальную переменную в JavaScript:

var clearCanvas = false;

Из вашего PaperScript определите:

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

Теперь, когда вы устанавливаете clearCanvas в true, он очищает все элементы с экрана.