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.