Die Leinwand wird bei Verwendung von CSS gestreckt, ist jedoch normal mit den Eigenschaften "Breite" / "Höhe"

194

Ich habe 2 Leinwände, eines verwendet HTML-Attribute widthund heightzur Größenanpassung verwendet das andere 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 wird wie angezeigt angezeigt, compteur2 jedoch nicht. Der Inhalt wird mit JavaScript auf einer 300 x 300-Leinwand gezeichnet.

Warum gibt es einen Anzeigeunterschied?

Alt-Text

Sirber
quelle

Antworten:

215

Es scheint, dass die Attribute widthund heightdie Breite oder Höhe des Koordinatensystems der Zeichenfläche bestimmen, während die CSS-Eigenschaften nur die Größe des Felds bestimmen, in dem es angezeigt wird.

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

Das canvasElement verfügt über zwei Attribute zur Steuerung der Größe der Bitmap des Elements: widthund height. Wenn diese Attribute angegeben werden, müssen sie Werte haben, die gültige nicht negative Ganzzahlen sind . Die Regeln zum Parsen nicht negativer Ganzzahlen müssen verwendet werden, um ihre numerischen Werte zu erhalten. Wenn ein Attribut fehlt oder wenn das Parsen seines Werts einen Fehler zurückgibt, muss stattdessen der Standardwert verwendet werden. Das widthAttribut ist standardmäßig 300 und das heightAttribut standardmäßig 150.

SamB
quelle
11
in der Tat .. Ich dachte immer, direkte Attribute wie "Breite" und "Höhe" wurden in den letzten HTML-Versionen veraltet ..
Sirber
4
Oh, anscheinend ist es tatsächlich ziemlich gut unter whatwg.org/specs/web-apps/current-work/multipage/… (Abschnitt #attr-canvas-width) beschrieben. Das Problem ist, dass ich widthvorher auf das falsche geklickt habe und stattdessen zum #dom-canvas-widthAbschnitt gegangen bin . Abgelegt w3.org/Bugs/Public/show_bug.cgi?id=9469 darüber.
SamB
3
Eine API zu haben, die aussieht, sich aber grundlegend von einer anderen unterscheidet (CSS-Breite, Höhe). Beeindruckend.
Ben Aston
1
Es ist wichtig, diese für Zeiten zu unterscheiden, in denen das interne Koordinatensystem unterschiedlich sein soll. (dh für Retina-Displays oder 8-Bit-Spiel)
Samy Bencherif
1
Das war wirklich verwirrend. Wir haben versucht, die Breite und Höhe im CSS einzustellen. Wir haben 2 Tage lang an den Haaren gezogen, um uns über diese 2 unterschiedlichen Interpretationen von Breite und Höhe zu informieren. Wow ...
NME New Media Entertainment
39

Um das einzustellen widthund heightSie benötigen, können Sie verwenden

canvasObject.setAttribute('width', '475');
Fermar
quelle
6
+1 el.setAttribute('width', parseInt($el.css('width')))hat den Trick gemacht, danke
Shanimal
9
Was ist, wenn meine Leinwand eine relative Größe haben soll? Das heißt, wie man eine width: 100%;CSS-Eigenschaft nachahmt?
Maxbester
1
Tolle Antwort, aber vergessen Sie nicht, auch das canvasObject.setAttribute ('height', '123') hinzuzufügen!
Tom Wells
Ich glaube nicht, dass Sie .setAttribute () verwenden müssen. Ich habe immer die Eigenschaften .width und .height verwendet
Zorgatone
4
Einfache JavaScript-Version (ohne jQuery) mit getComputedStyle : canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));. Wiederholen Sie dies für die Höhe.
Ben J
25

Für <canvas>Elemente regelt widthund heightlegt das CSS die tatsächliche Größe des Canvas-Elements fest, das auf die Seite gezeichnet wird. Andererseits die HTML-Attribute widthund heightdie Größe des Koordinatensystems oder 'Rasters', das von der Canvas-API verwendet wird.

Betrachten Sie zum Beispiel Folgendes ( 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>

Auf beiden wurde in Bezug auf die internen Koordinaten des Canvas-Elements dasselbe gezeichnet. In der zweiten Zeichenfläche ist das rote Rechteck jedoch doppelt so breit, da die gesamte Zeichenfläche nach den CSS-Regeln über einen größeren Bereich gespannt wird.

Hinweis: Wenn die CSS-Regeln für widthund / oder heightnicht angegeben sind, verwendet der Browser die HTML-Attribute, um das Element so zu dimensionieren, dass 1 Einheit dieser Werte 1 Pixel auf der Seite entspricht. Wenn diese Attribute nicht angegeben werden, werden standardmäßig a widthvon 300und a heightvon verwendet 150.

Ben Jackson
quelle
16

Die Leinwand wird gedehnt, wenn Sie die Breite und Höhe in Ihrem CSS festlegen. Wenn Sie die Dimension der Zeichenfläche dynamisch bearbeiten möchten, müssen Sie JavaScript wie folgt verwenden:

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
Blauer Regen
quelle
1
Toll! Danke für diese Antwort. Ich musste canvas.setAttributevorher setzen canvas.getContext('2d'), um eine Dehnung des Bildes zu vermeiden.
hhh
6

Der Browser verwendet die CSS-Breite und -Höhe, das Canvas-Element skaliert jedoch basierend auf der Canvas-Breite und -Höhe. Lesen Sie in Javascript die Breite und Höhe des CSS und stellen Sie die Breite und Höhe der Leinwand darauf ein.

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

Shannimal- Korrektur

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

CSS legt die Breite und Höhe des Canvas-Elements so fest, dass es den Koordinatenraum beeinflusst und alles gezeichnet bleibt

Hier erfahren Sie, wie Sie die Breite und Höhe mit Vanilla JavaScript einstellen

canvas.width = numberForWidth

canvas.height = numberForHeight
Anthony Gedeon
quelle
-1

Wenn Sie ein dynamisches Verhalten basierend auf z. B. CSS-Medienabfragen wünschen, verwenden Sie keine Attribute für die Breite und Höhe der Zeichenfläche. Verwenden Sie CSS-Regeln und weisen Sie dann vor dem Abrufen des Canvas-Rendering-Kontexts den Attributen width und height die CSS-Stile width und height zu:

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

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

var ctx1 = elem.getContext("2d");
...
Manolo
quelle
Es ist klar, dass eine Zeichenfläche eine Standardkoordinatengröße (300 x 150) erhält, wenn die Größe nur in CSS angegeben wird. Dieser Vorschlag funktioniert jedoch nicht für mich, aber die folgende Lösung funktioniert.
Per Lindberg
@PerLindberg - Diese Lösung funktioniert, wenn Sie für das Canvas-Element eine CSS-Breite und -Höhe in Pixel definiert haben.
Manolo