Stacking canvases

So I am trying to make the program I made in a different language in JS. I want to be able to place a point, have a line constantly buffer to where my mouse is till I place the second point which is when all the points are cleared and a line is drawn between them.

My first problem is I can’t remove lines in JS without clearing the entire canvas which means I need 2 canvases stacked on top of each other. Stacking them should have been a simple copy and paste but it didn’t work…

My second problem is the line buffer isn’t running on the second canvas. I am sure the point_counter, x1 and y1 are global variables. The MouseUp function might not be running due to a logic error I made.

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8" />
    <title>Grid</title>
  </head>

  <body>
    <div style="position: relative;">
      <canvas id="canvas" width="250" height="250" style="border: 2px solid black" "position: absolute; left: 0; top: 0; z-index: 1;" onclick="onMouseClick(event)"></canvas>
      <canvas id="canvas2" width="250" height="250" style="border: 2px solid black" "position: absolute; left: 0; top: 0; z-index: 1;" onmouseup="onMouseUp(event)"></canvas>
    </div>


    <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script>
      //Global Variables
      //canvas is for grid, canvas2 is for line buffer
      var cnv = document.getElementById('canvas');
      var ctx = cnv.getContext('2d');
      var cnv2 = document.getElementById('canvas2');
      var ctx2 = cnv2.getContext('2d');
      var size = 25;

      var x1 = {};
      var x2 = {};
      var y1 = {};
      var y2 = {};
      var dot = {};
      var point_counter = 0;

      var delayInMilliseconds = 250; //1000 = 1 second

      //draws grid on bottom canvas
      function drawGrid(cnv, size) {
        var box = {};
        var width = cnv.width;
        var height = cnv.height;
        var cols = Math.floor(width / size);
        var rows = Math.floor(height / size);

        for (var i = 0; i < rows; i++) {
          for (var j = 0; j < cols; j++) {
            if (!(i in box)) {
              box[i] = {};
            }

            box[i][j] = {
              x: i * size,
              y: j * size,
              width: size,
              height: size
            };

            ctx.rect.apply(ctx, Object.values(box[i][j]));
            ctx.stroke();
          }
        }

        return box;
      }
      drawGrid(cnv, size);

      //point is place on bottom canvas
      function onMouseClick(event) {
        if (point_counter == 0) {
          point_counter = 1;
          x1 = event.offsetX;
          y1 = event.offsetY;
          ctx.beginPath();
          dot = ctx.arc(x1, y1, size / 4, 0, Math.PI * 2, true);
          ctx.closePath();
          ctx.fill();
        } else { //point_counter == 1;, first point is removed, line is drawn between
          //first and second point
          point_counter = 0;
          x2 = event.offsetX;
          y2 = event.offsetY;
          ctx.remove.dot();
          ctx.beginPath();
          ctx.moveTo(x1, y1);
          ctx.lineTo(x2, y2);
          ctx.stroke();

        }
      }

      //line buffer, line will be drawn from point to mouse deleted then repeat till second point is placed
      function onMouseUp(event) {
        while (point_counter == 1) {
          ctx2.beginPath();
          ctx2.moveTo(x1, y1);
          ctx2.lineTo(event.offsetX, event.offsetY);
          ctx2.stroke();
          setTimeout(function() {}, delayInMilliseconds);
          ctx2.clearRect(0, 0, canvas.width, canvas.height);
        }
      }

    </script>


  </body>

</html>

Instead of bothering with 2 canvases, you could just store it’s current state and paint that state back to the canvas.
Here’s a demo:[code]

[/code]
2 Likes

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.