Как получить ширину и высоту холста HTML5?


98

Как я могу получить ширину и высоту элемента холста в JavaScript?

Кроме того, каков «контекст» холста, о котором я продолжаю читать?

Ответы:


128

Возможно, стоит посмотреть учебник: Руководство по MDN Canvas.

Вы можете получить ширину и высоту элемента холста, просто получив доступ к этим свойствам элемента. Например:

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

Если атрибуты ширины и высоты отсутствуют в элементе холста, будет возвращен размер по умолчанию 300x150. Чтобы динамически получить правильную ширину и высоту, используйте следующий код:

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

Или используйте более короткий синтаксис деструктуризации объекта:

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

Это contextобъект, который вы получаете с холста, чтобы вы могли рисовать на нем. Вы можете рассматривать его contextкак API холста, который предоставляет вам команды, позволяющие рисовать на элементе холста.


Обратите внимание, что учебник Mozilla, к сожалению, теперь представляет собой набор неработающих ссылок. Надеюсь, они когда-нибудь это исправят.
Sz.

1
Это возвращает размер холста контекста в Chrome 31.
shuji 03

12
это работает, только если widthи heightуказано напрямую как <canvas />атрибуты тега
vladkras 07

5
Это неправда. Он всегда возвращает значение даже без атрибутов тега, по умолчанию 300 x 150.
Майкл Териот,

Имейте в виду, что getBoundingClientRect () иногда включает границы. Это может иметь значение, а может и не иметь значения, но в моем CSS я установил ширину и высоту на 100,100, а getBoundingClientRect возвращает 102, 102. clientHeight и clientWidth (или scrollHeight и scrollWidth) возвращают 100 правильно.
DoomGoober

38

Что ж, все предыдущие ответы не совсем верны. 2 основных браузера не поддерживают эти 2 свойства (IE является одним из них) или используют их по-разному.

Лучшее решение (поддерживается большинством браузеров, но я не проверял Safari):

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

По крайней мере, я получаю правильные значения с scrollWidth и -Height и ДОЛЖЕН установить canvas.width и высоту при изменении размера.


IE9, похоже, поддерживает canvas.width и height (версии до 9 вообще не поддерживали холст), я только что попробовал. С какими неприятностями столкнулись? А какой другой основной браузер?
thomanski

1
Правильно, я действительно никогда не обновляю IE, потому что я им не пользуюсь. Другой крупный браузер - Opera, который не обновлял / не обновлял ширину и высоту при изменении размера.
Bitterblue

2
canvas.width или height не возвращают общий размер холста, предпочитайте canvas.scrollWidth или height, чтобы получить общий реальный размер холста.
Jordan

1
Это сработало для меня, но другие ответы нет. Я искал решение, которое могло бы получить ширину и высоту, если бы холст был настроен с помощью начальной загрузки.
wanderer0810

22

Ответы, в которых упоминается, canvas.widthвозвращают внутренние размеры холста, то есть те, которые указаны при создании элемента:

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

Если вы измените размер холста с помощью CSS, его размеры DOM доступны через .scrollWidthи .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">


это был правильный ответ. 2 измерения, которые следует учитывать.
Надир

2
это должен быть выбранный ответ. direct widthи heightcall всегда будут возвращать 300x150, если вы не укажете никаких значений и используете относительный размер (при использовании начальной загрузки ... и т. д.). Спасибо.
mcy 05

16

Объект контекста позволяет вам управлять холстом; например, можно рисовать прямоугольники и многое другое.

Если вы хотите получить ширину и высоту, вы можете просто использовать стандартные атрибуты HTML widthи height:

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

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

3
Этот ответ практически идентичен ответу @andrewmu и не будет работать, если вы измените размер холста с помощью CSS. См. Мой ответ для более надежного решения.
Дэн Даскалеску 02

9

теперь, начиная с 2015 года, все (основные?) браузеры, похоже, разрешают c.widthи c.heightполучают внутренний размер холста , но:

вопрос, поскольку ответы неверны, потому что холст в принципе имеет 2 разных / независимых размера.

"Html" позволяет указать ширину / высоту CSS и его собственную (атрибут-) ширину / высоту.

посмотрите на этот короткий пример другого размера , где я поместил холст 200/200 в html-элемент 300/100

В большинстве примеров (все, что я видел) нет набора css-size, поэтому они подразумевают ширину и высоту размера холста (рисования). Но это не обязательно и может дать забавные результаты, если вы возьмете неправильный размер - т.е. css widht / height для внутреннего позиционирования.



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 масштабирует растровое изображение, чтобы оно соответствовало пространству макета (часто искажая его при масштабировании). Затем контекст может изменять масштаб для рисования с использованием векторных операций в разных размерах.


-1

У меня была проблема, потому что мой холст находился внутри контейнера без идентификатора, поэтому я использовал этот код jquery ниже

$('.cropArea canvas').width()

Я всегда отправляю сообщения, когда использую его ... Кто гений, проголосовавший против моего ответа? хотел бы знать ..
Брайан Санчес

JQuery - большая зависимость для этой небольшой задачи.
sdgfsdh

Я попробовал вариант, за который проголосовали, и у меня это не сработало, поэтому я опубликовал свое решение, когда кодирую то, что вам нужно, это время, время - золото, так почему бы не использовать jquery ?? .. интересно, тогда почему против? ...
Брайан Санчес

1
JQuery значительно увеличивает размер веб-сайта. Это может сэкономить ваше время, но замедлит работу страницы для ваших пользователей. Вы должны знать об этом компромиссе.
sdgfsdh
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.