Comment obtenir la largeur et la hauteur d'un canevas HTML5?

95

Comment puis-je obtenir la largeur et la hauteur de l'élément canvas en JavaScript?

Aussi, quel est le «contexte» du canevas que je continue à lire?

serrer
la source

Réponses:

122

Cela vaut peut-être la peine de regarder un tutoriel: Tutoriel Firefox Canvas

Vous pouvez obtenir la largeur et la hauteur d'un élément de canevas simplement en accédant à ces propriétés de l'élément. Par exemple:

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

Si les attributs width et height ne sont pas présents dans l'élément canvas, la taille par défaut 300x150 sera renvoyée. Pour obtenir dynamiquement la largeur et la hauteur correctes, utilisez le code suivant:

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

Ou en utilisant la syntaxe de déstructuration d'objet plus courte:

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

Le contextest un objet que vous obtenez du canevas pour vous permettre d'y dessiner. Vous pouvez considérer le contextcomme l'API du canevas, qui vous fournit les commandes qui vous permettent de dessiner sur l'élément canevas.

andrewmu
la source
Notez que le didacticiel Mozilla est essentiellement un tas de liens rompus maintenant, malheureusement. J'espère qu'ils le répareront un jour.
Sz.
1
Cela renvoie la taille de la toile de contexte dans Chrome 31.
shuji
12
cela ne fonctionne que si widthet heightsont spécifiés directement comme <canvas />attributs de balise
vladkras
5
Ce n'est pas vrai. Il renvoie toujours une valeur même sans attributs de balise, par défaut à 300 x 150.
Michael Theriot
Sachez que getBoundingClientRect () inclut parfois des bordures. Cela peut ou non avoir une importance, mais dans mon CSS, j'ai défini la largeur et la hauteur à 100,100 et le getBoundingClientRect renvoie 102, 102. clientHeight et clientWidth (ou scrollHeight et scrollWidth) retournent 100 correctement.
DoomGoober
38

Eh bien, toutes les réponses précédentes ne sont pas entièrement correctes. 2 des principaux navigateurs ne prennent pas en charge ces 2 propriétés (IE en fait partie) ou les utilisent différemment.

Meilleure solution (prise en charge par la plupart des navigateurs, mais je n'ai pas vérifié Safari):

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

Au moins j'obtiens des valeurs correctes avec scrollWidth et -Height et DOIT définir canvas.width et height lorsqu'il est redimensionné.

Bleu amer
la source
IE9 semble prendre en charge canvas.width et height bien (les versions antérieures à 9 ne supportaient pas du tout canvas), je viens de l'essayer. Quels problèmes avez-vous rencontrés? Et quel est l'autre navigateur majeur?
thomanski
1
Oui, je ne mets jamais à jour IE parce que je ne l'utilise pas. L'autre navigateur majeur est Opera qui n'a pas / n'a pas mis à jour la largeur et la hauteur lors du redimensionnement.
Bitterblue
2
canvas.width ou height ne renvoient pas la taille totale du canvas, préférez le canvas.scrollWidth ou height pour obtenir la taille réelle totale du canvas.
Jordan
1
Cela a fonctionné pour moi, mais les autres réponses n'ont pas fonctionné. Je cherchais une solution qui pourrait obtenir la largeur et la hauteur si la toile était définie à l'aide de bootstrap.
wanderer0810
21

Les réponses mentionnant canvas.widthrenvoient les dimensions internes du canevas, c'est à dire celles spécifiées lors de la création de l'élément:

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

Si vous dimensionnez le canevas avec CSS, ses dimensions DOM sont accessibles via .scrollWidthet .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
la source
c'était la bonne réponse. 2 dimensions à considérer.
Nadir
2
cela devrait être la réponse choisie. direct widthet heightcall renverront toujours 300x150 si vous ne spécifiez aucune valeur et utilisez le dimensionnement relatif (en utilisant bootstrap ... etc). Merci.
mcy
16

L'objet context vous permet de manipuler le canevas; vous pouvez dessiner des rectangles par exemple et bien plus encore.

Si vous souhaitez obtenir la largeur et la hauteur, vous pouvez simplement utiliser les attributs HTML standard widthet height:

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

alert( canvas.width );
alert( canvas.height ); 
Harmen
la source
3
Cette réponse est à peu près identique à celle de @ andrewmu et ne fonctionnera pas si vous redimensionnez le canevas via CSS. Voir ma réponse pour une solution plus robuste.
Dan Dascalescu
9

À partir de 2015, tous les navigateurs (principaux?) semblent autoriser c.widthet c.heightobtenir la taille interne du canevas , mais:

la question car les réponses sont trompeuses, car la toile a en principe 2 tailles différentes / indépendantes.

Le "html" laisse dire largeur / hauteur CSS et sa propre largeur / hauteur (attribut-)

regardez ce court exemple de tailles différentes , où j'ai mis un canevas 200/200 dans un élément html 300/100

Avec la plupart des exemples (tout ce que j'ai vu), il n'y a pas de jeu de taille css, donc ils impliquent la largeur et la hauteur de la taille de la toile (dessin-). Mais ce n'est pas un must, et peut produire des résultats amusants, si vous prenez la mauvaise taille - ie. css largeur / hauteur pour le positionnement intérieur.

demi-bit
la source
0

Aucun de ceux-ci n'a fonctionné pour moi. Essaye ça.

console.log($(canvasjQueryElement)[0].width)
Sous-thème
la source
0

Voici un CodePen qui utilise canvas.height / width, CSS height / width et context pour rendre correctement n'importe quel canevas de n'importe quelle taille .

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

Fondamentalement, canvas.height / width définit la taille du bitmap sur lequel vous effectuez le rendu. La hauteur / largeur CSS met ensuite le bitmap à l'échelle pour l'adapter à l'espace de mise en page (souvent en le déformant à mesure qu'il le met à l'échelle). Le contexte peut ensuite modifier son échelle pour dessiner, à l'aide d'opérations vectorielles, à différentes tailles.

DoomGoober
la source
-1

J'ai eu un problème car mon canevas était à l'intérieur d'un conteneur sans ID, j'ai donc utilisé ce code jquery ci-dessous

$('.cropArea canvas').width()
Brian Sanchez
la source
Je poste toujours quand je l'utilise .. qui est le génie qui vote ma réponse? aimerait savoir ..
Brian Sanchez
JQuery est une grande dépendance pour cette petite tâche.
sdgfsdh
J'ai essayé l'option votée et je n'ai pas fonctionné pour moi alors j'ai posté ma solution, lors du codage, ce dont vous avez besoin est le temps, le temps est d'or alors pourquoi ne pas utiliser jquery ?? .. intéressant, alors pourquoi voter contre? ...
Brian Sanchez
1
JQuery ajoute un gonflement considérable à un site Web. Cela peut vous faire gagner du temps, mais cela ralentit la page pour vos utilisateurs. Vous devez être conscient de ce compromis.
sdgfsdh