Home > Net >  A Grid slowing the moving element on JS canvas
A Grid slowing the moving element on JS canvas

Time:12-15

I'm drawing a grid on a JavaScript canvas on this canvas I also have a moving element so the Grid can be on/off with a button all is well apart from the speed of the moving element when grid is on it becomes extremely slow. I'm not really sure where am I going wrong. Can someone please give me some help. Thank you

HTML

<div>
    <input type=button id="up" onClick=move_img(id); value='Up'>
    <input type=button id="down"  onClick=move_img(id); value='Down'>
    <input type=button id="left"  onClick=move_img(id); value='Left'>
    <input type=button id="right"  onClick=move_img(id); value='Right'>
    <input type=button id="stop"  onClick=move_img(id); value='Stop'>
    <input type=button id="grid"  onClick=gridOn(); value='Grid'>
    <br>
    <p></p>
</div>

JavaScript

    var isGrid = new Boolean(false);
    var canvas = document.getElementById("canvas");
    b = canvas.getContext("2d");

    var width = canvas.width = 600;
    var height = canvas.height = 400;
    
    document.body.appendChild(canvas);

    b.fillStyle = "#F0F8FF";
    b.fillRect(0, 0, canvas.width, canvas.height);

    var posX = 10;
    posY = 10;
    x = 0;
    y = 0;
    
    setInterval(function () {
   
        b.fillStyle = "#F0F8FF";
        b.fillRect(0, 0, width, height);
        posX  = x;
        posY  = y;

        if (posX > width - 20) {
            x = 0;
            posX = width - 20;
        }
        if (posX < 0) {
            x = 0;
            posX = 0;
        }
        if (posY > height - 20) {
            y = 0;
            posY = height - 20;
        }
        if (posY < 0) {
            y = 0;
            posY = 0;
        }

    b.fillStyle = "red";
    b.fillRect(posX, posY, 20, 20);
    
    /**  Grid ***/
    if(isGrid){
        drawGrid();
    }
    /**************/
    
    }, 5)
   
    function move_img(id) {
        switch (id) {
        case "down":
            moveDown();
            break;
        case "up":
            moveUp();
            break;
        case "left":
            moveLeft();
            break;
        case "right":
            moveRight();
            break;
        case "stop":
            moveStop();
            break;
        }
    } 
    
    function moveDown(){
        x = 0;
        y = 1;
    }
    function moveUp(){
        x = 0;
        y = -1;
    }
    function moveLeft(){
        x = -1;
        y = 0;
    }
    function moveRight(){
        x = 1;
        y = 0;
    }
    function moveStop(){
        x = 0;
        y = 0;
    }
    function gridOn() {
        if(isGrid){
            isGrid = false;
        }else{
            isGrid = true;
        }
    } 
    
    function drawGrid(){    
        b.strokeStyle = 'black';
        b.lineWidth = 0.5;
        
        for(i = 0; i<= 600; i=i 40){
            b.moveTo(i, 0);
            b.lineTo(i, 600);
            b.stroke();
        }
        for(j = 0; j<= 600; j=j 40){
            b.moveTo(0, j);
            b.lineTo(600, j);
            b.stroke();
        }
    }

CodePudding user response:

You can use 2 canvas with position absolute. One for red box and another for Grid. That will help you to move box without clearing grid.

Also, you can follow @reyno's advice that will help you to reduce some loops.

Also, you can make only one method move and use it for all sides by passing x and y based on button. This will reduce the line of code.

See the Snippet below:

var isGrid = new Boolean(false);
    var canvas = document.getElementById("canvas");
    b = canvas.getContext("2d");
    
    var gridCanvas = document.getElementById("grid-canvas");
    bGrid = gridCanvas.getContext("2d");

    var width = gridCanvas.width = 600;
    var height = gridCanvas.height = 400;
    
    canvas.width = width;
    canvas.height = height;
    
    //document.body.appendChild(canvas);

    bGrid.fillStyle = "#F0F8FF";
    bGrid.fillRect(0, 0, gridCanvas.width, gridCanvas.height);
    b.fillRect(0, 0, gridCanvas.width, gridCanvas.height);

    var posX = 10;
    posY = 10;
    x = 0;
    y = 0;
    let _interval = null;
    drawImg();
    
    if(isGrid){
        drawGrid();
    }
    
    function drawImg(){
      _interval = setInterval(function(){
         /*b.fillStyle = "#F0F8FF";
          b.fillRect(0, 0, width, height);*/
          b.clearRect(0,0, width, height);
          posX  = x;
          posY  = y;

          if (posX > width - 20) {
              x = 0;
              posX = width - 20;
          }
          if (posX < 0) {
              x = 0;
              posX = 0;
          }
          if (posY > height - 20) {
              y = 0;
              posY = height - 20;
          }
          if (posY < 0) {
              y = 0;
              posY = 0;
          }

          b.fillStyle = "red";
          b.fillRect(posX, posY, 20, 20);
      }, 1000/60)
    }
    
    function stopImg(){
        clearInterval(_interval);
    }
   
    function move_img(id) {
        switch (id) {
        case "down":
            move(0,1);
            break;
        case "up":
            move(0,-1);
            break;
        case "left":
            move(-1,0);
            break;
        case "right":
            move(1,0);
            break;
        case "stop":
            move(0,0);
            break;
        }
    } 
    
    function move(_x,_y){
        x = _x;
      y = _y;
      if(_x ==0 && _y==0){
        stopImg();
      }else{
        drawImg();
      }
    }
    
    /*function moveDown(){
        x = 0;
        y = 1;
    }
    function moveUp(){
        x = 0;
        y = -1;
    }
    function moveLeft(){
        x = -1;
        y = 0;
    }
    function moveRight(){
        x = 1;
        y = 0;
    }
    function moveStop(){
        x = 0;
        y = 0;
    }*/
    function gridOn() {
        if(isGrid){
            isGrid = false;
            bGrid.clearRect(0,0, width, height);
            bGrid.fillRect(0,0, width, height);
        }else{
            isGrid = true;
            bGrid.fillRect(0,0, width, height);
            drawGrid();
        }
    } 
    
    function drawGrid(){ 
        bGrid.strokeStyle = 'black';
        bGrid.lineWidth = 0.5;
        
        for(i = 0; i<= 600; i=i 40){
            bGrid.moveTo(i, 0);
            bGrid.lineTo(i, 600);
            bGrid.stroke();
            
            bGrid.moveTo(0, i);
            bGrid.lineTo(600, i);
            bGrid.stroke();
        }
       /* for(j = 0; j<= 600; j=j 40){
            b.moveTo(0, j);
            b.lineTo(600, j);
            b.stroke();
        }*/
    }
canvas{
  position: absolute;
}

#canvas{
  z-index: 1;
}
<div>
    <input type=button id="up" onClick=move_img(id); value='Up'>
    <input type=button id="down"  onClick=move_img(id); value='Down'>
    <input type=button id="left"  onClick=move_img(id); value='Left'>
    <input type=button id="right"  onClick=move_img(id); value='Right'>
    <input type=button id="stop"  onClick=move_img(id); value='Stop'>
    <input type=button id="grid"  onClick=gridOn(); value='Grid'>
    <br>
    <p></p>
</div>

<canvas id="canvas"></canvas>
<canvas id="grid-canvas"></canvas>

You can also test it here

  • Related