Search code examples
javascripthtmlcanvasrect

How can I draw multiple semi-transparent rectangles on canvas?


I have an image on a canvas and I want to draw semi-transparent rectangles on it. I draw them progressively by dragging and dropping with one finger.

Right now my code looks like this:

...

function handleTouch(event) {
    if (event.targetTouches.length === 1) {
      touch = event.targetTouches[0];

      if (event.type == 'touchmove') {
        if (drag) {
          rect.w = touch.pageX - rect.startX;
          rect.h = touch.pageY - rect.startY ;
          draw();
        }
      } else {
        rect.startX = touch.pageX;
        rect.startY = touch.pageY;
        drag = true;
      }
    }
}

function handleEnd(event) {
    drag = false;
}

function draw() {
    drawImageOnCanvas();
    ctx.strokeStyle = "green";
    ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
    ctx.fillStyle = 'rgba(0, 100, 255, 0.1)';
    ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
}

function drawImageOnCanvas() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(imgObj, 0, 0);
}

Right now it works well for one rectangle at a time and it looks like what I want, but I want more. How should I go about it?


Solution

  • Is it not possible to just keep an array of rects and then iterate over them since you need to redraw it every time?

    ...
    var rects = [];
    
    function handleTouch(event) {
        if (event.targetTouches.length === 1) {
          touch = event.targetTouches[0];
    
          if (event.type == 'touchmove') {
            if (drag) {
              rects[rects.length-1].w = touch.pageX - rect.startX;
              rects[rects.length-1].h = touch.pageY - rect.startY ;
              draw();
            }
          } else {
            rects.push({
              startX: 0,
              startY: 0,
              w: 0,
              h: 0
            });
            rects[rects.length-1].startX = touch.pageX;
            rects[rects.length-1].startY = touch.pageY;
            drag = true;
          }
        }
    }
    
    function handleEnd(event) {
        drag = false;
    }
    
    function draw() {
        drawImageOnCanvas();
        for (var i in rects) {
          var rect = rects[i];
          ctx.strokeStyle = "green";
          ctx.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
          ctx.fillStyle = 'rgba(0, 100, 255, 0.1)';
          ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
        }
    }
    
    function drawImageOnCanvas() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(imgObj, 0, 0);
    }