Płótno jest rozciągane przy użyciu CSS, ale normalne z właściwościami „szerokość” / „wysokość”

195

Mam 2 płótnach używa atrybutów HTML widthi heightwielkości to, CSS innych zastosowań:

<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 wyświetla się tak, jak powinien, ale nie compteur2. Treść jest rysowana za pomocą JavaScript na kanwie 300 x 300.

Dlaczego występuje różnica w wyświetlaniu?

alternatywny tekst

Sirber
źródło

Odpowiedzi:

216

Wygląda na to, że atrybuty widthi heightokreślają szerokość lub wysokość układu współrzędnych obszaru roboczego, podczas gdy właściwości CSS po prostu określają rozmiar pola, w którym zostanie pokazany.

Wyjaśniono to na stronie http://www.whatwg.org/html#attr-canvas-width (wymaga JS) lub http://www.whatwg.org/c#attr-canvas-width (prawdopodobnie zje twój komputer) :

canvasElement ma dwa atrybuty do kontroli rozmiaru bitmapy tego elementu: widtha height. Te atrybuty, jeśli są określone, muszą mieć wartości, które są poprawnymi nieujemnymi liczbami całkowitymi . Te zasady analizowania liczby całkowite nieujemne muszą być stosowane w celu uzyskania ich wartości liczbowych. Jeśli brakuje atrybutu lub parsowanie jego wartości zwraca błąd, należy zamiast tego użyć wartości domyślnej. Te widthwartości domyślne atrybutów do 300, i heightdomyślne atrybutów 150.

SamB
źródło
11
w rzeczy
samej
4
Och, najwyraźniej jest to właściwie dobrze opisane na whatwg.org/specs/web-apps/current-work/multipage/… (sekcja #attr-canvas-width). Problem polega na tym, że wcześniej kliknąłem źle widthi poszedłem do #dom-canvas-widthsekcji. Złożony w3.org/Bugs/Public/show_bug.cgi?id=9469 na ten temat.
SamB
3
Posiadanie interfejsu API, który wygląda podobnie, ale zasadniczo różni się od innego (szerokość css, wysokość). Łał.
Ben Aston
1
Ważne jest, aby rozróżniać je w sytuacjach, gdy wewnętrzny układ współrzędnych ma być inny. (tj. dla wyświetlaczy siatkówki lub 8-bitowej gry)
Samy Bencherif,
1
To było naprawdę mylące. My próbowaliśmy ustawić szerokość i wysokość w css. Zajęło nam 2 dni stresu związanego z ciągnięciem włosów, aby dowiedzieć się o tych 2 różnych interpretacjach dotyczących szerokości i wysokości. Po prostu wow ...
NME New Media Entertainment
39

Aby ustawić widthi heightpotrzebujesz, możesz użyć

canvasObject.setAttribute('width', '475');
fermar
źródło
6
+1 el.setAttribute('width', parseInt($el.css('width')))
załatwiło sprawę
9
Co jeśli chcę, aby moje płótno miało względny rozmiar? To znaczy, jak naśladować width: 100%;właściwość css?
Maxbester
1
Świetna odpowiedź, ale nie zapomnij również dodać canvasObject.setAttribute ('wysokość', '123')!
Tom Wells,
Nie sądzę, że musisz używać .setAttribute () Zawsze korzystałem z właściwości .width i .height
Zorgatone
4
Zwykły JavaScript (jQuery) bez wersji z wykorzystaniem getComputedStyle : canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));. Powtórz dla wysokości.
Ben J
25

W przypadku <canvas>elementów CSS reguluje widthi heightustawia rzeczywisty rozmiar elementu canvas, który zostanie narysowany na stronie. Z drugiej strony atrybuty HTML widthi heightustawia rozmiar układu współrzędnych lub „siatki”, z której będzie korzystać interfejs API canvas.

Rozważmy na przykład to ( 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>

Oba mają narysowane to samo w stosunku do wewnętrznych współrzędnych elementu canvas. Ale w drugim kanwie czerwony prostokąt będzie dwa razy szerszy, ponieważ kanwa jako całość jest rozciągana na większym obszarze zgodnie z regułami CSS.

Uwaga: Jeśli reguły CSS dla widthi / lub heightnie zostaną określone, przeglądarka użyje atrybutów HTML, aby zmienić rozmiar elementu, tak aby 1 jednostka tych wartości na stronie wynosiła 1 piks. Jeśli te atrybuty nie są wymienione, a następnie będą one domyślnie widthof 300a heightod 150.

Ben Jackson
źródło
16

Płótno zostanie rozciągnięte, jeśli ustawisz szerokość i wysokość w swoim CSS. Jeśli chcesz dynamicznie manipulować wymiarem płótna, musisz użyć JavaScript w następujący sposób:

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
Niebieski deszcz
źródło
1
Wspaniały! Dziękuję za tę odpowiedź. Musiałem postawić canvas.setAttributewcześniej, canvas.getContext('2d')aby uniknąć rozciągania obrazu.
hhh
6

Przeglądarka używa szerokości i wysokości css, ale element canvas jest skalowany w oparciu o szerokość i wysokość canvas. W javascript przeczytaj szerokość i wysokość css i ustaw do tego szerokość i wysokość płótna.

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();
Russell Harkins
źródło
2

Korekta shannimal

var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))
XaviGuardia
źródło
0

CSS ustawia szerokość i wysokość elementu canvas, więc wpływa na przestrzeń współrzędnych, pozostawiając wszystko rysowane pochylone

Oto mój sposób na ustawienie szerokości i wysokości za pomocą Vanilla JavaScript

canvas.width = numberForWidth

canvas.height = numberForHeight
Anthony Gedeon
źródło
-1

Jeśli chcesz dynamicznego zachowania opartego np. Na zapytaniach o media CSS, nie używaj atrybutów szerokości i wysokości obszaru roboczego. Użyj reguł CSS, a następnie, przed uzyskaniem kontekstu renderowania na płótnie, przypisz atrybutom szerokość i wysokość style szerokości i wysokości CSS:

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

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

var ctx1 = elem.getContext("2d");
...
Manolo
źródło
Oczywiste jest, że obszar roboczy otrzyma domyślny rozmiar współrzędnych (300 x 150), jeśli rozmiar jest określony tylko w CSS. Jednak ta sugestia nie działa dla mnie, ale poniższe rozwiązanie działa.
Per Lindberg
@PerLindberg - To rozwiązanie działa, jeśli dla elementu canvas zdefiniowano szerokość i wysokość CSS w pikselach.
Manolo