Como obtenho a largura e a altura de uma tela HTML5?


94

Como posso obter a largura e a altura do elemento canvas em JavaScript?

Além disso, qual é o "contexto" da tela sobre a qual continuo lendo?

Respostas:


122

Pode valer a pena dar uma olhada em um tutorial: Firefox Canvas Tutorial

Você pode obter a largura e a altura de um elemento de tela simplesmente acessando essas propriedades do elemento. Por exemplo:

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

Se os atributos de largura e altura não estiverem presentes no elemento de tela, o tamanho padrão de 300 x 150 será retornado. Para obter dinamicamente a largura e altura corretas, use o seguinte código:

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

Ou usando a sintaxe de desestruturação de objeto mais curta:

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

O contexté um objeto que você obtém da tela para permitir que você desenhe nele. Você pode pensar no contextcomo a API para a tela, que fornece os comandos que permitem desenhar no elemento da tela.


Observe que o tutorial do Mozilla é basicamente um monte de links quebrados agora, infelizmente. Espero que consertem algum dia.
Sz.

1
Isso retorna o tamanho da tela de contexto no Chrome 31.
shuji

12
isso funciona apenas se widthe heightforem especificados diretamente como <canvas />atributos de tag
vladkras

5
Isso não é verdade. Ele sempre retorna um valor mesmo sem atributos de tag, com o padrão de 300 x 150.
Michael Theriot

Esteja ciente de que getBoundingClientRect () às vezes inclui bordas. Isso pode ou não importar, mas em meu CSS eu defino a largura e a altura como 100.100 e getBoundingClientRect retorna 102, 102. clientHeight e clientWidth (ou scrollHeight e scrollWidth) retornam 100 corretamente.
DoomGoober

38

Bem, todas as respostas anteriores não estão totalmente corretas. 2 dos principais navegadores não suportam essas 2 propriedades (o IE é uma delas) ou as usam de maneira diferente.

Melhor solução (compatível com a maioria dos navegadores, mas não verifiquei o Safari):

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

Pelo menos obtenho os valores corretos com scrollWidth e -Height e PRECISO definir canvas.width e height quando ele é redimensionado.


O IE9 parece oferecer suporte a canvas.width e height (as versões anteriores a 9 não suportavam canvas), acabei de tentar. Que problemas você encontrou? E qual é o outro navegador importante?
thomanski

1
Certo, eu realmente nunca atualizo o IE porque não o uso. O outro navegador principal é o Opera, que não atualizou / não atualizou a largura e a altura durante o redimensionamento.
Bitterblue

2
canvas.width ou height não retorna o tamanho total da tela, prefira canvas.scrollWidth ou height para obter o tamanho real total da tela.
Jordan

1
Isso funcionou para mim, mas as outras respostas não. Eu estava procurando uma solução que pudesse obter a largura e a altura se a tela fosse definida usando bootstrap.
wanderer0810

21

As respostas que mencionam canvas.widthretornam as dimensões internas do canvas, ou seja, aquelas especificadas na criação do elemento:

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

Se você dimensionar a tela com CSS, suas dimensões DOM podem ser acessadas por .scrollWidthe .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">


essa foi a resposta correta. 2 dimensões a considerar.
Nadir

2
esta deve ser a resposta selecionada. direct widthand heightcall sempre retornará 300x150 se você não especificar nenhum valor e usar o tamanho relativo (ao usar bootstrap ... etc). Obrigado.
mcy de

16

O objeto de contexto permite que você manipule a tela; você pode desenhar retângulos, por exemplo, e muito mais.

Se você deseja obter a largura e a altura, pode apenas usar os atributos HTML padrão widthe height:

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

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

3
Esta resposta é praticamente idêntica à de @andrewmu e não funcionará se você dimensionar a tela via CSS. Veja minha resposta para uma solução mais robusta.
Dan Dascalescu

9

agora, a partir de 2015, todos os (principais?) navegadores parecem baixar c.widthe c.heightobter o tamanho interno da tela , mas:

a pergunta como as respostas são enganosas, porque a tela tem em princípio 2 tamanhos diferentes / independentes.

O "html" permite dizer largura / altura CSS e sua própria (atributo) largura / altura

veja este pequeno exemplo de tamanho diferente , onde coloquei uma tela 200/200 em um elemento 300/100 html

Com a maioria dos exemplos (todos que eu vi), não existe um tamanho css definido, então eles implicam na largura e altura do tamanho da tela (desenho). Mas isso não é obrigatório e pode produzir resultados engraçados, se você escolher o tamanho errado - ou seja, css largura / altura para posicionamento interno.


0

Nenhum desses funcionou para mim. Experimente isso.

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

0

Aqui está um CodePen que usa canvas.height / width, CSS height / width e contexto para renderizar corretamente qualquer canvas em qualquer tamanho .

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

Basicamente, canvas.height / width define o tamanho do bitmap para o qual você está renderizando. A altura / largura do CSS, então, dimensiona o bitmap para caber no espaço do layout (geralmente distorcendo-o conforme o dimensiona). O contexto pode então modificar sua escala para desenhar, usando operações vetoriais, em tamanhos diferentes.


-1

Tive um problema porque minha tela estava dentro de um contêiner sem ID, então usei este código jquery abaixo

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

Eu sempre posto quando eu uso .. quem é o gênio downvoting minha resposta? gostaria de saber ..
Brian Sanchez

JQuery é uma grande dependência para essa pequena tarefa.
sdgfsdh

Tentei a opção votada e não funcionou para mim, então postei minha solução, ao codificar o que você precisa é de tempo, o tempo é ouro então por que não usar jquery ?? .. interessante, então por que fazer downvote? ...
Brian Sanchez

1
JQuery adiciona inchaço considerável a um site. Isso pode economizar seu tempo, mas torna a página mais lenta para seus usuários. Você precisa estar ciente dessa compensação.
sdgfsdh
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.