如何获取HTML5画布的宽度和高度?

122

如何使用JavaScript获取画布元素的宽度和高度?

此外,我一直看到关于画布“context”的内容,它是什么?


注:canvas元素是HTML5中的元素之一,可用于绘制图形、动画等。canvas的“context”代表画布上绘制的2D或3D环境。
7个回答

173

看一下教程可能会有帮助:MDN Canvas教程

你可以通过访问元素的这些属性来获取画布元素的宽度和高度。例如:

var canvas = document.getElementById('mycanvas');
var width = canvas.width;
var height = canvas.height;
如果canvas元素中没有width和height属性,则默认返回300x150大小。为动态获取正确的宽度和高度,请使用以下代码:
如果canvas标签中没有指定width和height属性,那么canvas元素默认将拥有300x150的尺寸。要动态获取正确的宽度和高度,请使用以下代码:
const canvasW = canvas.getBoundingClientRect().width;
const canvasH = canvas.getBoundingClientRect().height;

或者使用更简短的对象解构语法:

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

context 是一个从画布获取的对象,它允许你在其中进行绘图。你可以把 context 想象成 canvas 的 API,提供了使你能够在画布元素上进行绘图的命令。


请注意,不幸的是,Mozilla教程现在基本上是一堆损坏的链接。希望他们有一天能够修复它。 - Sz.
1
这将返回Chrome 31中上下文画布的大小。 - shuji
13
仅当 widthheight 直接指定为 <canvas /> 标签属性时,此方法才有效。 - vladkras
5
这不是真的。即使没有标签属性,它始终会返回一个值,默认为300 x 150。 - Michael Theriot
1
@Z80 - 你的canvas是一个2D上下文,而不是画布。上面的canvas是HTML画布元素,而不是2D上下文。 - T.J. Crowder
显示剩余4条评论

41

嗯,之前所有的回答并不完全正确。其中两个主要浏览器不支持这两个属性(IE 是其中之一),或者使用它们的方式不同。

更好的解决方案(大多数浏览器都支持,但我没有检查 Safari):

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

至少使用scrollWidth和-scrollHeight能获取正确的值,并且在重新调整大小时必须设置canvas的宽度和高度。


IE9似乎完全支持canvas.width和height(9之前的版本根本不支持canvas),我刚试过了。你遇到了什么问题?另一个主要的浏览器是哪个? - thomanski
1
没错,我从来不更新IE,因为我不用它。另一个主要的浏览器是Opera,在调整大小时没有更新宽度和高度。 - Bitterblue
2
canvas.width或height不会返回画布的总大小,建议使用canvas.scrollWidth或height来获取画布的实际总大小。 - Jordan
2
这对我有用,但其他答案不行。我正在寻找一个解决方案,如果使用Bootstrap设置画布,则可以获取其宽度和高度。 - wanderer0810

23
提到 canvas.width 的答案返回画布的内部尺寸,即在创建元素时指定的尺寸:
<canvas width="500" height="200">

如果您使用CSS对画布进行大小设置,则可以通过.scrollWidth.scrollHeight访问其DOM尺寸:

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">


那是正确的答案。 需要考虑两个维度。 - Nadir
2
如果您没有指定任何值并使用相对大小(同时使用Bootstrap等),则直接调用widthheight将始终返回300x150。谢谢。 - mcy

16

上下文对象允许您操作画布; 例如,您可以绘制矩形等等。

如果你想要获取宽度和高度,你可以直接使用标准的HTML属性widthheight

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

alert( canvas.width );
alert( canvas.height ); 

3
这个答案与 @andrewmu 的基本相同,如果您通过 CSS 调整画布的大小,则不起作用。请参阅 [我的答案](https://dev59.com/Ym865IYBdhLWcg3wA5yc#31195651)以获取更健壮的解决方案。 - Dan Dascalescu

10

从2015年开始,所有(主要?)浏览器似乎都允许使用c.widthc.height获取画布的内部大小,但是:

问题在于答案是误导性的,因为一个画布原则上有2种不同/独立的尺寸。

例如,“html”宽度/高度以及其自身(属性)宽度/高度

看一下这个不同尺寸的简短示例,我将一个200/200的画布放入一个300/100的HTML元素中。

大多数示例(我看到的所有示例)都没有设置CSS尺寸,因此这些尺寸会隐式地获得(绘图)画布大小的宽度和高度。但这不是必须的,并且如果您选择错误的尺寸(即用于内部定位的CSS宽度/高度),可能会产生有趣的结果。


1

那些都对我没用。试试这个。

console.log($(canvasjQueryElement)[0].width)

0

这里有一个 CodePen,它使用 canvas.height/width、CSS height/width 和 context 来正确地渲染任何大小的画布

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
  };
}

基本上,canvas.height/width设置了您要渲染的位图的大小。然后,CSS height/width将位图缩放以适应布局空间(通常在缩放时扭曲它)。然后,上下文可以修改其比例以使用矢量操作以不同的大小进行绘制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接