Как очистить холст для перерисовки
после экспериментов с составными операциями и рисования изображений на холсте я теперь пытаюсь удалить изображения и композицию. Как мне это сделать?
Мне нужно очистить холст для перерисовки других изображений; это может продолжаться некоторое время, поэтому я не думаю, что рисование нового прямоугольника каждый раз будет наиболее эффективным вариантом.
20 ответов
использование: 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
другие уже сделали отличную работу, отвечая на вопрос, а если простой 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 = 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, он очистит все элементы с экрана.