2010-04-06 9 views
156

I 2 Leinwänden haben, verwendet man HTML-Attribute width und height Größe es, die andere verwendet CSS:Leinwand gespannt wird, wenn CSS aber normal mit "Breite"/"Höhe" Eigenschaften mit Hilfe

<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 Displays wie es sollte, aber nicht compteur2. Der Inhalt wird mithilfe von JavaScript auf einer 300 x 300-Leinwand gezeichnet.

Warum gibt es einen Anzeigenunterschied?

alt text

Antwort

172

Es scheint, dass die width und height Attribute die Breite oder Höhe der Leinwand Koordinatensystem bestimmen, während die CSS-Eigenschaften nur die Größe der Box bestimmen, in dem es angezeigt.

Dies wird bei http://www.whatwg.org/html#attr-canvas-width erklärt (benötigt JS) oder http://www.whatwg.org/c#attr-canvas-width (wahrscheinlich Ihren Computer essen):

Das canvas Element hat zwei Attribute die Größe des Bitmap des Elements zu steuern: width und height. Wenn diese Attribute angegeben sind, müssen sie gültige nicht negative Ganzzahlen haben. Die Regeln für die Analyse nichtnegativer Ganzzahlen müssen verwendet werden, um ihre numerischen Werte zu erhalten. Wenn ein Attribut fehlt oder wenn das Analysieren seines Werts einen Fehler zurückgibt, muss stattdessen der Standardwert verwendet werden. Die width Attribut standardmäßig auf 300 und die height Attribut standardmäßig auf 150.

+4

in der Tat .. Ich dachte immer, direkte Attribute wie „Breite“ und „Höhe“ wurden als veraltet in den letzten html-Versionen .. – Sirber

+4

Oh, anscheinend ist es tatsächlich ziemlich gut beschrieben bei http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#attr-canvas- Breite (Abschnitt '# attr-canvas-width'). Das Problem ist, dass ich vorher die falsche "Breite" angeklickt habe und stattdessen zum Abschnitt "# dom-canvas-width" gegangen bin. Gespeichert http://www.w3.org/Bugs/Public/show_bug.cgi?id=9469 darüber. – SamB

+1

hast du mir schreckliche Kopfschmerzen erspart .... Danke! – nurxyz

33

Zur Einstellung der width und height Sie benötigen, können Sie

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

+1 'el.setAttribute ('width', parseInt ($ el.css ('width')))' hat den Trick gemacht, danke – Shanimal

+4

Was ist, wenn ich möchte, dass meine Leinwand eine relative Größe hat? Das heißt, wie man eine 'Breite: 100%;' CSS-Eigenschaft nachahmt? – Maxbester

+1

Große Antwort, aber vergessen Sie nicht, das canvasObject.setAttribute ('height', '123') auch hinzuzufügen! –

13

Die Leinwand gespannt wird verwenden können, wenn Sie die Breite eingestellt und Höhe in Ihrem CSS. Wenn Sie die Dimension der Leinwand dynamisch manipulieren Sie JavaScript zu verwenden, haben in etwa so:

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

Großartig! Danke für diese Antwort. Ich musste 'canvas.setAttribute' vor 'canvas.getContext ('2d')' setzen, um das Bild nicht zu strecken. – hhh

17

Für <canvas> Elemente setzen die CSS-Regeln für width und height die tatsächliche Größe des Canvas-Element, das gezogen werden wird Die Seite. Auf der anderen Seite legen die HTML-Attribute width und height die Größe des Koordinatensystems oder Gitters fest, das die Canvas-API verwenden soll.

Betrachten wir zum Beispiel das (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>

Sowohl die auf sie relativ zu den inneren Koordinaten des Canvas-Element gezogen gleiche Sache gemacht haben. Aber in der zweiten Leinwand wird das rote Rechteck doppelt so breit sein, weil die Leinwand insgesamt durch die CSS-Regeln über einen größeren Bereich gestreckt wird.

Hinweis: Wenn die CSS-Regeln für width und/oder height nicht angegeben sind, verwendet der Browser die HTML-Attribute, um das Element so zu skalieren, dass 1 Einheit dieser Werte 1px auf der Seite entspricht.Wenn diese Attribute nicht angegeben sind, werden sie standardmäßig auf width von 300 und height von 150 gesetzt.

+2

Schöne, klare Beschreibung von dem, was vor sich geht! – Ben

2

Der Browser verwendet die css-Breite und -Höhe, aber das canvas-Element skaliert basierend auf der Leinwandbreite und -höhe. Lesen Sie in JavaScript die CSS-Breite und -Höhe und legen Sie die Breite und Höhe des Arbeitsbereichs fest.

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

Shannimal Korrektur

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

Wenn Sie ein dynamisches Verhalten, basierend auf, zum Beispiel CSS-Medienabfragen verwenden keine Attribute für die Breite und Höhe der Leinwand. Verwenden Sie Regeln CSS und dann, bevor die Leinwand Rendering-Kontext immer, zuweisen, um Höhe und Breite an die CSS-Breite und Höhe Stile:

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

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

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

Es ist klar, dass eine Arbeitsfläche eine Standardkoordinatengröße (300 x 150) erhält, wenn Größe nur in CSS angegeben wird. Dieser Vorschlag funktioniert jedoch nicht für mich, aber die Lösung unten tut. –

+0

@PerLindberg - Diese Lösung funktioniert, wenn Sie eine CSS-Breite und -Höhe in Pixel für das Canvas-Element definiert haben. – Manolo