Faruk
Faruk

Reputation: 853

Canvas putimagedata is sometimes not drawing like expected

I am trying to draw a simple flat line from the left center of my canvas to right side. The starting and ending points will be taken from textbox input. To do this i am first drawing a line from start to end with same html color with canvas to erase previous lines and then drawing the new line. However i am getting inconsistent behaviour. Sometimes it is drawing the input coordinates sometimes it isnt. What i may be doing wrong?

Here is my html code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <link rel="stylesheet" href="./css/cizim.css" />
        <title>Line</title>
        
    </head>
    <body>
        <div align="center"><canvas width ="400" height="400" id="canvas">
          
        </canvas>
    <script src="canvas.js"></script>  
        </div>
        <div align="center">
            <table width="400" border="0">
            <tbody>
              <tr>
                <td><label for="fname">Başlangıç:</label></td>
                <td><input type="text" id="start" name="fname"></td>
              </tr>
              <tr>
                <td><label for="fname">Bitiş:</label></td>
                <td><input type="text" id="end" name="sname"></td>
              </tr>
              <tr>
                <td>&nbsp;</td>
                <td><button id="myBtn" onclick="updateCanvas()">Draw</button></td>
              </tr>
            </tbody>
          </table>
            

        </div>
        
        
    </body>
</html>

And here is my javascript code:

function updateCanvas() {
    var canvas = document.getElementById("canvas");
    var start = document.getElementById("start").value;
    var end = document.getElementById("end").value;
    var canvasWidth = canvas.width;
    var canvasHeight = canvas.height;
    var ctx = canvas.getContext("2d");  
    var canvasData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
    
    function drawPixel (x, y, r, g, b, a) {
        var index = (x + y * canvasWidth) * 4;
        //pixelDensity(1);
        canvasData.data[index + 0] = r;
        canvasData.data[index + 1] = g;
        canvasData.data[index + 2] = b;
        canvasData.data[index + 3] = a;
    }
//Drawing 0 to 400 pixels to erase previous line here
    for (var i=0;i<=400;i++){
      drawPixel(i, 200, 247, 176, 84, 255);
    }
//Drawing new line
    for (var i=start;i<=end;i++){
      drawPixel(i, 200, 255, 0, 0, 255);
    }
    ctx.putImageData(canvasData, 0, 0);
}

function updateCanvas() {
    var canvas = document.getElementById("canvas");
    var start = document.getElementById("start").value;
    var end = document.getElementById("end").value;
    var canvasWidth = canvas.width;
    var canvasHeight = canvas.height;
    var ctx = canvas.getContext("2d");  
    var canvasData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
    
    function drawPixel (x, y, r, g, b, a) {
        var index = (x + y * canvasWidth) * 4;
        //pixelDensity(1);
        canvasData.data[index + 0] = r;
        canvasData.data[index + 1] = g;
        canvasData.data[index + 2] = b;
        canvasData.data[index + 3] = a;
    }
    for (var i=0;i<=400;i++){
      drawPixel(i, 200, 247, 176, 84, 255);
    }
    for (var i=start;i<=end;i++){
      drawPixel(i, 200, 255, 0, 0, 255);
    }   
    ctx.putImageData(canvasData, 0, 0);
}
body {
    background-color: #F7B054;
  }
  
  h1 {
    color: white;
    text-align: center;
  }
  
  p {
    font-family: verdana;
    font-size: 20px;
  }

  #canvas{
    border: 2px solid black;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <link rel="stylesheet" href="./css/cizim.css" />
        <title>Line</title>
        
    </head>
    <body>
        <div align="center"><canvas width ="400" height="400" id="canvas">
          
        </canvas>
    <script src="canvas.js"></script>  
        </div>
        <div align="center">
            <table width="400" border="0">
            <tbody>
              <tr>
                <td><label for="fname">Başlangıç:</label></td>
                <td><input type="text" id="start" name="fname" value="50"></td>
              </tr>
              <tr>
                <td><label for="fname">Bitiş:</label></td>
                <td><input type="text" id="end" name="sname" value="300"></td>
              </tr>
              <tr>
                <td>&nbsp;</td>
                <td><button id="myBtn" onclick="updateCanvas()">Draw</button></td>
              </tr>
            </tbody>
          </table>
            
<script src="canvas.js"></script>
        </div>
        
        
    </body>
</html>

The problem is that with the input being 50 and 300 respectively, the line is not displayed. While with 100 and 300, for example, it works well.

Upvotes: 4

Views: 240

Answers (1)

Lajos Arpad
Lajos Arpad

Reputation: 76814

The problem is that you are loading input attributes that have a textual type, so "50" is > "300". The solution is to convert them to numbers when you get the values so the comparison will be numerical. See the snippet below:

function updateCanvas() {
    var canvas = document.getElementById("canvas");
    var start = parseInt(document.getElementById("start").value);
    var end = parseInt(document.getElementById("end").value);
    var canvasWidth = canvas.width;
    var canvasHeight = canvas.height;
    var ctx = canvas.getContext("2d");  
    var canvasData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
    
    function drawPixel (x, y, r, g, b, a) {
        var index = (x + y * canvasWidth) * 4;
        //pixelDensity(1);
        canvasData.data[index + 0] = r;
        canvasData.data[index + 1] = g;
        canvasData.data[index + 2] = b;
        canvasData.data[index + 3] = a;
    }
    for (var i=0;i<=400;i++){
      drawPixel(i, 200, 247, 176, 84, 255);
    }
    for (var i=start;i<=end;i++){
      drawPixel(i, 200, 255, 0, 0, 255);
    }   
    ctx.putImageData(canvasData, 0, 0);
}
body {
    background-color: #F7B054;
  }
  
  h1 {
    color: white;
    text-align: center;
  }
  
  p {
    font-family: verdana;
    font-size: 20px;
  }

  #canvas{
    border: 2px solid black;
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <link rel="stylesheet" href="./css/cizim.css" />
        <title>Line</title>
        
    </head>
    <body>
        <div align="center"><canvas width ="400" height="400" id="canvas">
          
        </canvas>
    <script src="canvas.js"></script>  
        </div>
        <div align="center">
            <table width="400" border="0">
            <tbody>
              <tr>
                <td><label for="fname">Başlangıç:</label></td>
                <td><input type="text" id="start" name="fname" value="50"></td>
              </tr>
              <tr>
                <td><label for="fname">Bitiş:</label></td>
                <td><input type="text" id="end" name="sname" value="300"></td>
              </tr>
              <tr>
                <td>&nbsp;</td>
                <td><button id="myBtn" onclick="updateCanvas()">Draw</button></td>
              </tr>
            </tbody>
          </table>
            
<script src="canvas.js"></script>
        </div>
        
        
    </body>
</html>

Upvotes: 1

Related Questions