Search code examples
javascripthtmlcanvasjohnny-five

Drawing a canvas line based on variables


I'm working with Arduino and I'm using an Accelerometer. I want to make a 2D line based on the x and y variables from the accelerometer.

I'm trying to it with this code:

board.on("ready", () => {
  const accelerometer = new Accelerometer({
    controller: "MPU6050"
  });
  accelerometer.on("change", function () {
    const {
      acceleration,
      inclination,
      orientation,
      pitch,
      roll,
      x,
      y,
      z
    } = accelerometer;
      const $yPos = y * 100 * 10;
      const $canvas = document.querySelector(`.simulation__line`);
        if ($canvas.childElementCount > 0) {
          $canvas.innerHTML = ``;
        }
      const drawing = $canvas.getContext("2d");
      drawing.beginPath();
      drawing.moveTo(1000, 1000 - $yPos);
      drawing.lineTo(0,  1000);
      drawing.lineTo(-1000, 1000 + $yPos);
      drawing.stroke();
      drawing.clearRect(1000, $yTest, drawing.width, drawing.height);  
  });
});

So every time the accelerometer changes variables, it draws a new line. This results in a lot of lines, but I want only one which is constantly changing. I tried to do it with the if statement if ($canvas.childElementCount > 0), but this won't help.


Solution

  • Here is a very simple example of drawing something on a canvas with a variable.
    I believe your issue is in the way you are using the clearRect to clear the canvas

    <input type="range" min="1" max="99" value="10" id="slider" oninput="draw()">
    <br/>
    <canvas id="canvas"></canvas>
    
    <script>
      function draw() {
        y = document.getElementById("slider").value
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillRect(0, y, 250, 3);
      }
    
      // init canvas
      var canvas = document.getElementById('canvas');
      canvas.height = (canvas.width = 250)/2;
      var ctx = canvas.getContext('2d');
      draw();
    </script>

    Run that code snippet to see it in action.
    The slider controls the Y position of a "line" that I'm drawing in the canvas, there should be just one line visible on the screen at any time.

    The key is to wipe the screen:
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    before we draw anything


    Looking at your code you are doing a few things inside the "accelerometer change" function that you should consider doing outside here is what I mean:

      const $canvas = document.querySelector(`.simulation__line`);
      const drawing = $canvas.getContext("2d"); 
    

    Those should not be changing as the accelerometer changes so I would keep them out


    The other sticky point is your call to:

      drawing.clearRect(1000, $yTest, drawing.width, drawing.height); 
    
    • that should be the first before you start drawing anything
    • not sure why to start at 1000, $yTest you should clear the entire canvas start at 0,0
    • and the drawing.width, drawing.height are not the same as canvas.width, canvas.height if I change that on my example it certainly will not wipe the canvas