0

I'm trying to load sprites from a tile set, and load them into a HTML5 canvas.

The problem is that the the coordinates aren't equal to the of the size of the images (It's getting stretched)

All my images are 64x64 pixels. (Preview on 1080p resolution: img) As you can see, the canvas is stretching those 64x64 images.

All of the code: HTML:

<html>
<head>
    <link rel="stylesheet" href="css/reset.css" />
    <link rel="stylesheet" href="css/board.css" />

    <script src="js/ext/jquery.js"></script>
    <script src="js/game.js"></script>
</head>
<body>
    <canvas id="GameBoard"></canvas>
</body>
</html>

CSS:

#GameBoard {
    width: 100vw;
    height: 100vh;
    border: 1px solid white;
}

JavaScript:

$(document).ready(function()
{
    createWorld();
}); 
function createWorld()
{
    var TileSets = loadTiles();
    drawWorld(TileSets);
}
var chunks = 
[
    [[0],[0],[0],[0],[0]],
    [[0],[1],[0],[1],[0]],
    [[0],[1],[0],[1],[0]],
    [[0],[1],[0],[1],[0]],
    [[0],[0],[0],[0],[0]]
];
var tiles = 
[
    { tileid: 0, tileset: 1, tilerow: 0, tilecolumn: 0},
    { tileid: 1, tileset: 1, tilerow: 0, tilecolumn: 1}
]
var tilesets =
[
    { tilesetid: 0, tilesrc: "static/tiles/tileset0.png", description:"OLD" },
    { tilesetid: 1, tilesrc: "static/tiles/tileset1.png", description:"New TEST" }
]

function loadTiles()
{
    var tiless = [];
    for(var i = 0; i < tilesets.length; i++)
    {
        var img = new Image();
        img.src = tilesets[i].tilesrc;
        tiless.push(img);
    }
    return tiless;
}

function drawWorld(TileSets)
{
    var WorldData = chunks;
    var canvas = document.getElementById("GameBoard");

    var counter = 0;

    for(var i = 0; i < WorldData.length; i++)
    {
        for(var j = 0; j < WorldData[i].length; j++)
        {
            counter++;

            var ctx = canvas.getContext("2d");
            var tileid = WorldData[i][j];
            var tilerow = tiles[tileid].tilerow;
            var tilecolumn = tiles[tileid].tilecolumn;

            console.log("DRAWN: " + counter + " FROM SET: " + tilerow + "x" + tilecolumn + " AT: " + i + "x" + j);

            ctx.drawImage(TileSets[1], 64 * tilecolumn , 64 * tilerow, 64, 64, 64 * j, 64 * i, 64, 64);
        }
    }
}

So is there any way, JavaScript, CSS, or something else to make the size of the grid of the canvas 64 by 64 so that the images are placed on their own scale next to eachother.

Peter O.
  • 32,158
  • 14
  • 82
  • 96

3 Answers3

2
<canvas id="GameBoard"></canvas>

You have to specify width and height attributes by values in pixels. These values are the virtual size of canvas. This size is used when you draw something.

CSS

Sizes in css are scaling canvas to the specified size, but without changing its virtual size. You are seeing this scaling.

You have to keep proportions in css by specifying only one dimension. If it's not a solution, provide more information about virtual size you need and I'll try to help by more concrete css.

Qwertiy
  • 19,681
  • 15
  • 61
  • 128
1

The canvas element properties/attributes are very different from the canvas element styles. The former represent the actual number of pixels on the canvas (the actual pixel you can manipulate, etc.) while the latter is the DOM representation of the canvas. It can be useful for stretching and zooming, but is usually used my a mistake, as in your case.

Two solutions:

  • either set the canvas element height and width to match the element's styles (CSS)
  • make the style (CSS) width and height the same as the actual canvas width and height (64x64 in your case)

See the difference here:

var img = document.getElementById('img');
var c1 = document.getElementById('c1');
var c2 = document.getElementById('c2');
var c3 = document.getElementById('c3');

c1.width = 150;
c1.height = 150;

c2.width = 150;
c2.height = 150;

c3.width = 200;
c3.height = 150;

img.onload = function() {
  c1.getContext('2d').drawImage(img, 0, 0);
  c2.getContext('2d').drawImage(img, 0, 0);
  c3.getContext('2d').drawImage(img, 0, 0);
}
canvas {border: 1px solid #aaa; width: 150px; height: 150px}
#c2 {width: 200px}
img {visibility: hidden; position: absolute}
<img src="http://mario.nintendo.com/img/mario_logo.png" id="img" />
<canvas id="c1"></canvas>
<canvas id="c2"></canvas>
<canvas id="c3"></canvas>
<p>The first one is correct - CSS resolution matching the element resolution</p>
<p>The second one tries to resize by changing the element style (CSS) only</p>
<p>The third one tried to resize by changing the element width only</p>
Shomz
  • 37,421
  • 4
  • 57
  • 85
-1

The problem is you are setting the canvas size in vw and vh , and that too in an external css files. For canvas to work properly try something like

<canvas id='Ganeboard' width='800px' height='400px'></canvas>

or use inline style, but i guess the canvas size has to be set fixed, you have to handle the resizing yourself with code

dippas
  • 58,591
  • 15
  • 114
  • 126
Sourab Reddy
  • 353
  • 2
  • 14
  • 1. No `px` in attibutes, just a number. 2. Attributes are copied to styles (with low priority) but styles do not affect the virtual size. – Qwertiy Jul 25 '15 at 23:47