Як отримати ширину та висоту полотна HTML5?


95

Як я можу отримати ширину та висоту елемента полотна в JavaScript?

Крім того, що таке "контекст" полотна, про яке я постійно читаю?

Відповіді:


122

Можливо, варто поглянути на підручник: Підручник з Firefox 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предмет, який ви отримуєте з полотна, щоб дозволити вам втягнути в нього. Ви можете уявити contextAPI як API для полотна, який надає вам команди, що дозволяють малювати на елементі полотна.


Зауважте, що підручник з Mozilla - це, на жаль, зараз купа розірваних посилань. Сподіваюся, що колись це виправлять.
Sz.

1
Це повертає розмір контекстного полотна в Chrome 31.
shuji

12
це працює тільки якщо widthі heightвказані безпосередньо в якості <canvas />атрибутів тегів
vladkras

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 та height, коли його розмір змінюється.


IE9, здається, добре підтримує canvas.width і width (версії до 9 взагалі не підтримували canvas), я щойно дав їй змогу. На які неприємності ви натрапили? А який інший основний браузер?
thomanski

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

2
canvas.width або height не повертає загальний розмір полотна, віддайте перевагу canvas.scrollWidth або height, щоб отримати загальний реальний розмір полотна.
Йорданія

1
Це спрацювало для мене, але інші відповіді - ні. Я шукав рішення, яке могло б отримати ширину та висоту, якщо полотно було встановлено за допомогою bootstrap.
wanderer0810

21

Згадані відповіді 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, якщо ви не вказали жодних значень і не використовуєте відносний розмір (під час використання bootstrap ... тощо). Дякую.
mcy

16

Об'єкт контексту дозволяє маніпулювати полотном; Ви можете намалювати прямокутники, наприклад, і багато іншого.

Якщо ви хочете отримати ширину та висоту, ви можете просто використовувати стандартні атрибути HTML widthта height:

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

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

3
Ця відповідь майже ідентична відповіді @ andrewmu і не буде працювати, якщо розмір полотна встановлюється за допомогою CSS. Дивіться мою відповідь на більш надійне рішення.
Дан Даскалеску,

9

тепер, починаючи з 2015 року, всі (основні?) браузери здаються недоступними c.widthта c.heightотримують внутрішнє полотно розмір , але:

питання як відповіді хибні, оскільки полотно має в принципі 2 різні / незалежні розміри.

"Html" дозволяє сказати ширину / висоту CSS та власну (атрибут) ширину / висоту

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

У більшості прикладів (усе, що я бачив) немає встановленого розміру css, тому вони отримують імплітіт ширини та висоти розміру полотна (для малювання). Але це не обов’язково, і це може принести веселі результати, якщо ви приймаєте неправильний розмір - тобто. css widht / height для внутрішнього позиціонування.


0

Жоден із тих не працював у мене. Спробуйте це.

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

0

Ось CodePen, який використовує canvas.height / width, CSS висоту / ширину та контекст для правильної візуалізації будь-якого полотна будь-якого розміру .

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.