La tela viene allungata quando si utilizza CSS ma normale con proprietà "larghezza" / "altezza"


195

Ho 2 tele, una usa gli attributi HTML widthe heightper ridimensionarla, l'altra 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 viene visualizzato come dovrebbe, ma non compteur2. Il contenuto viene disegnato utilizzando JavaScript su una tela 300x300.

Perché c'è una differenza di visualizzazione?

testo alternativo

Risposte:


216

Sembra che gli attributi widthe heightdeterminino la larghezza o l'altezza del sistema di coordinate del canvas, mentre le proprietà CSS determinano solo la dimensione del riquadro in cui verrà mostrato.

Questo è spiegato su http://www.whatwg.org/html#attr-canvas-width (necessita di JS) o http://www.whatwg.org/c#attr-canvas-width (probabilmente mangerà il tuo computer) :

L' canvaselemento ha due attributi per controllare la dimensione della bitmap dell'elemento: widthe height. Questi attributi, quando specificati, devono avere valori che sono numeri interi non negativi validi . Le regole per l'analisi di numeri interi non negativi devono essere utilizzate per ottenere i loro valori numerici. Se manca un attributo o se l'analisi del suo valore restituisce un errore, è necessario utilizzare invece il valore predefinito. L' widthattributo predefinito è 300 e l' heightattributo predefinito 150.


11
anzi .. ho sempre pensato che attributi diretti come "larghezza" e "altezza" fossero deprecati nelle recenti versioni html ..
Sirber

4
Oh, a quanto pare in realtà è descritto piuttosto bene su whatwg.org/specs/web-apps/current-work/multipage/… (sezione #attr-canvas-width). Il problema è che ho cliccato sull'errato widthprima e sono andato #dom-canvas-widthinvece alla sezione. Archiviato w3.org/Bugs/Public/show_bug.cgi?id=9469 al riguardo.
SamB

3
Avere un'API che assomiglia ma è sostanzialmente diversa da un'altra (larghezza css, altezza). Wow.
Ben Aston,

1
È importante distinguerli per i momenti in cui si desidera che il sistema di coordinate interno sia diverso. (ovvero per display a retina o gioco in stile 8 bit)
Samy Bencherif,

1
Questo è stato davvero confuso. Dove stavamo cercando di impostare la larghezza e l'altezza nel CSS. Ci sono voluti 2 giorni di stress per tirare i capelli per scoprire queste 2 diverse interpretazioni su larghezza e altezza. Solo wow ...
NME New Media Entertainment

39

Per impostare il widthe heightnecessario, è possibile utilizzare

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

6
+1 ha el.setAttribute('width', parseInt($el.css('width')))fatto il trucco, grazie
Shanimal

9
Cosa succede se voglio che la mia tela abbia una dimensione relativa? Vale a dire, come imitare una width: 100%;proprietà CSS?
Maxbester

1
Ottima risposta, ma non dimenticare di aggiungere anche canvasObject.setAttribute ('height', '123')!
Tom Wells,

Non penso che sia necessario utilizzare .setAttribute () Ho sempre usato le proprietà .width e .height
Zorgatone,

4
Plain JavaScript (senza jQuery) versione utilizzando getComputedStyle : canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));. Ripeti per l'altezza.
Ben J,

25

Per gli <canvas>elementi, le regole CSS regolano widthe heightimpostano le dimensioni effettive dell'elemento canvas che verrà disegnato sulla pagina. D'altra parte, gli attributi HTML di widthe heightimpostare la dimensione del sistema di coordinate o 'griglia' che verrà utilizzata dall'API canvas.

Ad esempio, considera questo ( 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>

Entrambi hanno avuto la stessa cosa disegnata su di loro rispetto alle coordinate interne dell'elemento tela. Ma nella seconda tela, il rettangolo rosso sarà due volte più largo perché la tela nel suo insieme viene estesa su un'area più grande dalle regole CSS.

Nota: se le regole CSS per widthe / o heightnon sono specificate, il browser utilizzerà gli attributi HTML per dimensionare l'elemento in modo che 1 unità di questi valori sia uguale a 1px sulla pagina. Se questi attributi non vengono specificati, per impostazione predefinita saranno a widthdi 300e a heightdi 150.


16

La tela verrà allungata se imposti la larghezza e l'altezza nel tuo CSS. Se vuoi manipolare dinamicamente la dimensione della tela devi usare JavaScript in questo modo:

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

1
Grande! Grazie per questa risposta Ho dovuto mettere canvas.setAttributeprima canvas.getContext('2d')per evitare l'allungamento dell'immagine.
hhh,

6

Il browser utilizza la larghezza e l'altezza del CSS, ma l'elemento tela viene ridimensionato in base alla larghezza e all'altezza della tela. In javascript, leggi la larghezza e l'altezza del CSS e imposta la larghezza e l'altezza della tela su quella.

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

2

Correzione Shannimal

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

0

CSS imposta la larghezza e l'altezza dell'elemento canvas in modo che influisca sullo spazio delle coordinate lasciando tutto il disegno distorto

Ecco il mio modo su come impostare la larghezza e l'altezza con Vanilla JavaScript

canvas.width = numberForWidth

canvas.height = numberForHeight

-1

Se si desidera un comportamento dinamico basato, ad esempio, query multimediali CSS, non utilizzare gli attributi di larghezza e altezza della tela. Utilizzare le regole CSS e quindi, prima di ottenere il contesto di rendering della tela, assegnare agli attributi larghezza e altezza gli stili di larghezza e altezza CSS:

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

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

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

È chiaro che una tela otterrà una dimensione di coordinate predefinita (300 x 150) se la dimensione è specificata solo nel CSS. Tuttavia, questo suggerimento non funziona per me, ma la soluzione seguente funziona.
Per Lindberg,

@PerLindberg - Questa soluzione funziona se hai definito una larghezza e un'altezza CSS in pixel per l'elemento canvas.
Manolo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.