¿Cómo obtengo el ancho y el alto de un lienzo HTML5?

95

¿Cómo puedo obtener el ancho y el alto del elemento de lienzo en JavaScript?

Además, ¿cuál es el "contexto" del lienzo sobre el que sigo leyendo?

abrazadera
fuente

Respuestas:

122

Podría valer la pena ver un tutorial: Tutorial de Firefox Canvas

Puede obtener el ancho y el alto de un elemento de lienzo simplemente accediendo a esas propiedades del elemento. Por ejemplo:

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

Si los atributos de ancho y alto no están presentes en el elemento de lienzo, se devolverá el tamaño predeterminado de 300x150. Para obtener dinámicamente el ancho y alto correctos, use el siguiente código:

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

O usando la sintaxis de desestructuración de objetos más corta:

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

El contextes un objeto que obtienes del lienzo para que puedas dibujar en él. Puede pensar en el contextcomo la API del lienzo, que le proporciona los comandos que le permiten dibujar en el elemento del lienzo.

andrewmu
fuente
Tenga en cuenta que el tutorial de Mozilla es básicamente un montón de enlaces rotos ahora, desafortunadamente. Espero que lo arreglen algún día.
Sz.
1
Esto devuelve el tamaño del lienzo de contexto en Chrome 31.
shuji
12
esto solo funciona si widthy heightse especifican directamente como <canvas />atributos de etiqueta
vladkras
5
Eso no es verdad. Siempre devuelve un valor incluso sin atributos de etiqueta, con un valor predeterminado de 300 x 150.
Michael Theriot
Tenga en cuenta que getBoundingClientRect () a veces incluye bordes. Esto puede o no importar, pero en mi CSS configuro el ancho y el alto en 100,100 y getBoundingClientRect devuelve 102, 102. clientHeight y clientWidth (o scrollHeight y scrollWidth) devuelven 100 correctamente.
DoomGoober
38

Bueno, todas las respuestas anteriores no son del todo correctas. 2 de los principales navegadores no admiten esas 2 propiedades (IE es una de ellas) o las usan de manera diferente.

Mejor solución (compatible con la mayoría de los navegadores, pero no verifiqué Safari):

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

Al menos obtengo los valores correctos con scrollWidth y -Height y DEBO establecer canvas.width y height cuando se cambia de tamaño.

Azul amargo
fuente
IE9 parece admitir canvas.width y height bien (las versiones anteriores a la 9 no admitían canvas en absoluto), acabo de intentarlo. ¿Qué problemas te has encontrado? ¿Y cuál es el otro navegador importante?
thomanski
1
Bien, realmente nunca actualizo IE porque no lo uso. El otro navegador principal es Opera, que no actualizó / no actualizó el ancho y el alto mientras cambiaba el tamaño.
Bitterblue
2
canvas.width o height no devuelven el tamaño total del lienzo, prefiera canvas.scrollWidth o height para obtener el tamaño real total del lienzo.
Jordania
1
Esto funcionó para mí, pero las otras respuestas no. Estaba buscando una solución que pudiera obtener el ancho y la altura si el lienzo se configuraba mediante bootstrap.
wanderer0810
21

Las respuestas que mencionan canvas.widthdevuelven las dimensiones internas del lienzo, es decir, las especificadas al crear el elemento:

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

Si modifica el tamaño del lienzo con CSS, se puede acceder a sus dimensiones DOM mediante .scrollWidthy .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
fuente
esa fue la respuesta correcta. 2 dimensiones a considerar.
Nadir
2
esta debería ser la respuesta seleccionada. direct widthy heightcall siempre devolverán 300x150 si no especifica ningún valor y usa un tamaño relativo (mientras usa bootstrap ... etc.). Gracias.
mcy
16

El objeto de contexto le permite manipular el lienzo; puedes dibujar rectángulos, por ejemplo, y mucho más.

Si desea obtener el ancho y el alto, puede usar los atributos HTML estándar widthy height:

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

alert( canvas.width );
alert( canvas.height ); 
Harmen
fuente
3
Esta respuesta es prácticamente idéntica a la de @ andrewmu y no funcionará si modifica el tamaño del lienzo mediante CSS. Vea mi respuesta para una solución más robusta.
Dan Dascalescu
9

ahora a partir de 2015, todos los navegadores (¿principales?) parecen permitir c.widthy c.heightobtener el tamaño interno del lienzo , pero:

la pregunta como las respuestas son engañosas, porque el lienzo tiene en principio 2 tamaños diferentes / independientes.

El "html" permite decir CSS ancho / alto y su propio (atributo-) ancho / alto

mire este breve ejemplo de diferentes tamaños , donde puse un lienzo 200/200 en un elemento html 300/100

Con la mayoría de los ejemplos (todos los que vi) no hay un conjunto de tamaño css, por lo que estos incluyen el ancho y la altura del tamaño del lienzo (dibujo). Pero eso no es obligatorio y puede producir resultados divertidos si se toma el tamaño incorrecto, es decir. css ancho / alto para posicionamiento interior.

medio bit
fuente
0

Ninguno de ellos funcionó para mí. Prueba esto.

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

Aquí hay un CodePen que usa canvas.height / width, CSS height / width y context para representar correctamente cualquier lienzo en cualquier tamaño .

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

Básicamente, canvas.height / width establece el tamaño del mapa de bits que está renderizando. El alto / ancho de CSS luego escala el mapa de bits para que se ajuste al espacio de diseño (a menudo lo deforma al escalarlo). El contexto puede entonces modificar su escala para dibujar, usando operaciones vectoriales, en diferentes tamaños.

DoomGoober
fuente
-1

Tuve un problema porque mi lienzo estaba dentro de un contenedor sin identificación, así que usé este código jquery a continuación

$('.cropArea canvas').width()
Brian Sánchez
fuente
Siempre publico cuando lo uso ... ¿quién es el genio que rechaza mi respuesta? quisiera saber ..
Brian Sanchez
JQuery es una gran dependencia para esta pequeña tarea.
sdgfsdh
Probé la opción votada y no funcionó para mí, así que publiqué mi solución, cuando codificar lo que necesitas es tiempo, el tiempo es oro, ¿por qué no usar jquery ?? .. interesante, ¿entonces por qué votar en contra? ...
Brian Sanchez
1
JQuery agrega una hinchazón considerable a un sitio web. Puede ahorrarle tiempo, pero ralentiza la página para sus usuarios. Debe ser consciente de esta compensación.
sdgfsdh