ImageData causing problems

So my code is almost done. I just have a problem filling in the rectangles in the function detection as the line buffer code keeps reseting the grid using image data. I tried adding a second canvas to store the fill in rectangles and the second canvas was below the first one and the filled in rectangles weren’t in the right places.I am new to programming so this is bad functioning code.

<!DOCTYPE html>
<html>

  <head>
    <title>Grid</title>
  </head>

  <body>
    <canvas id="cnv" width="500" height="500" style="border: 2px solid black"></canvas>
    <script type="text/javascript"></script>
    <script>
      var cnv = document.getElementById('cnv');
      cnv.addEventListener('click', clickHandler);
      cnv.addEventListener('mousemove', moveHandler);
      var ctx = cnv.getContext('2d');
      var x1 = {};
      var y1 = {};
      var x2 = {};
      var y2 = {};
      var counter = 0;
      var move = 0; //for determining if line is in the same column
      var boxes = "";
      var size = 25; //size of boxes
      var dotSize = 5;
      var dotAdj = 7; //dot adjustment
      var line = false;

      function drawGrid(cnv, size) {
        var width = cnv.width,
          height = cnv.height,
          x,
          y;
        ctx.beginPath();
        for (x = 0; x < width; x += size) {
          ctx.moveTo(x, 1);
          ctx.lineTo(x, cnv.height);
        }
        for (y = 0; y < height; y += size) {
          ctx.moveTo(0, y);
          ctx.lineTo(cnv.width, y);
        }
        ctx.stroke();
      };
      drawGrid(cnv, size);

      function clickHandler(event) {
        if (counter == 0) {
          counter = 1;
          x1 = event.clientX - ctx.canvas.offsetLeft;
          y1 = event.clientY - ctx.canvas.offsetTop;
          //console.log(['point 1', x1, y1]);
        } else {
          counter = 0;
          x2 = event.clientX - ctx.canvas.offsetLeft;
          y2 = event.clientY - ctx.canvas.offsetTop;
          //console.log(['point 2', x2, y2]);
          line_algorithm();
        }
        if (!line) { //no line, starts line function
          line = new Line(event.layerX, event.layerY);
        } else { //line drawn from first point to second point
          line = line.close(event.layerX, event.layerY);
        }
      };

      function moveHandler(event) {
        if (line) { //line buffers to where mouse is
          line.drawBuffer(event.layerX, event.layerY)
        }
      };

      function Line(x, y) {

        this.currentState = ctx.getImageData(0, 0, cnv.width, cnv.height);
        this.x = x;
        this.y = y;
        drawDot.call(this, x, y);

        function resetState() {
          ctx.clearRect(0, 0, cnv.width, cnv.height);
          ctx.putImageData(this.currentState, 0, 0);
        };

        function drawLine(x, y) {
          ctx.beginPath();
          ctx.moveTo(this.x - dotAdj, this.y - dotAdj);
          ctx.lineTo(x - dotAdj, y - dotAdj);
          ctx.stroke();
        };

        function drawDot(x, y) {
          ctx.beginPath();
          ctx.arc(x - dotAdj, y - dotAdj, dotSize, 0, 2 * Math.PI);
          ctx.stroke();
        };
        this.close = function(x, y) {
          resetState.call(this);
          drawLine.call(this, x, y);
          return false;
        };
        this.drawBuffer = function(x, y) {
          resetState.call(this);
          drawDot.call(this, this.x, this.y);
          drawDot.call(this, x, y);
          ctx.setLineDash([5, 10]);
          drawLine.call(this, x, y);
          ctx.setLineDash([]);
        };
      };

      function line_algorithm() {
        var m = ((y1 - y2) / (x1 - x2)); //slope
        var b = (y1 - (m * x1)); //y intercept
        console.log(['point 1', x1, y1, '  point 2', x2, y2]);
        console.log(['m', m, '  b', b]);
        for (var i = 1; i <= cnv.width / size; i++) {
          if (x1 >= (i - 1) * size && x1 <= (i * size) && x2 >= (i - 1) * size && x2 <= (i * size)) { //check if line is in same column
            move = 1; //line is in the same column
          }
        } //end of while loop
        if (move === 1) {
          noshift(m, b);
        } else {
          shift(m, b);
        }


        function detection(row, column) { //hitcheck list string starts off as ""

          if (boxes.indexOf(row + ":" + column + ",") === -1) { //if last hitcheck ISN'T in list of coordinates then box is filled in
            boxes = boxes + row + ":" + column + ","; //adds hitcheck to list
            console.log(['box hit', row, column]);
            //row = 1, column = 1, [0,0], row = 2, column = 1, [25,0]
            //      ctx.beginPath();
            //       ctx.rect((row - 1) * size, (column - 1) * size, size, size);
            //   ctx.fillStyle = 'black';
            //     ctx.fill();
            // ctx.putImageData(this.currentState, 0, 0);
            //ctx.clearRect(0, 0, cnv.width, cnv.height);

          }
        }

        function noshift(m, b) { //line is in the same column
          console.log(['no shift hit']);
          move = 0;
          boxes = "";
          //need to make a statement for when the y is the same
          if (y1 != y2) {
            var y3 = Math.min(y1, y2);
            var x3 = (y3 - b) / m;
            var row = 0;
            var column = Math.floor(x3 / size) + 1; //right and left
            while (y3 <= Math.max(y1, y2)) { //loop starts from smaller y coordinate to bigger y coordinate, inc by 1
              row = Math.floor(y3 / size) + 1; //up and down
              detection(row, column);
              y3 += 1;
            }
          } else { //y is the same
            var y3 = 0;
            var x3 = (y3 - b) / m;
            var row = 0;
            var column = Math.floor(x3 / size) + 1; //right and left
            while (y3 <= y1) { //loop starts from smaller y coordinate to bigger y coordinate, inc by 1
              row = Math.floor(y3 / size) + 1; //up and down
              detection(row, column);
              y3 += 1;
            }


          }
        }

        function shift(m, b) { //line crosses more than one column
          console.log(['shift hit']);
          boxes = "";
          var x3 = Math.min(x1, x2);
          var y3 = 0;
          var row = 0;
          var column = 0;
          while (x3 <= Math.max(x1, x2)) { //loop starts from smaller x coordinate to bigger x coordinate, inc by 1
            y3 = m * x3 + b; //y = mx + b;
            row = Math.floor(y3 / size) + 1; //math.floor gets lowest possible integer, 5.3 to 5
            column = Math.floor(x3 / size) + 1; //row and column are x and y of  a box hit, use smaller coordinates
            detection(row, column);
            x3 += 1;
          }
        }
      }; //end of line_algortihm

    </script>
  </body>

</html>


The reset is happening because line_algorithm() is called before line.close(). If line.close() is called first it works correctly. I simplified some functions, because I got division by zero errors with straight lines.

[code]

[/code]
1 Like

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