【问题标题】:html 5 canvas, I can only draw a single rectangle, how do i draw multiple rectangles and have them remain on the canvashtml 5画布,我只能画一个矩形,我如何画多个矩形并让它们留在画布上
【发布时间】:2023-03-28 05:13:01
【问题描述】:

问题

我可以绘制一个矩形,但是当我单击绘制另一个矩形时,第一个矩形消失了。我知道为什么会发生这种情况,但我想做的是能够绘制多个矩形,并且每个矩形在我绘制时都留在画布上。我必须使用多个上下文吗?

 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/

【问题讨论】:

    标签: html html5-canvas


    【解决方案1】:

    存储渲染对象

    您需要在将每个对象绘制为对象时存储它们,然后每次清除画布时重新绘制所有存储的对象。

    当对象的数量在 100 多个时,这将很有效,但如果计数变得非常高,则需要使用另一种方法。

    维护像素存储

    第二种方法是创建第二个画布。每次清除主画布时,都会在其顶部绘制第二个画布,如果鼠标按下,则在其上绘制新框。

    当鼠标变为向上时,清除第二个画布并将第一个画布绘制到上面。这会在您继续添加框时复制当前像素用作背景。

    我在您的代码中添加了一个基本背景,在 cmets //========== 之间

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

    【讨论】: