Canvas se estira cuando se usa CSS pero normal con propiedades" width " / "height"


Tengo 2 lienzos, uno usa atributos HTML width y height para dimensionarlo, el otro usa CSS:

<canvas id="compteur1" width="300" height="300" onmousedown="compteurClick(this.id);"></canvas>
<canvas id="compteur2" style="width: 300px; height: 300px;" onmousedown="compteurClick(this.id);"></canvas>

Compteur1 se muestra como debería, pero no compteur2. El contenido se dibuja usando JavaScript en un lienzo de 300x300.

¿Por qué hay una diferencia de visualización?

texto alt

Author: Martijn Pieters, 2010-04-07

7 answers

Parece que los atributos width y height determinan el ancho o alto del sistema de coordenadas del lienzo, mientras que las propiedades CSS solo determinan el tamaño del cuadro en el que se mostrará.

Esto se explica en http://www.whatwg.org/html#attr-canvas-width (necesita JS) o http://www.whatwg.org/c#attr-canvas-width (probablemente se comerá su computadora):

El elemento canvas tiene dos atributos para controlar el tamaño del elemento mapa de bits: width y height. Estos atributos, cuando se especifican, deben tener valores que sean enteros no negativos válidos. Las reglas para analizar enteros no negativos deben usarse para obtener sus valores numéricos. Si falta un atributo, o si el análisis de su valor devuelve un error, se debe usar el valor predeterminado en su lugar. El atributo width por defecto es 300, y el atributo height por defecto es 150.

 185
Author: SamB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-06 05:46:32

Para establecer el width y height que necesita, puede usar

canvasObject.setAttribute('width', '475');
 34
Author: fermar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-09 18:26:44

Para los elementos <canvas>, las reglas CSS para width y height establecen el tamaño real del elemento canvas que se dibujará en la página. Por otro lado, los atributos HTML de width y height establecen el tamaño del sistema de coordenadas o 'grid' que utilizará la API canvas.

Por ejemplo, considere esto ( jsfiddle):

var ctx = document.getElementById('canvas1').getContext('2d');
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);

var ctx2 = document.getElementById('canvas2').getContext('2d');
ctx2.fillStyle = "red";
ctx2.fillRect(10, 10, 30, 30);
canvas {
  border: 1px solid black;
}
<canvas id="canvas1" style="width: 50px; height: 100px;" height="50" width="100"></canvas>
<canvas id="canvas2" style="width: 100px; height: 100px;" height="50" width="100"></canvas>

Ambos han dibujado la misma cosa en relación con las coordenadas internas del elemento canvas. Pero en el segundo lienzo, el rectángulo rojo será el doble de ancho porque el lienzo en su conjunto se estira a través de un área más grande por las reglas CSS.

Nota: Si no se especifican las reglas CSS para width y/o height, el navegador utilizará los atributos HTML para dimensionar el elemento de manera que 1 unidad de estos valores sea igual a 1px en la página. Si estos atributos no se especifican, entonces tendrán por defecto un width de 300 y un height de 150.

 19
Author: BYossarian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-12 04:12:52

El lienzo se extenderá si establece el ancho y la altura en su CSS. Si desea manipular dinámicamente la dimensión del lienzo, debe usar JavaScript de la siguiente manera:

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
 15
Author: Arindam Mojumder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-24 16:45:57

El navegador utiliza el ancho y el alto de css, pero el elemento canvas se escala en función del ancho y el alto del lienzo. En javascript, lea el ancho y alto de css y establezca el ancho y alto del lienzo en eso.

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();
 3
Author: Russell Harkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-18 22:19:13

Corrección Shannimal

var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))
 2
Author: XaviGuardia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-21 11:47:09

Si desea un comportamiento dinámico basado en, por ejemplo, consultas de medios CSS, no utilice los atributos de ancho y alto de lienzo. Use reglas CSS y luego, antes de obtener el contexto de representación de canvas, asigne a los atributos width y height los estilos CSS width y height:

var elem = document.getElementById("mycanvas");

elem.width = elem.style.width;
elem.height = elem.style.height;

var ctx1 = elem.getContext("2d");
...
 0
Author: Manolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-25 19:43:17