Сохранение объектов рендеринга
Вам нужно будет сохранять каждый объект при рисовании его как объекта, а затем каждый раз при очистке холста вы перерисовываете все сохраненные объекты.
Это будет работать хорошо когда число объектов находится в сотнях, но если количество должно быть очень большим, вам нужно будет использовать другой подход.
Поддерживать хранилище пикселей
Второй подход заключается в создании второй холст. Каждый раз, когда вы очищаете основной холст, нарисуйте второй холст поверх него, рисуя над ним новое поле, когда мышь нажата.
Когда мышь изменится на верхнюю, очистите второй холст и нарисуйте первый. на него. Это делает копию текущих пикселей, которые используются в качестве фона, когда вы продолжаете добавлять блоки.
Я добавил базовый c фон к вашему коду, между комментариями //==========
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
//=================================================
// Background canvas
const background = document.createElement("canvas");
background.width = canvas.width;
background.height = canvas.height;
const bgCtx = background.getContext("2d");
//=================================================
$(canvas).on('mousedown', function(e) {
last_mousex = parseInt(e.clientX-canvasx);
last_mousey = parseInt(e.clientY-canvasy);
mousedown = true;
});
$(canvas).on('mouseup', function(e) {
mousedown = false;
//==============================
// capture new background
bgCtx.clearRect(0,0,canvas.width, canvas.height);
bgCtx.drawImage(canvas, 0, 0);
//==============================
});
$(canvas).on('mousemove', function(e) {
mousex = parseInt(e.clientX-canvasx);
mousey = parseInt(e.clientY-canvasy);
if(mousedown) {
ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas
//==============================
// draw background
ctx.drawImage(background, 0, 0);
//==============================
ctx.beginPath();
var width = mousex-last_mousex;
var height = mousey-last_mousey;
ctx.rect(last_mousex,last_mousey,width,height);
ctx.strokeStyle = 'black';
ctx.lineWidth = 10;
ctx.stroke();
}