Как удалять в 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 шт):

Автор решения: Daniil Loban

Согласно задаче нужно просто сделать очистку через определенное время. Так как отрисовка зациклена то лучший вариант 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>

→ Ссылка
Автор решения: OPTIMUS PRIME

Необходимо откуда-то узнать, кого нужно удалить, и в какой последовательности. Можно создать очередь (массив), где будут храниться данные о точках. Как только количесво точек доберется до лимита, на каждой отрисовке начнет удаляться одна точка:

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 область. Что будет эффективнее - не знаю, можете попробовать, сравнить)

→ Ссылка