Thay đổi kích thước canvas HTML5 để phù hợp với cửa sổ


400

Làm cách nào tôi có thể tự động chia tỷ lệ thành <canvas>phần HTML5 để phù hợp với trang?

Ví dụ: tôi có thể lấy <div>tỷ lệ bằng cách đặt các thuộc tính heightwidth100%, nhưng <canvas>tỷ lệ sẽ không?


7
tại sao canvas {width: 100%; height: 100%} không hoạt động?
zloctb

28
@zloctb - Điều đó sẽ mở rộng khung vẽ trực tiếp, giúp kéo dài hình ảnh của bạn.
Derek 朕 會

8
Xem Nguyên tắc cơ bản của WebGL để được giải thích chi tiết về những gì và không nên làm cho các vấn đề liên quan.
huyền thoại2k

2
Một khung vẽ cũng sẽ có tỷ lệ tốt, chỉ cần thêm css {width: 100%}, tuy nhiên nội dung của nó sẽ không hoàn toàn là vấn đề nữa!
ejectamenta

Câu trả lời:


372

Tôi tin rằng tôi đã tìm thấy một giải pháp tao nhã cho việc này:

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;
}

Cho đến nay, không có bất kỳ tác động tiêu cực lớn nào đối với tôi.


7
Bạn có thể phải vô hiệu hóa ký quỹ vớibody, html { margin: 0px;}
Nicklas A.

45
Đây có phải là thích nghe sự kiện thay đổi kích thước?
Eric

25
@Elisabeth: Để thoát khỏi thanh cuộn, hãy thêm "overflow: hidden" vào kiểu của các phần tử html và phần thân. Xem thefutureoftheweb.com/blog/100-percent-height-interface
Denis Washington

17
Tôi đã làm điều này cộng với tôi cũng đặt canvas để hiển thị: block (dường như được mặc định là display: inline đang tạo thêm không gian!).
Elisabeth

15
Đây có thể là một mô hình chống; xem mục thứ ba ở đây để biết lý do và biện pháp khắc phục.
huyền thoại2k

67

Các giải pháp sau đây làm việc cho tôi tốt nhất. Vì tôi còn khá mới đối với tiền mã hóa, tôi muốn có xác nhận trực quan rằng một cái gì đó đang hoạt động theo cách tôi mong đợi. Tôi tìm thấy nó tại trang web sau: http://htmlcheats.com/html/resize-the-html5-canvas-dyamical/

Đây là mã:

<!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>

Đường viền màu xanh hiển thị cho bạn cạnh của khung vẽ thay đổi kích thước và luôn nằm dọc theo cạnh của cửa sổ, hiển thị ở cả 4 mặt, điều này KHÔNG phải là trường hợp đối với một số câu trả lời khác ở trên. Hy vọng nó giúp.


Câu trả lời này đã giải quyết vấn đề của tôi. Các overflow: hiddendisplay: blocklà những gì đã mất tích đối với tôi để làm việc này đúng cách.
Deathicon

1
Liên kết bị hỏng
Nic Scozzaro

22

Về cơ bản những gì bạn phải làm là liên kết sự kiện onresize với cơ thể của bạn, một khi bạn bắt được sự kiện, bạn chỉ cần thay đổi kích thước khung vẽ bằng window.innerWidth và window.innerHeight.

<!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
Bạn chỉ có thể sử dụng một người nghe sự kiện.
David Corbin

Điều này có lề và hiển thị thanh cuộn, cộng với việc bạn phải thay đổi kích thước màn hình trước khi nó làm bất cứ điều gì.
ArtOfWarfare

Điều gì xảy ra nếu khung vẽ lớn hơn khung nhìn (khi làm cho khung nhìn hẹp hơn hoặc ngắn hơn)? Giải pháp này dường như không xử lý được điều đó.
Lars Gyrup Brink Nielsen

@ArtOfWarfare câu hỏi ban đầu không đề cập bất cứ điều gì về phong cách. Nhưng bạn có thể cách điệu nó với css và loại bỏ lề và ẩn các thanh cuộn nếu bạn thích. Và bạn chỉ đơn giản có thể thêm `<body onload =" resize_canvas () ">` sau đó khi tải trang sau đó thay đổi kích thước canvas.
Equiman

@LayZee câu hỏi ban đầu saya bout quy mô canvas để phù hợp với trang , không phải là một khung nhìn. Đó có thể là một câu hỏi khác.
Equiman

19

Đặt chiều rộng và chiều cao không gian tọa độ canvas dựa trên kích thước của trình duyệt yêu cầu bạn thay đổi kích thước và vẽ lại bất cứ khi nào trình duyệt được thay đổi kích thước.

Một giải pháp ít phức tạp hơn là duy trì kích thước có thể vẽ trong các biến Javascript, nhưng đặt kích thước canvas dựa trên kích thước screen.ference, screen.height. Sử dụng CSS để phù hợp:

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

Cửa sổ trình duyệt thường sẽ không bao giờ lớn hơn màn hình (trừ trường hợp độ phân giải màn hình bị sai, vì nó có thể là với màn hình kép không khớp), vì vậy nền sẽ không hiển thị và tỷ lệ pixel sẽ không thay đổi. Các pixel canvas sẽ tỷ lệ thuận với độ phân giải màn hình trừ khi bạn sử dụng CSS để chia tỷ lệ canvas.


7
Thay đổi kích thước canvas với CSS là rắc rối. Ít nhất là trên Chrome và Safari, các vị trí sự kiện chuột / chạm sẽ không tương ứng 1: 1 với các vị trí pixel canvas và bạn sẽ phải chuyển đổi các hệ tọa độ.
jerseyboy

14

Một cách tiếp cận CSS thuần túy thêm vào giải pháp của @jerseyboy ở trên.
Hoạt động trong Firefox (được thử nghiệm trong v29), Chrome (được thử nghiệm trong v34) và Internet Explorer (được thử nghiệm trong v11).

<!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>

Liên kết với ví dụ: http://temporaer.net/open/so/140502_canvas-fit-to-window.html

Nhưng hãy cẩn thận, như @jerseyboy nói trong bình luận của mình:

Thay đổi kích thước canvas với CSS là rắc rối. Ít nhất là trên Chrome và Safari, các vị trí sự kiện chuột / chạm sẽ không tương ứng 1: 1 với các vị trí pixel canvas và bạn sẽ phải chuyển đổi các hệ tọa độ.


5
Cách CSS kéo dài khung vẽ, do đó hình ảnh được hiển thị sẽ được kéo dài. Điều này là không tốt so với thay đổi kích thước vải. Với một chút điều chỉnh, câu trả lời của Craig hoạt động tốt nhất.
Naya

Tôi thích giải pháp này vì điều này làm cho canvas 100% dựa trên chiều rộng cha mẹ.
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);

Thật tuyệt, khi tỷ lệ này rất quan trọng
sarkiroka 18/03/2016

8

Trừ khi bạn muốn khung vẽ tự động nâng cấp dữ liệu hình ảnh của bạn (đó là câu trả lời của James Black, nhưng nó sẽ không đẹp), bạn phải tự thay đổi kích thước và vẽ lại hình ảnh. Trung tâm một bức tranh


4

Nếu div của bạn hoàn toàn lấp đầy trang web thì bạn có thể điền vào div đó và do đó, có một khung vẽ lấp đầy div.

Bạn có thể thấy điều này thú vị, vì bạn có thể cần sử dụng css để sử dụng tỷ lệ phần trăm, nhưng, nó phụ thuộc vào trình duyệt bạn đang sử dụng và mức độ phù hợp với thông số: http://www.whatwg.org/ thông số kỹ thuật / ứng dụng web / công việc hiện tại / bội số / the-canvas-Element.html # the-canvas-Element

Kích thước nội tại của phần tử canvas bằng kích thước của không gian tọa độ, với các số được diễn giải bằng pixel CSS. Tuy nhiên, phần tử có thể được kích thước tùy ý bằng một biểu định kiểu. Trong quá trình kết xuất, hình ảnh được thu nhỏ để phù hợp với kích thước bố cục này.

Bạn có thể cần lấy offsetWidth và chiều cao của div hoặc lấy chiều cao / chiều rộng của cửa sổ và đặt giá trị đó làm giá trị pixel.


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

Nếu bạn quan tâm đến việc duy trì tỷ lệ khung hình và thực hiện điều đó bằng CSS thuần túy (với tỷ lệ khung hình), bạn có thể làm điều gì đó như dưới đây. Điều quan trọng là padding-bottomtrên ::contentyếu tố rằng kích thước của containerphần tử. Đây là kích thước tương ứng với chiều rộng của cha mẹ, 100%theo mặc định. Tỷ lệ được chỉ định ở đây phải khớp với tỷ lệ kích thước trên canvasphần tử.

// 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

Sử dụng jQuery, bạn cũng có thể theo dõi thay đổi kích thước cửa sổ và thay đổi độ rộng của khung vẽ bằng jQuery.

Một cái gì đó như thế

$( 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

Tôi nghĩ rằng đây là những gì chúng ta nên làm chính xác: 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

Tôi đang sử dụng sketch.js vì vậy sau khi tôi chạy lệnh init cho khung vẽ, tôi thay đổi chiều rộng và chiều cao bằng jquery. Nó dựa trên các kích thước của phần tử cha.

$ ('# DrawCanvas'). Sketch (). Attr ('height', $ ('# DrawCanvas'). Parent (). Height ()). Attr ('width', $ ('# DrawCanvas'). ().chiều rộng());

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.