0

I would like to dynamically create a canvas, specifying the dimensions of the canvas at runtime; then I'd like to render an image over that canvas so that it fills the entire dimension of the canvas.

This works as expected, when I declare a canvas's width & height on an <canvas> element, as shown in this snippet (hidden by default):

<!DOCTYPE html>
<html>

<body>

  <h3>
    Source Image
  </h3>
  <img id="image" src="http://placehold.it/180x180">

  <h3>Canvas:</h3>
  <canvas id="canvas" width="200" height="200" style="border:1px solid #d3d3d3;">
</canvas>

  <script>
    window.onload = function() {
      var c = document.getElementById("canvas");
      var ctx = c.getContext("2d");
      var img = document.getElementById("image");
      ctx.drawImage(img, 10, 10);
    }
  </script>

</body>

</html>

However, if I dynamically create the <canvas> element using Javascript, and use CSS to set the size after creating, the image will not fill the whole canvas:

<!DOCTYPE html>
<html>

<body>

  <h3>
    Source Image
  </h3>
  <img id="image" src="http://placehold.it/180x180">

  <h3>Canvas:</h3>
  <canvas id="canvas" style="border:1px solid #d3d3d3;">
</canvas>

  <script>
    window.onload = function() {
      var c = document.getElementById("canvas");
      c.style.width = "200px";
      c.style.height = "200px";
      var ctx = c.getContext("2d");
      var img = document.getElementById("image");
      ctx.drawImage(img, 10, 10);
    }
  </script>

</body>

</html>

I feel like I'm missing something pretty obvious here -- any help would be appreciated on how to get the dynamically rendered Canvas to look like the first snippet.

Edward Q. Bridges
  • 16,712
  • 8
  • 35
  • 42

1 Answers1

1

By using c.style.width, you're defining a scale for displaying it on your screen (it's just CSS).

To actually set the intrinsic size of the canvas, you do this:

window.onload = function() {
  var c = document.getElementById("canvas");
  c.width = 200;
  c.height = 200;
  var ctx = c.getContext("2d");
  var img = document.getElementById("image");
  ctx.drawImage(img, 10, 10);
}
<h3>Source Image</h3>
<img id="image" src="http://placehold.it/180x180">

<h3>Canvas:</h3>
<canvas id="canvas" style="border:1px solid #d3d3d3;"></canvas>

Note: This does not prevent you from having a different intrinsic size and display size. In fact, it's often useful if your page is displayed on a Retina screen with a high pixel density. In that case, you can have a 200x200 canvas, and set its CSS dimensions to be 100x100. That way every pixel in the canvas will be exactly 1 pixel of the screen it's displayed on.

More info on window.devicePixelRatio if you're interested.

blex
  • 24,941
  • 5
  • 39
  • 72