121

How can i get the width and height of the canvas element in JavaScript?

Also, what is the "context" of the canvas I keep reading about?

doppelgreener
  • 4,809
  • 10
  • 46
  • 63
clamp
  • 33,000
  • 75
  • 203
  • 299

7 Answers7

171

It might be worth looking at a tutorial: MDN Canvas Tutorial

You can get the width and height of a canvas element simply by accessing those properties of the element. For example:

var canvas = document.getElementById('mycanvas');
var width = canvas.width;
var height = canvas.height;

If the width and height attributes are not present in the canvas element, the default 300x150 size will be returned. To dynamically get the correct width and height use the following code:

const canvasW = canvas.getBoundingClientRect().width;
const canvasH = canvas.getBoundingClientRect().height;

Or using the shorter object destructuring syntax:

const { width, height } = canvas.getBoundingClientRect();

The context is an object you get from the canvas to allow you to draw into it. You can think of the context as the API to the canvas, that provides you with the commands that enable you to draw on the canvas element.

andrewmu
  • 14,276
  • 4
  • 39
  • 37
  • Note that the Mozilla tutorial is basically a bunch of broken links now, unfortunately. Hope they'll fix it some day. – Sz. Jun 18 '13 at 12:05
  • 1
    This returns the context canvas size in Chrome 31. – shuji Dec 03 '13 at 04:09
  • 13
    this works only if `width` and `height` are specified directly as `` tag attributes – vladkras Mar 07 '17 at 14:40
  • 5
    That is not true. It always returns a value even without tag attributes, defaulting to 300 x 150. – Michael Theriot May 28 '18 at 03:09
  • Be aware that getBoundingClientRect() sometimes includes borders. This may or may not matter, but in my CSS I set the width and height to 100,100 and the getBoundingClientRect returns 102, 102. clientHeight and clientWidth (or scrollHeight and scrollWidth) return 100 correctly. – DoomGoober Mar 30 '20 at 00:15
  • does not work with: canvas = document.getElementById( "myControl" ).getContext("2d"); – Gabriel May 19 '20 at 12:17
  • 1
    @Z80 - Your `canvas` is a 2D context, not the canvas. `canvas` in the above is the HTML canvas element, not a 2D context. – T.J. Crowder Aug 17 '21 at 10:42
  • Can someone (@andrewmu) explain why the `width` and `height` would not be available and need to return defaults? I'm getting these values (300,150) and yet the canvas is rendering full screen. When I draw my image on canvas, the image seems fully stretched. Do I need to wait for canvas element to be fully resized/rendered? Thanks. – Jeach Aug 31 '22 at 16:37
  • @Jeach if you don't explicitly specify the width and height for the canvas element, you'll get the defaults. Those are logical pixel size values, meaning the image will have a resolution of width x height. It maybe be that your canvas has CSS properties that give it a different size, e.g. `width: 100%` or maybe it's in a flex container. Then the canvas will display as a different size, but the image pixels in it will still be set by the width and height values (or the defaults) and scaled to fit the layout size. – andrewmu Sep 02 '22 at 23:10
41

Well, all the answers before aren't entirely correct. 2 of major browsers don't support those 2 properties (IE is one of them) or use them differently.

Better solution (supported by most browsers, but I didn't check Safari):

var canvas = document.getElementById('mycanvas');
var width = canvas.scrollWidth;
var height = canvas.scrollHeight;

At least I get correct values with scrollWidth and -Height and MUST set canvas.width and height when it is resized.

Bitterblue
  • 13,162
  • 17
  • 86
  • 124
  • IE9 does seem to support canvas.width and height alright (versions prior to 9 did not support canvas at all), I've just given it a go. What troubles did you run into? And which is the other major browser? – thomanski Dec 30 '12 at 00:11
  • 1
    Right, I really don't ever update IE because I don't use it. The other major browser is Opera which didn't / don't update width and height while resizing. – Bitterblue Jan 03 '13 at 10:17
  • 2
    canvas.width or height dont return the total size of the canvas, prefer the canvas.scrollWidth or height to get the total real size of the canvas. – Jordan Aug 11 '14 at 09:40
  • 2
    This worked for me, but the other answers didn't. I was looking for a solution that could get the width and height if the canvas was set using bootstrap. – wanderer0810 Dec 19 '17 at 01:11
23

The answers mentioning canvas.width return the internal dimensions of the canvas, i.e. those specified when creating the element:

<canvas width="500" height="200">

If you size the canvas with CSS, its DOM dimensions are accessible via .scrollWidth and .scrollHeight:

var canvasElem = document.querySelector('canvas');
document.querySelector('#dom-dims').innerHTML = 'Canvas DOM element width x height: ' +
      canvasElem.scrollWidth +
      ' x ' +
      canvasElem.scrollHeight

var canvasContext = canvasElem.getContext('2d');
document.querySelector('#internal-dims').innerHTML = 'Canvas internal width x height: ' +
      canvasContext.canvas.width +
      ' x ' +
      canvasContext.canvas.height;

canvasContext.fillStyle = "#00A";
canvasContext.fillText("Distorted", 0, 10);
<p id="dom-dims"></p>
<p id="internal-dims"></p>
<canvas style="width: 100%; height: 123px; border: 1px dashed black">
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
  • that was the correct answer. 2 dimensions to consider. – Nadir Jan 17 '16 at 02:39
  • 2
    this should be the selected answer. direct `width` and `height` call will always return 300x150 if you do not specify any values and use relative sizing (while using bootstrap...etc). Thanks. – mcy Feb 05 '16 at 09:30
16

The context object allows you to manipulate the canvas; you can draw rectangles for example and a lot more.

If you want to get the width and height, you can just use the standard HTML attributes width and height:

var canvas = document.getElementById( 'yourCanvasID' );
var ctx = canvas.getContext( '2d' );

alert( canvas.width );
alert( canvas.height ); 
Harmen
  • 22,092
  • 4
  • 54
  • 76
  • 3
    This answer is pretty much identical to @andrewmu's and won't work if you size the canvas via CSS. See [my answer](http://stackoverflow.com/questions/4032179/how-do-i-get-the-width-and-height-of-a-html5-canvas/31195651#31195651) for a more robust solution. – Dan Dascalescu Jul 02 '15 at 22:26
10

now starting 2015 all (major?) browsers seem to alow c.width and c.height to get the canvas internal size, but:

the question as the answers are missleading, because the a canvas has in principle 2 different/independent sizes.

The "html" lets say CSS width/height and its own (attribute-) width/height

look at this short example of different sizing, where I put a 200/200 canvas into a 300/100 html-element

With most examples (all I saw) there is no css-size set, so theese get implizit the width and height of the (drawing-) canvas size. But that is not a must, and can produce funy results, if you take the wrong size - ie. css widht/height for inner positioning.

halfbit
  • 3,773
  • 2
  • 34
  • 47
1

None of those worked for me. Try this.

console.log($(canvasjQueryElement)[0].width)
Subtopic
  • 71
  • 1
  • 11
0

Here's a CodePen that uses canvas.height/width, CSS height/width, and context to correctly render any canvas at any size.

HTML:

<button onclick="render()">Render</button>
<canvas id="myCanvas" height="100" width="100" style="object-fit:contain;"></canvas>

CSS:

canvas {
  width: 400px;
  height: 200px;
  border: 1px solid red;
  display: block;
}

Javascript:

const myCanvas = document.getElementById("myCanvas");
const originalHeight = myCanvas.height;
const originalWidth = myCanvas.width;
render();
function render() {
  let dimensions = getObjectFitSize(
    true,
    myCanvas.clientWidth,
    myCanvas.clientHeight,
    myCanvas.width,
    myCanvas.height
  );
  myCanvas.width = dimensions.width;
  myCanvas.height = dimensions.height;

  let ctx = myCanvas.getContext("2d");
  let ratio = Math.min(
    myCanvas.clientWidth / originalWidth,
    myCanvas.clientHeight / originalHeight
  );
  ctx.scale(ratio, ratio); //adjust this!
  ctx.beginPath();
  ctx.arc(50, 50, 50, 0, 2 * Math.PI);
  ctx.stroke();
}

// adapted from: https://www.npmjs.com/package/intrinsic-scale
function getObjectFitSize(
  contains /* true = contain, false = cover */,
  containerWidth,
  containerHeight,
  width,
  height
) {
  var doRatio = width / height;
  var cRatio = containerWidth / containerHeight;
  var targetWidth = 0;
  var targetHeight = 0;
  var test = contains ? doRatio > cRatio : doRatio < cRatio;

  if (test) {
    targetWidth = containerWidth;
    targetHeight = targetWidth / doRatio;
  } else {
    targetHeight = containerHeight;
    targetWidth = targetHeight * doRatio;
  }

  return {
    width: targetWidth,
    height: targetHeight,
    x: (containerWidth - targetWidth) / 2,
    y: (containerHeight - targetHeight) / 2
  };
}

Basically, canvas.height/width sets the size of the bitmap you are rendering to. The CSS height/width then scales the bitmap to fit the layout space (often warping it as it scales it). The context can then modify it's scale to draw, using vector operations, at different sizes.

DoomGoober
  • 1,533
  • 14
  • 20