Wie erhalte ich die Breite und Höhe einer HTML5-Zeichenfläche?

94

Wie kann ich die Breite und Höhe des Canvas-Elements in JavaScript ermitteln?

Was ist auch der "Kontext" der Leinwand, über die ich immer wieder lese?

Klemme
quelle

Antworten:

122

Es könnte sich lohnen, sich ein Tutorial anzusehen: Firefox Canvas Tutorial

Sie können die Breite und Höhe eines Canvas-Elements ermitteln, indem Sie einfach auf diese Eigenschaften des Elements zugreifen. Beispielsweise:

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

Wenn die Attribute width und height im Canvas-Element nicht vorhanden sind, wird die Standardgröße 300 x 150 zurückgegeben. Verwenden Sie den folgenden Code, um dynamisch die richtige Breite und Höhe zu erhalten:

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

Oder verwenden Sie die kürzere Objektzerstörungssyntax:

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

Dies contextist ein Objekt, das Sie von der Leinwand erhalten, damit Sie hinein zeichnen können. Sie können sich das contextals API für die Zeichenfläche vorstellen, die Ihnen die Befehle zur Verfügung stellt, mit denen Sie auf das Zeichenflächenelement zeichnen können.

andrewmu
quelle
Beachten Sie, dass das Mozilla-Tutorial jetzt leider eine Reihe von defekten Links enthält. Ich hoffe, sie werden es eines Tages reparieren.
Gr.
1
Dies gibt die Kontext-Canvas-Größe in Chrome 31 zurück.
Shuji
12
Dies funktioniert nur, wenn widthund heightdirekt als <canvas />Tag-Attribute angegeben werden
vladkras
5
Das ist nicht wahr. Es gibt auch ohne Tag-Attribute immer einen Wert zurück,
standardmäßig
Beachten Sie, dass getBoundingClientRect () manchmal Rahmen enthält. Dies mag wichtig sein oder auch nicht, aber in meinem CSS setze ich die Breite und Höhe auf 100.100 und getBoundingClientRect gibt 102, 102 zurück. ClientHeight und clientWidth (oder scrollHeight und scrollWidth) geben 100 korrekt zurück.
DoomGoober
38

Nun, alle Antworten zuvor sind nicht ganz richtig. 2 der gängigen Browser unterstützen diese beiden Eigenschaften nicht (IE ist eine davon) oder verwenden sie anders.

Bessere Lösung (wird von den meisten Browsern unterstützt, aber ich habe Safari nicht überprüft):

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

Zumindest erhalte ich korrekte Werte mit scrollWidth und -Height und MUSS canvas.width und height festlegen, wenn die Größe geändert wird.

Bitter blau
quelle
IE9 scheint canvas.width und height in Ordnung zu unterstützen (Versionen vor 9 unterstützten Canvas überhaupt nicht), ich habe es gerade ausprobiert. Auf welche Probleme sind Sie gestoßen? Und welcher ist der andere große Browser?
Thomanski
1
Richtig, ich aktualisiere den IE wirklich nie, weil ich ihn nicht benutze. Der andere Hauptbrowser ist Opera, der Breite und Höhe beim Ändern der Größe nicht aktualisiert hat.
Bitterblue
2
canvas.width oder height geben nicht die Gesamtgröße der Leinwand zurück. Bevorzugen Sie die canvas.scrollWidth oder height, um die tatsächliche Gesamtgröße der Leinwand zu erhalten.
Jordanien
1
Das hat bei mir funktioniert, die anderen Antworten jedoch nicht. Ich suchte nach einer Lösung, die die Breite und Höhe ermitteln kann, wenn die Zeichenfläche mithilfe von Bootstrap festgelegt wird.
wanderer0810
21

Die genannten Antworten canvas.widthgeben die internen Abmessungen der Zeichenfläche zurück, dh die beim Erstellen des Elements angegebenen:

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

Wenn Sie die Leinwand mit CSS Größe, sind seine DOME Dimensionen erreichbar über .scrollWidthund .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">

Dan Dascalescu
quelle
das war die richtige Antwort. 2 Dimensionen zu berücksichtigen.
Nadir
2
Dies sollte die ausgewählte Antwort sein. direct widthund heightcall geben immer 300x150 zurück, wenn Sie keine Werte angeben und die relative Größe verwenden (während Sie Bootstrap verwenden ... usw.). Vielen Dank.
mcy
17

Mit dem Kontextobjekt können Sie die Zeichenfläche bearbeiten. Sie können zum Beispiel Rechtecke und vieles mehr zeichnen.

Wenn Sie die Breite und Höhe erhalten möchten, können Sie einfach die Standard-HTML-Attribute verwenden widthund height:

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

alert( canvas.width );
alert( canvas.height ); 
Harmen
quelle
3
Diese Antwort ist ziemlich identisch mit der von @ andrewmu und funktioniert nicht, wenn Sie die Größe der Zeichenfläche über CSS anpassen. Siehe meine Antwort für eine robustere Lösung.
Dan Dascalescu
9

Ab 2015 scheinen alle (Haupt-?) Browser zuzulassen c.widthund c.heightdie interne Größe der Leinwand zu erhalten , aber:

Die Frage als Antwort ist irreführend, da die Leinwand grundsätzlich 2 verschiedene / unabhängige Größen hat.

Das "HTML" sagt CSS Breite / Höhe und seine eigene (Attribut-) Breite / Höhe

Schauen Sie sich dieses kurze Beispiel für eine andere Größe an , bei dem ich eine 200/200-Zeichenfläche in ein 300/100-HTML-Element eingefügt habe

Bei den meisten Beispielen (alles, was ich gesehen habe) gibt es keine CSS-Größe, so dass diese die Breite und Höhe der (Zeichnungs-) Leinwandgröße implizit erhalten. Aber das ist kein Muss und kann zu lustigen Ergebnissen führen, wenn Sie die falsche Größe wählen - dh. CSS-Breite / Höhe für die innere Positionierung.

Halbbit
quelle
0

Keiner von denen hat für mich gearbeitet. Versuche dies.

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

Hier ist ein CodePen, der canvas.height / width, CSS height / width und context verwendet, um jede Leinwand in jeder Größe korrekt zu rendern .

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

Grundsätzlich legt canvas.height / width die Größe der Bitmap fest, auf die Sie rendern. Die CSS-Höhe / Breite skaliert dann die Bitmap, um sie an den Layoutbereich anzupassen (häufig wird sie beim Skalieren verzerrt). Der Kontext kann dann seine Skalierung ändern, um mithilfe von Vektoroperationen unterschiedliche Größen zu zeichnen.

DoomGoober
quelle
-1

Ich hatte ein Problem, weil sich meine Leinwand in einem Container ohne ID befand, also habe ich diesen unten stehenden Abfragecode verwendet

$('.cropArea canvas').width()
Brian Sanchez
quelle
Ich poste immer, wenn ich es benutze. Wer ist das Genie, das meine Antwort ablehnt? würde gerne wissen ..
Brian Sanchez
JQuery ist eine große Abhängigkeit für diese kleine Aufgabe.
SDGFSDH
Ich habe die gewählte Option ausprobiert und nicht für mich gearbeitet, also habe ich meine Lösung veröffentlicht. Wenn Sie codieren, was Sie brauchen, ist Zeit, Zeit ist Gold. Warum also nicht jquery verwenden? Interessant, warum dann abstimmen? ...
Brian Sanchez
1
JQuery fügt einer Website ein beträchtliches Aufblähen hinzu. Dies spart möglicherweise Zeit, verlangsamt jedoch die Seite für Ihre Benutzer. Sie müssen sich dieses Kompromisses bewusst sein.
SDGFSDH