Leinwandbreite und -höhe in HTML5


181

Ist es möglich, die Breite und Höhe eines HTML5- canvasElements festzulegen ?

Der übliche Weg ist der folgende:

<canvas id="canvas" width="300" height="300"></canvas>

Antworten:


379

Die canvasDOM - Element hat , .heightund .widthEigenschaften , die entsprechen den height="…"und width="…"Attributen. Setzen Sie sie im JavaScript-Code auf numerische Werte, um die Größe Ihrer Zeichenfläche zu ändern. Beispielsweise:

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width  = 800;
canvas.height = 600;

Beachten Sie, dass dies die Leinwand löscht, obwohl Sie mit folgen sollten ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height); , um die Browser zu behandeln, die die Zeichenfläche nicht vollständig löschen. Sie müssen alle Inhalte neu zeichnen, die nach der Größenänderung angezeigt werden sollen.

Es sei weiter bemerkt , dass die Höhe und Breite sind die logische Leinwand Maße verwenden zum Ziehen und ist verschieden von den style.heightund style.widthCSS Attributen. Wenn Sie die CSS-Attribute nicht festlegen, wird die intrinsische Größe der Zeichenfläche als Anzeigegröße verwendet. Wenn Sie die CSS-Attribute festlegen und diese sich von den Canvas-Abmessungen unterscheiden, wird Ihr Inhalt im Browser skaliert. Beispielsweise:

// Make a canvas that has a blurry pixelated zoom-in
// with each canvas pixel drawn showing as roughly 2x2 on screen
canvas.width  = 400;
canvas.height = 300; 
canvas.style.width  = '800px';
canvas.style.height = '600px';

Sehen Sie sich dieses Live-Beispiel einer Leinwand an, die um das Vierfache vergrößert wird.


1
@Hazaart Wenn Sie sie anders festlegen möchten: $('#mycanvas').attr({width:400,height:300}).css({width:'800px',height:'600px'});Wenn die visuelle Größe der Pixelgröße entsprechen soll, legen Sie niemals die Stile, sondern nur die Attribute fest.
Phrogz

1
"Wenn Sie möchten, dass die visuelle Größe mit der Pixelgröße übereinstimmt, legen Sie niemals die Stile, sondern nur die Attribute fest", gibt es einen Grund für diese Einstellung? Wenn ich viele Objekte auf der Leinwand habe und zoomin / zoomout möchte, wäre es viel schneller, nur das CSS zurückzusetzen, nein? (Anstatt alle Objekte zu durchlaufen) ...
EnglishAdam

3
@Gamemorize: Durch Zoomen über CSS wird es verschwommen. Sie können jedoch über Kontextskalierung und Übersetzung zwischen dem Neuzeichnen zoomen, anstatt die Größe jedes Objekts zu ändern.
Phrogz

1
Vielen Dank. Ich sehe jetzt, was CSS tut ... es behandelt die Leinwand "wie" ein Bild, das Skalieren eines Bildes ist offensichtlich nicht so gut wie das "Neuzeichnen"!
EnglishAdam

3
Außerdem können Sie jetzt "pixeliges Vergrößern löschen" anstelle von "verschwommenes pixeliges Vergrößern" ausführen, zumindest in Chrome, indem Sie den Stil "Bildwiedergabe: pixeliert" auf der Leinwand verwenden. Ich habe an Ihrer Geige herumgespielt
Don Hatch

62

Eine Leinwand hat zwei Größen, die Größe der Pixel in der Leinwand (Backingstore oder DrawingBuffer) und die Anzeigegröße. Die Anzahl der Pixel wird mithilfe der Canvas-Attribute festgelegt. In HTML

<canvas width="400" height="300"></canvas>

Oder in JavaScript

someCanvasElement.width = 400;
someCanvasElement.height = 300;

Davon getrennt sind die Breite und Höhe des CSS-Stils der Leinwand

In CSS

canvas {  /* or some other selector */
   width: 500px;
   height: 400px;
}

Oder in JavaScript

canvas.style.width = "500px";
canvas.style.height = "400px";

Der wohl beste Weg, eine Leinwand mit 1x1 Pixel zu erstellen, besteht darin, IMMER CSS zu verwenden zu verwenden, um die Größe auszuwählen, und dann ein kleines Stück JavaScript zu schreiben, damit die Anzahl der Pixel dieser Größe entspricht.

function resizeCanvasToDisplaySize(canvas) {
   // look up the size the canvas is being displayed
   const width = canvas.clientWidth;
   const height = canvas.clientHeight;

   // If it's resolution does not match change it
   if (canvas.width !== width || canvas.height !== height) {
     canvas.width = width;
     canvas.height = height;
     return true;
   }

   return false;
}

Warum ist das der beste Weg? Weil es in den meisten Fällen funktioniert, ohne dass Code geändert werden muss.

Hier ist eine vollständige Fensterfläche:

Und hier ist eine Leinwand als Float in einem Absatz

Hier ist eine Leinwand in einem großen Bedienfeld

Hier ist eine Leinwand als Hintergrund

Da ich die Attribute nicht festgelegt habe, hat sich in jedem Beispiel nur das CSS geändert (was die Zeichenfläche betrifft).

Anmerkungen:

  • Setzen Sie keine Ränder oder Auffüllungen auf ein Canvas-Element. Das Berechnen der Größe zum Subtrahieren von der Anzahl der Dimensionen des Elements ist mühsam

Beste Antwort, dieses Snippet sollte eine Standard-DOM-Canvas-Methode sein.
Rustypaper

23

Vielen Dank! Schließlich habe ich das Problem mit unscharfen Pixeln mit diesem Code gelöst:

<canvas id="graph" width=326 height=240 style='width:326px;height:240px'></canvas>

Mit dem Hinzufügen des 'halben Pixels' wird der Trick gelöst, um Linien zu verwischen.


26
@UpTheCreek Wenn Sie eine Linie in der Leinwand zeichnen, sieht sie besser aus, als wenn sie unscharf wäre. Wenn Sie die Linien auf halbe Pixel setzen (z. B. 50,5 statt 50), erhalten Sie eine schöne, saubere Linie. Dies geschieht häufig mit ctx.translate (0.5, 0.5) ganz am Anfang Ihres Codes, damit Sie es später vergessen können
Johan

-2

Der beste Weg, es zu tun:

<canvas id="myChart" style="height: 400px; width: 100px;"></canvas>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.