HTML5 Canvas% 100 Genişlik Viewport Yüksekliği?


151

Görünümün genişliği ve yüksekliğinin% 100'ünü kaplayan bir tuval öğesi oluşturmaya çalışıyorum.

Benim örnekte görebileceğiniz burada ancak Chrome ve Firefox hem de kaydırma çubukları ekleyerek olur gerçekleşiyor. Ekstra kaydırma çubuklarını nasıl önleyebilirim ve sadece pencerenin genişliğini ve yüksekliğini tuvalin boyutu olarak nasıl sağlayabilirim?



Bana oldukça eğlenceli bir Fonejacker
Francis Booth

Yanıtlar:


258

Tuvali tam ekran genişliği ve yüksekliğini her zaman yapmak için, yani tarayıcı yeniden boyutlandırıldığında bile, çizim döngünüzü tuvali pencereye yeniden boyutlandıran bir işlev içinde çalıştırmanız gerekir.

Örnek: http://jsfiddle.net/jaredwilli/qFuDr/

HTML

<canvas id="canvas"></canvas>

JavaScript

(function() {
    var canvas = document.getElementById('canvas'),
            context = canvas.getContext('2d');

    // resize the canvas to fill browser window dynamically
    window.addEventListener('resize', resizeCanvas, false);

    function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;

            /**
             * Your drawings need to be inside this function otherwise they will be reset when 
             * you resize the browser window and the canvas goes will be cleared.
             */
            drawStuff(); 
    }
    resizeCanvas();

    function drawStuff() {
            // do your drawing stuff here
    }
})();

CSS

* { margin:0; padding:0; } /* to remove the top and left whitespace */

html, body { width:100%; height:100%; } /* just to be sure these are full screen*/

canvas { display:block; } /* To remove the scrollbars */

Tuvali tam olarak tarayıcının tam genişliğini ve yüksekliğini bu şekilde yaparsınız. Çizim için tüm kodu drawStuff () işlevinde tuvale koymanız yeterlidir.


2
Dolguyu çıkarmak ve genişliği, yüksekliği% 100 olarak ayarlamak neden gereklidir?
Kos

3
Ben esas olarak tarayıcının varsayılanları olan kullanıcı stil sayfasını geçersiz kılmak için olduğuna inanıyorum. Bir çeşit normalleştirme veya sıfırlama css dosyası kullanıyorsanız, bu zaten halledileceğinden bu gerekli değildir.
jaredwilli

2
Çok fazla yeniden boyutlandırma bekliyorsanız; örneğin bir dikey / yatay cihazda debounce, yeniden boyutlandırmak istersiniz, aksi takdirde tarayıcıyı taşarsınız.
dooburt

24
display: block: Bu yalnızca kaydırma çubuklarını kaldırmakla kalmaz, normalde bir blok içindeki metin satırlarının altına eklenen belge gövdesinin yüksekliğinden 2 piksel çıkarır. Bunun için +1
Neptilo

2
artı bir jQuery için
Félix Gagnon-Grenier

26

Görüntü birimi birimlerini (CSS3) deneyebilirsiniz :

canvas { 
  height: 100vh; 
  width: 100vw; 
  display: block;
}

5
Ekle display: block;ve işi yapar.
superlukas

18
Bunu denedim ve Chrome ve Firefox'ta, tuvalin tam görünüm penceresine uzanan resmi gösterdiğini buldum. Yeni çekilmiş elemanlar bile gerilir.
Vivian River

8
@Daniel haklı - bu cevap yanlış . Tuval bağlamının iç boyutunu değil, DOM öğesinin boyutlarını ayarlar. Fark için, ilgili soruya cevabım bakın .
Dan Dascalescu

19
Bu yöntem işe yaramaz, metni uzatır. Maalesef JS kullanmak zorundasınız .
i336_

16

Pencere yeniden boyutlandırıldığında tuvalin dinamik olarak nasıl uyarlanacağına dair daha genel soruyu cevaplayacağım. Kabul edilen cevap, genişliğin ve yüksekliğin her ikisinin de% 100 olması gerektiği, bu da istenen kanvasın en boy oranını değiştireceği durumu uygun şekilde ele alır. Birçok kullanıcı, en boy oranına dokunmadan tuvalin yeniden boyutlandırılmasında yeniden boyutlandırılmasını isteyecektir. Bu tam bir soru değil, ama soruyu biraz daha genel bir bağlama sokarak "uyuyor".

Pencerenin bir en boy oranı (genişlik / yükseklik) ve tuval nesnesi de olacaktır. Bu iki en-boy oranının birbiriyle ilişkisini nasıl istediğinizi açıklığa kavuşturmanız gereken bir şey var, bu soruya "tek beden herkese uyar" diye bir cevap yok - Neler yapabileceğinize dair bazı genel durumlardan geçeceğim istemek.

Açık olmanız gereken en önemli şey: html canvas nesnesinin bir width özelliği ve height özelliği vardır; ve sonra aynı nesnenin css'si de bir width ve height özelliğine sahiptir. Bu iki genişlik ve yükseklik farklıdır, ikisi de farklı şeyler için yararlıdır.

Genişlik ve yükseklik özelliklerini değiştirmek, tuvalinizin boyutunu her zaman değiştirebileceğiniz bir yöntemdir, ancak daha sonra her şeyi yeniden boyamanız gerekir, bu da zaman alır ve her zaman gerekli değildir, çünkü başarabileceğiniz bir miktar boyut değişikliği css öznitelikleri aracılığıyla, bu durumda tuvali yeniden çizmezsiniz.

Pencere yeniden boyutlandırmasında olmasını isteyebileceğiniz 4 durum görüyorum (tümü tam ekran tuval ile başlıyor)

1: genişliğin% 100 kalmasını ve en boy oranının olduğu gibi kalmasını istiyorsunuz. Bu durumda, tuvali yeniden çizmenize gerek yoktur; bir pencere yeniden boyutlandırma işleyicisine bile ihtiyacınız yoktur. Tum ihtiyacin olan sey

$(ctx.canvas).css("width", "100%");

Burada ctx tuval ortamınızdır. keman: resize

2: genişlik ve yüksekliğin her ikisinin de% 100 kalmasını istiyorsunuz ve en boy oranındaki değişimin, uzatılmış bir görüntü efekti olmasını istiyorsunuz. Şimdi, tuvali yeniden çizmeniz gerekmiyor, ancak bir pencere yeniden boyutlandırma işleyicisine ihtiyacınız var. İşleyicide,

$(ctx.canvas).css("height", window.innerHeight);

keman: messWithAspectratio

3: genişlik ve yüksekliğin% 100 kalmasını istiyorsunuz, ancak en boy oranındaki değişimin cevabı görüntüyü uzatmaktan farklı bir şey. Sonra yeniden çizmeniz ve kabul edilen cevapta özetlenen şekilde yapmanız gerekir.

keman: redraw

4: genişlik ve yüksekliğin sayfa yükünde% 100 olmasını istiyorsunuz, ancak daha sonra sabit kalın (pencere yeniden boyutlandırmasına tepki yok).

keman: sabit

Modun ayarlandığı satır 63 dışındaki tüm kemanlar aynı koda sahiptir. Yerel makinenizde çalıştırmak için keman kodunu da kopyalayabilirsiniz; bu durumda, modu bir sorgu dizesi bağımsız değişkeni ile? Mode = redraw olarak seçebilirsiniz.


1
fyi: $(ctx.canvas).css("width", "100%");eşdeğerdir $(canvas).css("width", "100%"); (bağlamın tuvali sadece tuvaldir)
Brad Kent

@BradKent istediğiniz "tuval-şeyleri" yapan bir yardımcı fonksiyon çağırdığınızda, argüman (lar) olarak 1) tuval nesnesini, 2) tuval içeriğini, 3) her ikisini de geçebilirsiniz. 3'ü sevmiyorum) ve ctx.canvasbundan çok daha kısa canvas.getContext('2d')- bu yüzden 2 yapıyorum). Bu nedenle, tuval denilen bir değişken yoktur, ancak ctx.canvas vardır. Ctx.canvas buradan geliyor.
mathheadinclouds

9

http://jsfiddle.net/mqFdk/10/

<!DOCTYPE html>
<html>
<head>
    <title>aj</title>
</head>
<body>

    <canvas id="c"></canvas>

</body>
</html>

CSS ile

body { 
       margin: 0; 
       padding: 0
     }
#c { 
     position: absolute; 
     width: 100%; 
     height: 100%; 
     overflow: hidden
   }

Bu çalışır, ancak tuvalimi tanımlanmış bir genişlik ve yükseklik olmadan bırakır. Tuval genişliği ve yüksekliği inandığım elemanda tanımlanmalıdır.
aherrick

@aherrick: Hayır, tuval öğesinin çalışması için açık bir genişlik / yükseklik ayarlamanız gerekmez. Bu kod düzgün çalışmalıdır.
Jon Adams

18
Aslında evet, kanvas elemanlarının açık bir genişlik / yükseklik ayarına ihtiyacı vardır. Bu olmadan onlar varsayılan bazı tarayıcı ön ayarlı (krom, sanırım 300x150 piksel) boyutu. Tuvale yapılan tüm çizimler bu boyutta yorumlanır ve daha sonra görünüm alanı boyutunun% 100'üne ölçeklenir. Ne demek istediğimi görmek için tuvalinizde bir şey çizmeyi deneyin - çarpılacak.
Mark Kahn

Tuvali% 100 genişlik ve yükseklik yapmaya çalışıyorsanız, bu hiç önemli değil. sadece yeniden boyutlandırmak
jaredwilli

1
Tuval öğesinin iç boyutları, CSS piksellerinde yorumlanan sayılarla koordinat alanının boyutuna eşittir. Ancak, öğe rastgele bir stil sayfası ile boyutlandırılabilir. Oluşturma sırasında, görüntü bu düzen boyutuna sığacak şekilde ölçeklendirilir.
jaredwilli

8

Ben de bu sorunun cevabını bulmak istiyordum ama kabul edilen cevap benim için kırılıyordu. Görünüşe göre window.innerWidth kullanmak taşınabilir değil. Bazı tarayıcılarda çalışıyor, ancak Firefox'un beğenmediğini fark ettim.

Gregg Tavares, bu sorunu doğrudan ele alan harika bir kaynak yayınladı: http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (Bkz. Anti-desen # 3 ve 4).

Window.innerWidth yerine canvas.clientWidth kullanımı iyi çalışıyor.

İşte Gregg'in önerilen render döngüsü:

function resize() {
  var width = gl.canvas.clientWidth;
  var height = gl.canvas.clientHeight;
  if (gl.canvas.width != width ||
      gl.canvas.height != height) {
     gl.canvas.width = width;
     gl.canvas.height = height;
     return true;
  }
  return false;
}

var needToRender = true;  // draw at least once
function checkRender() {
   if (resize() || needToRender) {
     needToRender = false;
     drawStuff();
   }
   requestAnimationFrame(checkRender);
}
checkRender();

2

(動靜 能量 cevabını genişleterek)

Tuvali vücudu doldurmak için şekillendirin. Tuval üzerine render yaparken boyutunu dikkate alın.

http://jsfiddle.net/mqFdk/356/

<!DOCTYPE html>
<html>
<head>
    <title>aj</title>
</head>
<body>

    <canvas id="c"></canvas>

</body>
</html>

CSS:

body { 
       margin: 0; 
       padding: 0
     }
#c { 
     position: absolute; 
     width: 100%; 
     height: 100%; 
     overflow: hidden
   }

JavaScript:

function redraw() {
    var cc = c.getContext("2d");
    c.width = c.clientWidth;
    c.height = c.clientHeight;
    cc.scale(c.width, c.height);

    // Draw a circle filling the canvas.
    cc.beginPath();
    cc.arc(0.5, 0.5, .5, 0, 2*Math.PI);
    cc.fill();
}

// update on any window size change.
window.addEventListener("resize", redraw);

// first draw
redraw();

1

Cep telefonları için kullanmak daha iyidir

canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;

Bu orientation.The “görünüm” değiştirdikten sonra hatalı gösterecektir, çünkü portrait.See tam yönünü değiştirirken artırılacaktır örneğin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.