html 5 холст, я могу нарисовать только один прямоугольник, как мне нарисовать несколько прямоугольников и оставить их на холсте - PullRequest
0 голосов
/ 07 марта 2020

Проблема

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

 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;


$(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;
});


$(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
      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();
}

Вот ссылка на jsfiddle

https://jsfiddle.net/richardcwc/ukqhf54k/

1 Ответ

1 голос
/ 08 марта 2020

Сохранение объектов рендеринга

Вам нужно будет сохранять каждый объект при рисовании его как объекта, а затем каждый раз при очистке холста вы перерисовываете все сохраненные объекты.

Это будет работать хорошо когда число объектов находится в сотнях, но если количество должно быть очень большим, вам нужно будет использовать другой подход.

Поддерживать хранилище пикселей

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

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

Я добавил базовый 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...