El lienzo se estira cuando se usa CSS pero es normal con los atributos `ancho` y `alto`

5 minutos de lectura

Avatar de usuario de Sirber
sirber

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 300×300.

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

texto alternativo

Avatar de usuario de SamB
SamB

parece que el width y height los atributos determinan 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 el Especificación HTML:

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

  • de hecho … Siempre pensé que los atributos directos como “ancho” y “alto” estaban en desuso en las versiones html recientes …

    – Sirber

    9 de abril de 2010 a las 0:02

  • Oh, aparentemente en realidad 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 lugar equivocado. width antes y fue a la #dom-canvas-width sección en su lugar. Archivado w3.org/Bugs/Public/show_bug.cgi?id=9469 sobre eso

    – SamB

    9 de abril de 2010 a las 16:27


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

    – Ben Astón

    28 de agosto de 2017 a las 9:22

  • Es importante distinguirlos en los casos en que desea que el sistema de coordenadas internas sea diferente. (es decir, para pantallas retina o juegos de estilo de 8 bits)

    – Samie Bencherif

    13 de noviembre de 2018 a las 6:13

  • Esto fue realmente confuso. Intentamos establecer el ancho y la altura en el css. Nos tomó 2 días de estrés tirando del cabello para descubrir estas 2 interpretaciones diferentes sobre el ancho y la altura. Simplemente guau…

    – Entretenimiento de nuevos medios NME

    7 mayo 2020 a las 22:40

avatar de usuario de fermar
Fermar

Para configurar el width y height en un lienzo, puede usar:

canvasObject.setAttribute('width', '150');
canvasObject.setAttribute('height', '300');

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

    – Shanimal

    7 de noviembre de 2012 a las 16:53

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

    – Maxbester

    7 de marzo de 2013 a las 8:00

  • Gran respuesta, ¡pero no olvides agregar canvasObject.setAttribute(‘height’, ‘123’) también!

    – Tom Wells

    15 de marzo de 2013 a las 14:46

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

    – Zorgatone

    21 de junio de 2017 a las 14:42

  • Versión de JavaScript simple (sin jQuery) usando getComputedStyle: canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));. Repita para la altura.

    – Ben J.

    14 de julio de 2017 a las 10:17

Avatar de usuario de Ben Jackson
ben jackson

Para <canvas> elementos, las reglas CSS para width y height establezca el tamaño real del elemento del lienzo que se dibujará en la página. Por otro lado, los atributos HTML de width y height establezca 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>

En ambos se ha dibujado lo mismo en relación con las coordenadas internas del elemento canvas. Pero en el segundo lienzo, el rectángulo rojo tendrá el doble de ancho porque el lienzo en su conjunto se estira en un área más grande según las reglas de CSS.

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

Avatar de usuario de Bluerain
Lluvia azul

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 así:

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

El navegador usa 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 establezca el ancho y alto del lienzo en eso.

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

Avatar de usuario de XaviGuardia
XaviGuardia

Shannimal corrección

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

Avatar de usuario de Yves M.
yves m

Canvas representa la imagen por búfer, por lo que cuando especifica los atributos HTML de ancho y alto, el tamaño y la longitud del búfer cambian, pero cuando usa CSS, el tamaño del búfer no cambia. Haciendo la imagen estirada.

Uso de tamaño HTML.

Se cambia el tamaño del lienzo -> se cambia el tamaño del búfer -> renderizado

Usando el tamaño de CSS

Se cambia el tamaño del lienzo -> renderizado

Dado que la longitud del búfer se mantiene sin cambios, cuando el contexto representa la imagen, la imagen se muestra en un lienzo redimensionado (pero renderizado en un búfer sin cambios).

¿Ha sido útil esta solución?