Search code examples
javascripthtmlcsscanvashtml5-canvas

Draw polygons of fixed sides with mouse on canvas


I am trying to draw polygons(lets say 4 sided) on a canvas using mouse click and move events.

  1. Click on canvas the moveTo(this point).
  2. Now move the cursor a lineTo(the current point) but not intermediate point. Line should keep moving with mousemove and should be draw to the canvas only once clicked.
  3. After fourth click(or any x) the polygon should closepath();

    var pressed = false;

    function myfunc1(e){
        context.beginPath();
        context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
        context.fill();
        context.beginPath();
        context.moveTo(e.clientX,e.clientY);
        pressed = true; 
    }
    
    function myfunc2(e){    
        if(pressed ===true){    
        context.lineTo(e.clientX,e.clientY);
        context.stroke();    
        }
    }    
    canvas.addEventListener('click',myfunc1);
    canvas.addEventListener('mousemove',myfunc2);
    

I wrote this, but i don't want the intermediate lines


Solution

  • I created an array(cords[]) which holds the coordinates of the polygon i am drawing and push them to another array (polygons[]) if the current polygon is completed. Then i can clear the canvas when required and redraw the polygons from polygon[]

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var img = document.getElementById("myimg");
    ctx.drawImage(img, 0, 0);
    var canvasOffset = $("#canvas").offset();
    var offsetX = canvasOffset.left;
    var offsetY = canvasOffset.top;
    var polygons = [];
    var cords = [];
    var start = false;
    var control = false;
    var clicks = 0;
    
    ctx.strokeStyle = "orange";
    ctx.lineWidth = 1;
    
    $("#canvas").mousedown(function(e) {
      handleMouseDown(e);
    });
    $("#canvas").mousemove(function(e) {
      handleMouseMove(e);
    });
    
    
    function handleMouseDown(e) {
      start = false;
      clicks = clicks + 1;
    
      var mouseX = parseInt(e.clientX - offsetX);
      var mouseY = parseInt(e.clientY - offsetY);
    
      cords.push([mouseX, mouseY]);
      console.log(cords);
      clearanddraw();
    
      if (clicks % 4 === 0) {
        return;
      }
      
      start = true;
    }
    
    function handleMouseMove(e) {
      if (!start) {
        return;
      }
    
      canvasclear();
    
      var mouseX = parseInt(e.clientX - offsetX);
      var mouseY = parseInt(e.clientY - offsetY);
    
      ctx.beginPath();
      ctx.moveTo(cords[clicks - 1][0], cords[clicks - 1][1]);
      ctx.lineTo(mouseX, mouseY);
      ctx.stroke();
    }
    
    function canvasclear() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(myimg, 0, 0);
      drawOtherPol();
      ctx.beginPath();
      ctx.moveTo(cords[0][0], cords[0][1]);
    
      for (var i = 0; i < clicks - 1; i++) {
        ctx.lineTo(cords[i + 1][0], cords[i + 1][1]);
        //alert("redrwan");
      }
      ctx.stroke();
      return;
    
    }
    
    function clearanddraw() {
      if (clicks > 1) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(myimg, 0, 0);
        drawOtherPol();
        ctx.beginPath();
        ctx.moveTo(cords[0][0], cords[0][1]);
        
        for (var i = 0; i < clicks - 1; i++) {
          ctx.lineTo(cords[i + 1][0], cords[i + 1][1]);
        }
        
        if (clicks < 4) {
          ctx.stroke();
        }
        if (clicks === 4) {
          ctx.closePath();
          ctx.stroke();
          savepolygon();
          cords = [];
          clicks = 0;
          return;
        }
      }
      start = true;
    }
    
    function savepolygon() {
      polygons.push(cords);
      console.log(polygons);
      return
    }
    
    function drawOtherPol() {
      if (polygons.length === 0) {
        return;
      } else {
        for (var i = 0; i < polygons.length; i++) {
          ctx.beginPath();
          ctx.moveTo(polygons[i][0][0], polygons[i][0][1]);
          ctx.lineTo(polygons[i][1][0], polygons[i][1][1]);
          ctx.lineTo(polygons[i][2][0], polygons[i][2][1]);
          ctx.lineTo(polygons[i][3][0], polygons[i][3][1]);
          ctx.closePath();
          ctx.stroke();
        }
        return;
      }
    }