El lienzo se estira cuando se usa CSS pero es normal con las propiedades "ancho" / "alto"


194

Tengo 2 lienzos, uno usa atributos HTML widthy heightpara 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 alternativo

Respuestas:


215

Parece que los atributos widthy heightdeterminan el ancho o la altura 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 canvaselemento tiene dos atributos para controlar el tamaño del mapa de bits del elemento: widthy 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 utilizar el valor predeterminado. El widthatributo predeterminado es 300 y el heightatributo predeterminado es 150.


11
de hecho .. Siempre pensé atributos directos como "ancho" y "alto" quedaron en desuso en las últimas versiones html ..
Sirber

44
Oh, aparentemente se describe bastante bien en whatwg.org/specs/web-apps/current-work/multipage/… (sección #attr-canvas-width). El problema es que hice clic en el error widthantes y fui a la #dom-canvas-widthsección en su lugar. Archivado w3.org/Bugs/Public/show_bug.cgi?id=9469 al respecto.
SamB

3
Tener una API que se parece pero es fundamentalmente diferente a otra (css ancho, alto). Guau.
Ben Aston

1
Es importante distinguirlos cuando desee que el sistema de coordenadas interno sea diferente. (es decir, para pantallas de retina o juegos de 8
bits

1
Esto fue realmente confuso. Intentamos establecer el ancho y la altura en el CSS. Nos tomó 2 días estresándonos para descubrir estas 2 interpretaciones diferentes sobre el ancho y la altura. Just wow ...
NME New Media Entertainment

39

Para configurar widthy heightque necesita, puede usar

canvasObject.setAttribute('width', '475');

66
+1 el.setAttribute('width', parseInt($el.css('width')))hizo el truco, gracias
Shanimal

9
¿Qué sucede si quiero que mi lienzo tenga un tamaño relativo? Es decir, ¿cómo imitar una width: 100%;propiedad css?
Maxbester

1
Gran respuesta, pero no olvides agregar el canvasObject.setAttribute ('altura', '123') también.
Tom Wells

No creo que necesite usar .setAttribute () Siempre he usado las propiedades .width y .height
Zorgatone

44
Llanura JavaScript (sin jQuery) utilizando la versión getComputedStyle : canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));. Repita para la altura.
Ben J

25

Para los <canvas>elementos, las reglas CSS widthy heightestablecen el tamaño real del elemento del lienzo que se dibujará en la página. Por otro lado, los atributos HTML de widthy heightestablecen el tamaño del sistema de coordenadas o 'cuadrícula' que utilizará la API de lienzo.

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>

A ambos se les ha dibujado lo mismo en relación con las coordenadas internas del elemento de lienzo. Pero en el segundo lienzo, el rectángulo rojo tendrá el doble de ancho porque las reglas de CSS extienden el lienzo como un todo en un área más grande.

Nota: Si las reglas CSS para widthy / o heightno se especifican, el navegador usará los atributos HTML para dimensionar el elemento de manera que 1 unidad de estos valores sea igual a 1px en la página. Si no se especifican estos atributos, los valores predeterminados serán a widthde 300y a heightde 150.


16

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

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');

1
¡Excelente! Gracias por esta respuesta Tuve que poner canvas.setAttributeantes canvas.getContext('2d')para evitar el estiramiento de la imagen.
hhh

6

El navegador utiliza el ancho y el alto del CSS, pero el elemento del lienzo se escala según el ancho y el alto del lienzo. En javascript, lea el ancho y alto de css y configure el ancho y alto del lienzo para eso.

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();

2

Corrección de Shannimal

var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))

0

CSS establece el ancho y la altura del elemento de lienzo para que afecte el espacio de coordenadas dejando todo dibujado torcido

Este es mi camino sobre cómo establecer el ancho y la altura con Vanilla JavaScript

canvas.width = numberForWidth

canvas.height = numberForHeight

-1

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

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

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

var ctx1 = elem.getContext("2d");
...

Está claro que un lienzo obtendrá un tamaño de coordenadas predeterminado (300 x 150) si el tamaño solo se especifica en CSS. Sin embargo, esta sugerencia no funciona para mí, pero la solución a continuación sí.
Por Lindberg

@PerLindberg: esta solución funciona si ha definido un ancho y alto de CSS en píxeles para el elemento de lienzo.
Manolo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.