Reputation: 71
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
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
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.
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