Sriram
Sriram

Reputation: 71

HTML canvas coordinates are different when created using JS versus embed in HTML

Playing with HTML5 canvas and JS, I found a strange behaviour when a canvas is added to the HTML body directly versus creating a canvas using JS.

<!DOCTYPE html>
<html>
<head></head>
<body>
<canvas id="test" width="200" height="200" style="border:1px solid #000000;">
</canvas>
<script>
    var c=document.getElementById("test");
    ctx=c.getContext("2d");
    ctx.fillStyle = "#9ea7b8";
    ctx.fill();
    ctx.moveTo(0,0);
    ctx.lineTo(200,200);
    ctx.stroke(); 

    // creating canvas using JS
    c = document.createElement("canvas");
    c.id="MyCanvas";
    c.style.width="200px";
    c.style.height="200px";
    c.style.border="1px solid #000000";
    ctx=c.getContext("2d");
    ctx.fillStyle = "#9ea7b8";
    ctx.fill();
    ctx.moveTo(0,0);
    ctx.lineTo(200,200);
    ctx.stroke();
    document.body.appendChild(c);
</script>
</body>
</html>

Please see the code & ouput here

I expected the line (stroke) to be a consistent diagonal across the canvas but alas!. Please help me know where am I going wrong!

Note: I forgot to mention, I tried this on Chrome only not sure if the behaviour is consistent for other browsers.

Upvotes: 6

Views: 1210

Answers (2)

Simon Sarris
Simon Sarris

Reputation: 63830

Canvas width and height attributes are not the same as its CSS width and height. Setting canvas.width/height attributes determines the total drawable pixel area, which can be (but does not need to be) scaled with CSS to be larger or smaller on the screen.


Normal scenario: Make canvas attribute bounds larger than CSS bounds

In fact, to make a high density display canvas it is necessary to set canvas.width and canvas.height twice as large as the css. In other words you might do:

// Two canvas pixels per screen pixel so it looks nice
// on a high density (in this case pixel ratio: 2) display
canvas.width = 800;
canvas.height = 800;
canvas.style.width = '400px';
canvas.style.height = '400px';

Normal scenario: Make canvas attribute bounds smaller than CSS bounds

On the flip side in order to make some apps like games fast canvas.width and canvas.height might be restricted to 640x480 (or something small) and then scaled with CSS to take up the whole screen. Since the total number of pixels handled on the canvas is small, the game will be faster than if you used a really large canvas and filled the screen. Obviously the game will look different, since CSS will be scaling the graphics (for better or worse).

Upvotes: 0

Joel Almeida
Joel Almeida

Reputation: 8037

So, basically if you change from style to attribute it works.

Why ?

It seems that the width and height attributes determine the width or height of the canvas's coordinate system, whereas the CSS properties just determine the size of the box in which it will be shown.

Source

Like this it will work fine:

        var c = document.getElementById("test");
        ctx = c.getContext("2d");
        ctx.fillStyle = "#9ea7b8";
        ctx.fill();
        ctx.moveTo(0, 0);
        ctx.lineTo(200, 200);
        ctx.stroke();

        // creating canvas using JS
        c = document.createElement("canvas");
        c.id = "MyCanvas";
        c.setAttribute("width", "200px")
         c.setAttribute("height", "200px")
         c.style.border = "1px solid #000000";
        ctx = c.getContext("2d");
        ctx.fillStyle = "#9ea7b8";
        ctx.fill();
        ctx.moveTo(0, 0);
        ctx.lineTo(200, 200);
        ctx.stroke();
        document.body.appendChild(c);
<canvas id="test" width="200" height="200" style="border:1px solid #000000;"></canvas>

Upvotes: 2

Related Questions