Как удалять в canvas объекты через пару секунд после их появления?
есть такой простенький код, хочу сделать так, что бы он после определенного момента времени удалял лишние элементы в canvas, но не знаю как. Пожалуйста, помогите мне.
let x = 0;
let timer;
drawSin();
function drawSin(){
let red = Math.floor(Math.random()* 255);
let green = Math.floor(Math.random() * 255);
let blue = Math.floor(Math.random() * 255);
ctx.fillStyle = "rgb("+red+","+green+"," +blue+" )";
y = Math.sin(x);
x = Math.floor(Math.random() * canvas.width);
y = Math.floor(Math.random() * canvas.height);
ctx.fillRect(x,y,2,2);
timer = setTimeout(drawSin,20);
}
Ответы (2 шт):
Согласно задаче нужно просто сделать очистку через определенное время.
Так как отрисовка зациклена то лучший вариант setInterval его достаточно установить 1 раз
timerClear = setInterval(()=>ctx.clearRect(0, 0, 255, 255), 2000)
очистит прямоугольник 255x255 c координатами (0, 0) через 2 секунды
var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
let x = 0;
let timer, timerClear;
drawSin();
function drawSin(){
let red = Math.floor(Math.random()* 255);
let green = Math.floor(Math.random() * 255);
let blue = Math.floor(Math.random() * 255);
ctx.fillStyle = "rgb("+red+","+green+"," +blue+" )";
y = Math.sin(x);
x = Math.floor(Math.random() * canvas.width);
y = Math.floor(Math.random() * canvas.height);
ctx.fillRect(x,y,2,2);
timer = setTimeout(drawSin,20);
}
timerClear = setInterval(()=>ctx.clearRect(0, 0, 255, 255), 2000)
<canvas id="tutorial" width="150" height="150"></canvas>
Необходимо откуда-то узнать, кого нужно удалить, и в какой последовательности. Можно создать очередь (массив), где будут храниться данные о точках. Как только количесво точек доберется до лимита, на каждой отрисовке начнет удаляться одна точка:
let cnv = document.querySelector("#c");
let ctx = cnv.getContext('2d');
const WID = cnv.width;
const HEI = cnv.height;
const LIMIT = 200; // Одновременно не больше 200 точек.
let points = []; // Будет хранить данные про точки: x, y, цвет.
let size = 2; // Размер квадратиков
(function draw() {
ctx.clearRect(0, 0, WID, HEI);
// В массиве points хранятся объекты вида:
// { x: число, y: число, color: "rgb( , , )" }
points.forEach(function (point) {
// циклом рисует все точки
ctx.fillStyle = point.color;
ctx.fillRect(point.x, point.y, size, size);
});
points.push( new Point() ); // Создает новый объект точки и добавляет его в массив.
if (points.length > LIMIT) points.shift(); // Больше 200 ? Удалить первый.
requestAnimationFrame(draw);
// requestAnimationFrame заново вызывает функцию примерно через 16 миллисекунд,
// и зацикливается (~60 вызовов в секунду)
// Все точки на каждом вызове рисуются заново.
})();
function rand_color() {
let r = Math.random() * 256 | 0; // | 0 ← Отбрасывает дробную часть
let g = Math.random() * 256 | 0;
let b = Math.random() * 256 | 0;
return `rgb(${ r },${ g },${ b })`;
// равносильно → "rgb(" + r + "," + g + "," + b + ")"
}
function Point() { // Справка: «Функции-конструкторы»
this.x = Math.random() * (WID - size) | 0;
this.y = Math.random() * (HEI - size) | 0;
this.color = rand_color();
}
// Не удержался!)
let inp = document.querySelector("#inp");
inp.addEventListener("input", () => size = Number(inp.value));
let autumn = document.querySelector("#autumn");
autumn.addEventListener("click", function() {
rand_color = function() {
let r = 100 + Math.random() * 156 | 0;
let g = r - Math.random() * 100 | 0;
let b = 0;
return `rgb(${ r },${ g },${ b })`
};
inp.value = size = 40;
});
<input id="inp" type="range" value="2" min="2" max="40">
<button id="autumn">Осень</button>
<br><br>
<canvas id="c"></canvas>
Можно немного усложнить функцию point(), чтобы гарантированно выдавала такие точки, которые не будут перекрывать друг друга. Тогда вместо полной отрисовки, на каждой итерации можно нарисовать ровно одну точку и стереть только маленькую 2x2 область. Что будет эффективнее - не знаю, можете попробовать, сравнить)