HTML5 Canvas 100% Ширина Высота области просмотра? - PullRequest
133 голосов
/ 26 ноября 2010

Я пытаюсь создать элемент canvas, который занимает 100% ширины и высоты области просмотра.

Вы можете видеть в моем примере здесь , что происходит, однако он добавляет полосы прокрутки в Chrome и FireFox.Как я могу запретить лишние полосы прокрутки и просто точно указать ширину и высоту окна в соответствии с размером холста?

Ответы [ 6 ]

239 голосов
/ 13 декабря 2011

Чтобы холст всегда был на всю ширину и высоту экрана, т. Е. Даже при изменении размера браузера, вам нужно запустить цикл рисования внутри функции, которая изменяет размер холста на window.innerHeight и window.innerWidth. *

Пример: 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 */

Именно так вы правильно сделаете холст на всю ширину и высоту браузера. Вам просто нужно поместить весь код для рисования на холст в функцию drawStuff ().

28 голосов
/ 27 мая 2013

Вы можете попробовать единицы просмотра (CSS3):

canvas { 
  height: 100vh; 
  width: 100vw; 
  display: block;
}
14 голосов
/ 03 декабря 2013

Я отвечу на более общий вопрос о том, как сделать так, чтобы холст динамически изменял размер при изменении размера окна. Принятый ответ соответствующим образом обрабатывает случай, когда ширина и высота, как предполагается, равны 100%, что и было запрошено, но это также изменит соотношение сторон холста. Многие пользователи захотят изменить размер холста при изменении размера окна, но при этом не изменяя пропорции. Это не точный вопрос, но он «вписывается», просто помещая вопрос в чуть более общий контекст.

Окно будет иметь некоторое соотношение сторон (ширина / высота), как и объект Canvas. То, как вы хотите, чтобы эти два аспектных соотношения соотносились друг с другом, - это одна вещь, о которой вы должны уяснить: нет ответа «один размер подходит всем» - я рассмотрю несколько общих случаев того, что вы можете хочу.

Самая важная вещь, о которой вы должны знать: объект HTML-холста имеет атрибут width и height; и затем CSS того же объекта также имеет атрибуты width и height. Эти две ширины и высоты разные, они полезны для разных вещей.

Изменение атрибутов ширины и высоты - это один из методов, с помощью которого вы всегда можете изменить размер холста, но тогда вам придется перекрашивать все, что займет время и не всегда необходимо, потому что некоторое изменение размера Вы можете выполнить с помощью атрибутов CSS, в этом случае вы не перерисовываете холст.

Я вижу 4 случая, когда вы можете изменить размер окна (все начинается с полноэкранного холста)

1: вы хотите, чтобы ширина оставалась 100%, и вы хотите, чтобы соотношение сторон оставалось прежним. В этом случае вам не нужно перерисовывать холст; вам даже не нужен обработчик изменения размера окна. Все, что вам нужно, это

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

где ctx - ваш контекст холста. скрипка: resizeByWidth

2: вы хотите, чтобы ширина и высота оставались на 100%, и вы хотите, чтобы результирующее изменение соотношения сторон имело эффект растянутого изображения. Теперь вам не нужно перерисовывать холст, но вам нужен обработчик изменения размера окна. В обработчике вы делаете

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

скрипка: messWithAspectratio

3: ширина и высота должны оставаться равными 100%, но ответ на изменение соотношения сторон отличается от растяжения изображения. Затем вам нужно перерисовать и сделать это так, как указано в принятом ответе.

скрипка: перерисовка

4: вы хотите, чтобы ширина и высота составляли 100% при загрузке страницы, но после этого оставались постоянными (никакой реакции на изменение размера окна.

скрипка: фиксированная

Все скрипты имеют одинаковый код, за исключением строки 63, в которой установлен режим. Вы также можете скопировать код скрипты для запуска на локальном компьютере, и в этом случае вы можете выбрать режим с помощью аргумента строки запроса, например? Mode = redraw

8 голосов
/ 12 мая 2015

Я тоже искал ответ на этот вопрос, но принятый ответ сломался для меня.Очевидно, использование window.innerWidth не является переносимым.В некоторых браузерах это работает, но я заметил, что Firefox это не понравилось.

Грегг Таварес разместил здесь замечательный ресурс, который напрямую решает эту проблему: http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (см. Anti-pattern #'s3 и 4).

Использование canvas.clientWidth вместо window.innerWidth, кажется, работает хорошо.

Вот предложенный Греггом цикл рендеринга:

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();
7 голосов
/ 26 ноября 2010

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

<!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
   }
2 голосов
/ 13 августа 2013

(Продолжая ответ 動靜 能量)

Стиль холста, чтобы заполнить тело.При визуализации на холст учитывайте его размер.

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();
...