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

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

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

20 ответов


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

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

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

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

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

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

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

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

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

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

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

context.beginPath();

иначе линии не снимут.


другие уже сделали отличную работу, отвечая на вопрос, а если простой 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
};

  • 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;
}

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

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

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

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

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

это 2018 год, и до сих пор нет собственного метода, чтобы полностью очистить холст для перерисовки. clearRect() тут не очистить холст полностью. Чертежи типа non-fill не очищаются (например. rect())

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

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

плюсы: сохраняет strokeStyle, fillStyle etc.; Нет отставания;

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

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

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

или

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

плюсы: работает с IE Минусы: сбрасывает strokeStyle, fillStyle на черный; ЛаГГи;

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

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


в WebKit вам нужно установить ширину на другое значение, то вы можете установить его обратно в исходное значение


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

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

недостатком является то, что холст больше не является прозрачным.


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

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

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

canvas.width = canvas.width

Idk, как это работает, но это так!


быстрый способ:

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

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

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 as globalCompositeOperation. Затем восстанавливает предыдущее состояние контекста.


простой, но не очень читаемый способ, чтобы написать это:

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

// after doing some rendering

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

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

заполните данный прямоугольник значениями RGBA:
0 0 0 0 : хром
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
независимо от браузера !


Если вы используете только 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);">

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


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

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


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

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

var clearCanvas = false;

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

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

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