HTML5 tuvalini pencereye sığacak şekilde yeniden boyutlandırma


400

HTML5 <canvas>öğesini sayfaya sığacak şekilde otomatik olarak nasıl ölçekleyebilirim ?

Örneğin <div>, heightve widthözelliklerini% 100 olarak ayarlayarak ölçeklendirmeyi alabilirim , ancak <canvas>ölçeklenmeyecek mi?


7
neden kanvas {genişlik:% 100; yükseklik:% 100} çalışmıyor?
zloctb

28
@zloctb - Bu, tuvali doğrudan ölçeklendirir ve görüntünüzü uzatır.
Derek 朕 會 功夫

8
İlgili konular için ne yapılacağı ve ne yapılamayacağı hakkında ayrıntılı bir açıklama için WebGL Temelleri bölümüne bakın .
legends2k

2
Bir tuval de iyi ölçeklendirilir, sadece css {width: 100%} 'i ekleyin, ancak içeriği olmayacaktır, bu tamamen başka bir konudur!
ejectamenta

Yanıtlar:


372

Buna zarif bir çözüm bulduğuma inanıyorum:

JavaScript

/* important! for alignment, you should make things
 * relative to the canvas' current width/height.
 */
function draw() {
  var ctx = (a canvas context);
  ctx.canvas.width  = window.innerWidth;
  ctx.canvas.height = window.innerHeight;
  //...drawing code...
}

CSS

html, body {
  width:  100%;
  height: 100%;
  margin: 0;
}

Şimdiye kadar benim için büyük bir olumsuz performans etkisi olmadı.


7
Muhtemelen marjı devre dışı body, html { margin: 0px;}
bırakmanız gerekir

45
Bu, yeniden boyutlandırma etkinliğini dinlemeyi tercih ediyor mu?
Eric

25
@Elisabeth: Kaydırma çubuklarından kurtulmak için, html ve gövde öğelerinin stiline "taşma: gizli" ifadesini ekleyin. Bkz thefutureoftheweb.com/blog/100-percent-height-interface
Denis Washington

17
Bunu yaptım ve ayrıca tuvali görüntülemek için ayarladım: blok (görüntülemek için varsayılan gibi görünüyordu: ekstra alan yaratan satır içi!).
Elisabeth

15
Bu bir anti-desen olabilir; Nedeni ve çözümü için buradaki üçüncü maddeye bakın .
legends2k

67

Aşağıdaki çözüm benim için en iyisi oldu. Kodlama konusunda nispeten yeni olduğum için, bir şeyin beklediğim gibi çalıştığına dair görsel onay almayı seviyorum. Aşağıdaki sitede buldum: http://htmlcheats.com/html/resize-the-html5-canvas-dyamically/

İşte kod:

<!DOCTYPE html>

<head>
    <meta charset="utf-8">
    <title>Resize HTML5 canvas dynamically | www.htmlcheats.com</title>
    <style>
    html, body {
      width: 100%;
      height: 100%;
      margin: 0px;
      border: 0;
      overflow: hidden; /*  Disable scrollbars */
      display: block;  /* No floating content on sides */
    }
    </style>
</head>

<body>
    <canvas id='c' style='position:absolute; left:0px; top:0px;'>
    </canvas>

    <script>
    (function() {
        var
        // Obtain a reference to the canvas element using its id.
        htmlCanvas = document.getElementById('c'),
        // Obtain a graphics context on the canvas element for drawing.
        context = htmlCanvas.getContext('2d');

       // Start listening to resize events and draw canvas.
       initialize();

       function initialize() {
           // Register an event listener to call the resizeCanvas() function 
           // each time the window is resized.
           window.addEventListener('resize', resizeCanvas, false);
           // Draw canvas border for the first time.
           resizeCanvas();
        }

        // Display custom canvas. In this case it's a blue, 5 pixel 
        // border that resizes along with the browser window.
        function redraw() {
           context.strokeStyle = 'blue';
           context.lineWidth = '5';
           context.strokeRect(0, 0, window.innerWidth, window.innerHeight);
        }

        // Runs each time the DOM window resize event fires.
        // Resets the canvas dimensions to match window,
        // then draws the new borders accordingly.
        function resizeCanvas() {
            htmlCanvas.width = window.innerWidth;
            htmlCanvas.height = window.innerHeight;
            redraw();
        }
    })();

    </script>
</body> 
</html>

Mavi kenarlık, yeniden boyutlandırma tuvalinin kenarını gösterir ve her zaman pencerenin kenarı boyunca, 4 tarafında da görülebilir, bu da yukarıdaki diğer cevapların bazıları için geçerli DEĞİLDİR. Umarım yardımcı olur.


Bu cevap sorunumu çözdü. overflow: hiddenVe display: blockbana doğru bu çalışma almak için eksik olan budur.
Deathicon

1
Bağlantı koptu
Nic Scozzaro

22

Temel olarak yapmanız gereken, onresize olayını vücudunuza bağlamaktır, olayı yakaladıktan sonra sadece window.innerWidth ve window.innerHeight kullanarak tuvali yeniden boyutlandırmanız gerekir.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Canvas Resize</title>

    <script type="text/javascript">
        function resize_canvas(){
            canvas = document.getElementById("canvas");
            if (canvas.width  < window.innerWidth)
            {
                canvas.width  = window.innerWidth;
            }

            if (canvas.height < window.innerHeight)
            {
                canvas.height = window.innerHeight;
            }
        }
    </script>
</head>

<body onresize="resize_canvas()">
        <canvas id="canvas">Your browser doesn't support canvas</canvas>
</body>
</html>

1
Bir olay dinleyicisi kullanabilirsiniz.
David Corbin

Bunun kenar boşlukları vardır ve kaydırma çubukları gösterir, ayrıca herhangi bir şey yapmadan önce ekranı yeniden boyutlandırmanız gerekir.
ArtOfWarfare

Tuval görünüm penceresinden daha büyükse (görünüm alanını daha dar veya daha kısa yaparken)? Bu çözüm bununla başa çıkmıyor gibi görünüyor.
Lars Gyrup Brink Nielsen

@ArtOfWarfare orijinal sorular stiller hakkında hiçbir şeyden bahsetmez. Ancak css ile stilize edebilir ve kenar boşluklarını kaldırabilir ve isterseniz kaydırma çubuklarını gizleyebilirsiniz. Ve sadece <<body onload = "resize_canvas ()"> `sonra sayfa yüklendiğinde tuvali yeniden boyutlandırın.
equiman

@AYZee orijinal soru saya bout tuval bir sayfaya değil, sığacak şekilde ölçeklendirin . Bu başka bir soru olabilir.
equiman

19

Tuval koordinat alanı genişliğini ve yüksekliğini tarayıcı istemcisinin boyutlarına göre ayarlamak, tarayıcı yeniden boyutlandırıldığında yeniden boyutlandırmanızı ve yeniden çizmenizi gerektirir.

Daha az kıvrımlı bir çözüm, Javascript değişkenlerindeki çekilebilir boyutları korumak, ancak tuval boyutlarını screen.width, screen.height boyutlarına göre ayarlamaktır. Sığdırmak için CSS kullanın:

#containingDiv { 
  overflow: hidden;
}
#myCanvas {
  position: absolute; 
  top: 0px;
  left: 0px;
} 

Tarayıcı penceresi genellikle ekranın kendisinden daha büyük olmaz (ekran çözünürlüğünün yanlış bildirildiği durumlar hariç, eşleşmeyen çift monitörlerde olduğu gibi), bu nedenle arka plan görünmez ve piksel oranları değişmez. Tuvali ölçeklemek için CSS kullanmazsanız, tuval pikselleri ekran çözünürlüğü ile doğru orantılı olacaktır.


7
Tuvali CSS ile yeniden ölçeklendirmek zahmetlidir. En azından Chrome ve Safari'de, fare / dokunma etkinliği konumları tuval piksel konumlarıyla 1: 1'e karşılık gelmeyecek ve koordinat sistemlerini dönüştürmeniz gerekecek.
jerseyboy

14

Bir saf CSS yukarıdaki @jerseyboy çözümüne ekleyerek yaklaşım.
Firefox (v29'da test edilmiştir), Chrome (v34'te test edilmiştir) ve Internet Explorer'da (v11'de test edilmiştir) çalışır.

<!DOCTYPE html>
<html>
    <head>
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            margin: 0;
        }
        canvas {
            background-color: #ccc;
            display: block;
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <script>
        var canvas = document.getElementById('canvas');
        if (canvas.getContext) {
            var ctx = canvas.getContext('2d');
            ctx.fillRect(25,25,100,100);
            ctx.clearRect(45,45,60,60);
            ctx.strokeRect(50,50,50,50);
        }
    </script>
</body>
</html>

Örneğe bağlantı: http://temporaer.net/open/so/140502_canvas-fit-to-window.html

Ancak @jerseyboy'un yorumunda belirttiği gibi dikkatli olun:

Tuvali CSS ile yeniden ölçeklendirmek zahmetlidir. En azından Chrome ve Safari'de, fare / dokunma etkinliği konumları tuval piksel konumlarıyla 1: 1'e karşılık gelmeyecek ve koordinat sistemlerini dönüştürmeniz gerekecek.


5
CSS yolu tuvali uzatır, böylece oluşturulan görüntüler gerilir. Tuvali yeniden boyutlandırmaya kıyasla bu iyi değil. Küçük bir ayarlama ile Craig'in cevabı en iyi şekilde çalışır.
Nayan

Ebeveyn genişliğine göre tuvali% 100 yapan bu çözümü seviyorum.
Maihan Nijat

9
function resize() {

    var canvas = document.getElementById('game');
    var canvasRatio = canvas.height / canvas.width;
    var windowRatio = window.innerHeight / window.innerWidth;
    var width;
    var height;

    if (windowRatio < canvasRatio) {
        height = window.innerHeight;
        width = height / canvasRatio;
    } else {
        width = window.innerWidth;
        height = width * canvasRatio;
    }

    canvas.style.width = width + 'px';
    canvas.style.height = height + 'px';
};

window.addEventListener('resize', resize, false);

Oran önemli olduğunda güzel
sarkiroka

8

Tuvalin görüntü verilerinizi otomatik olarak yükseltmesini istemiyorsanız (James Black'in cevabı budur, ancak hoş görünmez), kendiniz yeniden boyutlandırmanız ve görüntüyü yeniden çizmeniz gerekir. Bir tuvali ortalamak


4

Div'niz web sayfasını tamamen doldurduysa, bu div'i doldurabilir ve div'ı dolduran bir tuvaliniz olabilir.

Yüzdeyi kullanmak için bir css kullanmanız gerekebileceğinden bunu ilginç bulabilirsiniz, ancak hangi tarayıcıyı kullandığınıza ve spesifikasyonla ne kadar uyumlu olduğuna bağlıdır: http://www.whatwg.org/ gözlük / web uygulamaları / akım-iş / multipage /-tuval-element.html #-kanvas-eleman

Tuval öğesinin gerçek 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.

Div'in offsetWidth ve yüksekliğini almanız veya pencere yüksekliğini / genişliğini almanız ve bunu piksel değeri olarak ayarlamanız gerekebilir.


3

CSS

body { margin: 0; } 
canvas { display: block; } 

JavaScript

window.addEventListener("load", function()
{
    var canvas = document.createElement('canvas'); document.body.appendChild(canvas);
    var context = canvas.getContext('2d');

    function draw()
    {
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        context.moveTo(0, 0); context.lineTo(canvas.width, canvas.height); 
        context.moveTo(canvas.width, 0); context.lineTo(0, canvas.height); 
        context.stroke();
    }
    function resize()
    {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        draw();
    }
    window.addEventListener("resize", resize);
    resize();
});

3

En boy oranlarını korumak ve saf CSS'de (en boy oranı verildiğinde) bunu yapmakla ilgileniyorsanız, aşağıdaki gibi bir şey yapabilirsiniz. Anahtarıdır padding-bottomüzerinde ::contentboyutları elemanı containerelemanı. Bu, 100%varsayılan olarak üst öğesinin genişliğine göre boyutlandırılır . Burada belirtilen oran, canvaseleman üzerindeki boyutların oranı ile eşleşmelidir .

// Javascript

var canvas = document.querySelector('canvas'),
    context = canvas.getContext('2d');

context.fillStyle = '#ff0000';
context.fillRect(500, 200, 200, 200);

context.fillStyle = '#000000';
context.font = '30px serif';
context.fillText('This is some text that should not be distorted, just scaled', 10, 40);
/*CSS*/

.container {
  position: relative; 
  background-color: green;
}

.container::after {
  content: ' ';
  display: block;
  padding: 0 0 50%;
}

.wrapper {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
}

canvas {
  width: 100%;
  height: 100%;
}
<!-- HTML -->

<div class=container>
  <div class=wrapper>
    <canvas width=1200 height=600></canvas>  
  </div>
</div>


2

JQuery kullanarak pencere yeniden boyutlandırmasını izleyebilir ve jQuery kullanarak tuvalinizin genişliğini değiştirebilirsiniz.

Bunun gibi bir şey

$( window ).resize(function() {
 		$("#myCanvas").width($( window ).width())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;">


1
(function() {

    // get viewport size
    getViewportSize = function() {
        return {
            height: window.innerHeight,
            width:  window.innerWidth
        };
    };

    // update canvas size
    updateSizes = function() {
        var viewportSize = getViewportSize();
        $('#myCanvas').width(viewportSize.width).height(viewportSize.height);
        $('#myCanvas').attr('width', viewportSize.width).attr('height', viewportSize.height);
    };

    // run on load
    updateSizes();

    // handle window resizing
    $(window).on('resize', function() {
        updateSizes();
    });

}());

0

Bence tam olarak ne yapmalıyız: http://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/

function resizeGame() {
    var gameArea = document.getElementById('gameArea');
    var widthToHeight = 4 / 3;
    var newWidth = window.innerWidth;
    var newHeight = window.innerHeight;
    var newWidthToHeight = newWidth / newHeight;

    if (newWidthToHeight > widthToHeight) {
        newWidth = newHeight * widthToHeight;
        gameArea.style.height = newHeight + 'px';
        gameArea.style.width = newWidth + 'px';
    } else {
        newHeight = newWidth / widthToHeight;
        gameArea.style.width = newWidth + 'px';
        gameArea.style.height = newHeight + 'px';
    }

    gameArea.style.marginTop = (-newHeight / 2) + 'px';
    gameArea.style.marginLeft = (-newWidth / 2) + 'px';

    var gameCanvas = document.getElementById('gameCanvas');
    gameCanvas.width = newWidth;
    gameCanvas.height = newHeight;
}

window.addEventListener('resize', resizeGame, false);
window.addEventListener('orientationchange', resizeGame, false);

-2

Tuval için init komutunu çalıştırdıktan sonra genişlik ve yüksekliği jquery ile değiştirdiğim için sketch.js kullanıyorum. Boyutları üst öğeye dayandırır.

$ ( '# DrawCanvas'). Taslak (). Attr (height, $ ( '# DrawCanvas'). Üst (). Yüksekliği ()). Attr (width, $ ( '# DrawCanvas'). Üst ().Genişlik());

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.