HTML5 Canvas Javascript – How to make a moveable canvas with tiles using 'translate3d'?

I’m having trouble with a movable canvas that adjusts as the ‘player’ moves around the map. As drawing 600 tiles, 60 times a second is very inefficient, I switched over to using translate3d and only draw once the player crossed a full tile — but it keeps glitching and not moving around smooth. How would I achieve this properly?

const ctx = canvas.getContext('2d');
canvas.height = 200;
canvas.width = 600;
const tileSize = canvas.height/6;
const MAIN = {position:{x: 120, y: 120}};
const canvasRefresh = {x: 0, y: 20};
document.body.onmousemove = e => MAIN.position = {x: e.clientX, y: e.clientY};
const tiles = {x: 20, y: 20}

function update(){
    moveMap();
    requestAnimationFrame(update);
}
function drawMap(){
    for(var i = 0; i < tiles.x; i++){
        for(var j = 0; j < tiles.y; j++){
            ctx.fillStyle = ['black', 'green','orange'][Math.floor((i+j+canvasRefresh.x1+canvasRefresh.y1)%3)];
            ctx.fillRect(tileSize * i, tileSize * j, tileSize, tileSize);
        }
    }
}
function moveMap(){
    const sector = {
        x: Math.round(-MAIN.position.x % tileSize),
        y: Math.round(-MAIN.position.y % tileSize)
    };
    const x2 = Math.floor(MAIN.position.x/tileSize);
    const y2 = Math.floor(MAIN.position.y/tileSize);
    if(canvasRefresh.x1 != x2 || canvasRefresh.y1 != y2){
        canvasRefresh.x1 = x2;
        canvasRefresh.y1 = y2;
        requestAnimationFrame(drawMap);
    }
    $('#canvas').css({
        transform: "translate3d(" + sector.x + "px, " + sector.y + "px, 0)"
    });
}
update();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id=canvas></canvas>

15 thoughts on “HTML5 Canvas Javascript – How to make a moveable canvas with tiles using 'translate3d'?”

  1. Since you enjoy the freedom of raw code here is most of the solution…

    no CCS tricks and no jQuery, just raw javascript,
    your next challenge is to bring the colors back

    const ctx = canvas.getContext('2d');
    canvas.height = 160;
    canvas.width = 550;
    
    const tileSize = 30;
    var position = { x: 120, y: 120 };
    var canvasRefresh = { x: 0, y: 20 };
    
    document.body.onmousemove = e => position = { x: e.clientX, y: e.clientY };
    const tiles = {
      x: canvas.width / tileSize + 2,
      y: canvas.height / tileSize + 2
    }
    
    function update() {
      moveMap();
      requestAnimationFrame(update);
    }
    
    function drawMap() {
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      for (var i = -1; i < tiles.x; i++) {
        for (var j = -1; j < tiles.y; j++) {
          ctx.strokeRect(
            tileSize * i + canvasRefresh.x1%tileSize, 
            tileSize * j + canvasRefresh.y1%tileSize, 
            tileSize, tileSize
          );
        }
      }
    }
    
    function moveMap() {
      if (canvasRefresh.x1 != position.x || canvasRefresh.y1 != position.y) {
        canvasRefresh.x1 = position.x;
        canvasRefresh.y1 = position.y;
        requestAnimationFrame(drawMap);
      }
    }
    update();
    canvas {
      border: 1px solid red
    }
    <canvas id=canvas></canvas>
    Reply
  2. Great blog! Do you have any recommendations for aspiring writers?
    I’m hoping to start my own blog soon but I’m a little lost on everything.
    Would you recommend starting with a free platform like WordPress or go for a paid option? There are so many choices out there that I’m completely confused ..
    Any suggestions? Thank you!

    Feel free to surf to my webpage :: sky777

    Reply

Leave a Comment