Jak uzyskać szerokość i wysokość płótna HTML5?


97

Jak uzyskać szerokość i wysokość elementu canvas w JavaScript?

A jaki jest „kontekst” płótna, o którym ciągle czytam?

Odpowiedzi:


127

Warto zajrzeć do samouczka: Samouczek MDN Canvas

Możesz uzyskać szerokość i wysokość elementu canvas po prostu uzyskując dostęp do tych właściwości elementu. Na przykład:

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

Jeśli atrybuty szerokości i wysokości nie są obecne w elemencie canvas, zostanie zwrócony domyślny rozmiar 300x150. Aby dynamicznie uzyskać prawidłową szerokość i wysokość, użyj następującego kodu:

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

Lub używając krótszej składni destrukturyzacji obiektów:

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

contextTo obiekt można uzyskać z płótna, co pozwala wyciągnąć do niego. Możesz myśleć o contextinterfejsie API dla kanwy, który zapewnia polecenia, które umożliwiają rysowanie na elemencie canvas.


Zauważ, że samouczek Mozilli jest teraz w zasadzie zbiorem niedziałających linków, niestety. Mam nadzieję, że pewnego dnia to naprawią.
Sz.

1
Zwraca to rozmiar płótna kontekstu w Chrome 31.
shuji

12
działa to tylko wtedy, gdy widthi heightsą określone bezpośrednio jako <canvas />atrybuty tagu
vladkras

5
To nie jest prawda. Zawsze zwraca wartość, nawet bez atrybutów tagów,
domyślnie

Należy pamiętać, że metoda getBoundingClientRect () czasami zawiera obramowania. To może mieć znaczenie, ale nie musi, ale w moim CSS ustawiłem szerokość i wysokość na 100,100, a getBoundingClientRect zwraca 102, 102. clientHeight i clientWidth (lub scrollHeight i scrollWidth) zwracają 100 poprawnie.
DoomGoober

38

Cóż, wszystkie wcześniejsze odpowiedzi nie są całkowicie poprawne. 2 z głównych przeglądarek nie obsługują tych 2 właściwości (IE jest jedną z nich) lub używają ich w inny sposób.

Lepsze rozwiązanie (obsługiwane przez większość przeglądarek, ale nie sprawdzałem Safari):

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

Przynajmniej otrzymuję poprawne wartości za pomocą scrollWidth i -Height i MUSZĘ ustawić canvas.width i height, gdy jest zmieniany.


IE9 wydaje się obsługiwać canvas.width i height w porządku (wersje wcześniejsze niż 9 w ogóle nie obsługiwały canvas), właśnie dałem mu szansę. Jakie problemy napotkałeś? Jaka jest druga popularna przeglądarka?
thomanski

1
Racja, naprawdę nigdy nie aktualizuję IE, ponieważ go nie używam. Inną główną przeglądarką jest Opera, która nie aktualizowała / nie aktualizowała szerokości i wysokości podczas zmiany rozmiaru.
Bitterblue

2
canvas.width or height nie zwraca całkowitego rozmiaru płótna, preferuj canvas.scrollWidth lub height, aby uzyskać całkowity rzeczywisty rozmiar płótna.
Jordan,

1
To zadziałało dla mnie, ale inne odpowiedzi nie. Szukałem rozwiązania, które pozwoliłoby uzyskać szerokość i wysokość, gdyby płótno zostało ustawione za pomocą bootstrapa.
wędrowiec

22

Odpowiedzi wspominające o canvas.widthzwracaniu wymiarów wewnętrznych płótna, czyli określonych przy tworzeniu elementu:

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

Jeśli dopasujesz płótno do CSS, jego wymiary DOM są dostępne przez .scrollWidthi .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">


to była poprawna odpowiedź. 2 wymiary do rozważenia.
Nadir

2
powinna to być wybrana odpowiedź. direct widthi heightcall zawsze zwracają 300x150, jeśli nie określisz żadnych wartości i użyjesz względnego rozmiaru (podczas używania bootstrap ... itd.). Dzięki.
mcy,

16

Obiekt kontekstu umożliwia manipulowanie kanwą; możesz rysować na przykład prostokąty i wiele więcej.

Jeśli chcesz uzyskać szerokość i wysokość, możesz po prostu użyć standardowych atrybutów HTML widthi height:

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

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

3
Ta odpowiedź jest prawie identyczna z @ andrewmu i nie zadziała, jeśli zmienisz rozmiar płótna za pomocą CSS. Zobacz moją odpowiedź na bardziej solidne rozwiązanie.
Dan Dascalescu

9

teraz począwszy od 2015 roku wszystkie (główne?) przeglądarki wydają się zezwalać c.widthi c.heightuzyskują wewnętrzny rozmiar płótna , ale:

pytanie jako odpowiedzi jest mylące, ponieważ płótno ma w zasadzie 2 różne / niezależne rozmiary.

„HTML” określa szerokość / wysokość CSS oraz własną (atrybut-) szerokość / wysokość

spójrz na ten krótki przykład różnych rozmiarów , w którym umieściłem płótno 200/200 w elemencie html 300/100

W większości przykładów (wszystkie, które widziałem) nie ma ustawionego rozmiaru css, więc otrzymają one szerokość i wysokość rozmiaru (rysunku) płótna. Ale nie jest to konieczne i może przynieść kiepskie rezultaty, jeśli wybierzesz niewłaściwy rozmiar - tj. css szerokość / wysokość do pozycjonowania wewnętrznego.


0

Żaden z nich nie pracował dla mnie. Spróbuj tego.

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

0

Oto CodePen, który używa canvas.height / width, CSS height / width oraz context, aby poprawnie renderować dowolne płótno w dowolnym rozmiarze .

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

Zasadniczo plik canvas.height / width określa rozmiar renderowanej mapy bitowej. Wysokość / szerokość CSS następnie skaluje bitmapę, aby dopasować ją do obszaru układu (często wypaczając ją podczas skalowania). Kontekst może następnie zmodyfikować swoją skalę, aby rysować, używając operacji wektorowych, w różnych rozmiarach.


-1

Miałem problem, ponieważ moje płótno znajdowało się w kontenerze bez identyfikatora, więc użyłem poniższego kodu jquery

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

Zawsze publikuję, kiedy go używam .. kto jest geniuszem odrzucającym moją odpowiedź? chciałbym wiedzieć ...
Brian Sanchez

JQuery to duża zależność dla tego małego zadania.
sdgfsdh

Wypróbowałem opcję głosowania i nie zadziałało, więc opublikowałem moje rozwiązanie, kiedy kodowanie to czas, czas jest złoty, więc dlaczego nie użyć jquery ?? .. ciekawe, więc dlaczego przeciwnie? ...
Brian Sanchez

1
JQuery dodaje do witryny znaczne rozmiary. Może to zaoszczędzić czas, ale spowolni stronę dla użytkowników. Musisz zdawać sobie sprawę z tego kompromisu.
sdgfsdh
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.