Полотно HTML5 100% ширина висоти вікна перегляду?


151

Я намагаюся створити елемент полотна, який займає 100% ширини та висоти вікна перегляду.

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


1
Дивіться також: stackoverflow.com/questions/4037212
hippietrail

Нагадує досить кумедний ескіз комедії Fonejacker: youtu.be/6oj_oLMD688?t=22s
Френсіс Бут

Відповіді:


258

Для того, щоб полотно завжди було шириною і висотою повного екрану, тобто навіть при зміні розміру браузера, потрібно запустити цикл малювання в межах функції, яка змінює полотно до 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 ().


2
Чому потрібно прибрати прокладки і встановити ширину, висоту до 100%?
Кос

3
Я вважаю, що це головним чином для переоформлення таблиці стилів користувачів, для якої браузер має за замовчуванням. Якщо ви використовуєте якийсь файл нормалізації або скидання css-файлу, це не потрібно, оскільки це вже буде усунуто.
jaredwilli

2
Якщо ви очікуєте досить багато зміни розміру; Наприклад, на пристрої для портретного / ландшафтного debounceрежиму , ви хочете змінити розмір, інакше перелийте браузер.
dooburt

24
display: block: Це не тільки видаляє смуги прокрутки, але видаляє 2 пікселя з висоти тіла документа, які зазвичай додаються під текстовими рядками всередині блоку. Тож +1 для цього
Нептіло

2
плюс один за відсутність jQuery
Фелікс Ганьон-Греньє

26

Ви можете спробувати одиниці перегляду (CSS3):

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

5
Додайте display: block;і це робить роботу.
superlukas

18
Я спробував це і виявив, що в Chrome і Firefox полотно просто показує зображення, розтягнуте до повного огляду. Натягнуті навіть навіть щойно намальовані елементи.
Вівіан-Рівер

8
@Daniel вірно - ця відповідь неправильна . Він не встановлюватиме внутрішній вимір контексту полотна, а скоріше розміри елемента DOM. Для різниці дивіться мою відповідь на пов'язане питання .
Дан Даскалеску

19
Цей метод не працює, він розтягує текст. На жаль, ви повинні використовувати JS.
i336_

16

Я відповім на більш загальне питання про те, як полотно динамічно адаптуватися за розмірами під розміром вікна. Прийнята відповідь належним чином обробляє той випадок, коли ширина та висота повинні бути 100%, що саме просили, але який також змінить співвідношення сторін полотна. Багато користувачів захочуть, щоб полотно змінило розмір вікна, але при цьому зберігати співвідношення сторін не слід. Це не точне запитання, але воно "вписується", просто ставлячи питання в дещо більш загальний контекст.

Вікно матиме певне співвідношення сторін (ширина / висота), і так буде об’єкт полотна. Як ви хочете, щоб ці два співвідношення сторін співвідносилися один з одним, вам потрібно буде зрозуміти, на це питання немає відповіді "один розмір, який відповідає всім" - я перегляну кілька загальних випадків того, що ви могли б хочу.

Найголовніше, про що вам має бути зрозуміло: об’єкт полотна html має атрибут ширини та атрибут висоти; а потім, css того ж об'єкта також має атрибут ширини та висоти. Ці дві ширини і висоти різні, обидві корисні для різних речей.

Зміна атрибутів ширини та висоти - це один метод, за допомогою якого ви завжди можете змінити розмір свого полотна, але тоді вам доведеться перефарбувати все, що займе час і не завжди потрібно, тому що певну зміну розміру ви можете досягти через атрибути 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


1
fyi: $(ctx.canvas).css("width", "100%");еквівалентно $(canvas).css("width", "100%"); (полотно контексту - просто полотно)
Бред Кент

@BradKent, коли ви викликаєте функцію помічника, яка виконує потрібні вами "canvas-речі", ви можете або в якості аргументу (аргументів) 1) передавати об'єкт canvas, 2) передавати контекст полотна, 3) і те й інше. Мені не подобається 3), і ctx.canvasце набагато коротше, canvas.getContext('2d')- тому я роблю 2). Отже, немає змінної під назвою canvas, але є ctx.canvas. Ось звідки походить ctx.canvas.
mathheadinclouds

9

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
   }

Це працює, але це залишає моє полотно без визначеної ширини та висоти. Ширина та висота полотна повинні визначатися на елемент, якому я вірю.
aherrick

@aherrick: Ні, вам не потрібно мати чітку ширину / висоту на елементі полотна, щоб він працював. Цей код повинен добре працювати.
Джон Адамс

18
Насправді так, елементи полотна дійсно потребують явного набору ширини / висоти. Без цього вони за замовчуванням до деякого попередньо встановленого браузера (у хромі, я думаю, що це розмір 300x150px). Весь малюнок на полотні інтерпретується в такому розмірі, а потім масштабується до 100% розміру вікна перегляду. Спробуйте намалювати що- небудь на своєму полотні, щоб побачити, що я маю на увазі - це буде спотворено.
Марк Кан

якщо ви намагаєтеся зробити полотно на 100% шириною та висотою, то це взагалі не має значення. ви просто змінити розмір у будь-якому випадку
jaredwilli

1
Властиві розміри елемента полотна рівні розміру простору координат з числами, інтерпретованими у пікселях CSS. Однак елемент можна розміряти довільно за допомогою аркуша стилів. Під час візуалізації зображення масштабується відповідно до цього розміру макета.
jaredwilli

8

Я шукав відповідь і на це питання, але прийнята відповідь для мене зламалася. Мабуть, використовуючи window.innerWidth не портативний. Це працює в деяких браузерах, але я помітив, що Firefox це не любив.

Грегг Таварес розмістив тут чудовий ресурс, який безпосередньо стосується цього питання: http://webglfundamentals.org/webgl/lessons/webgl-anti-patterns.html (Див. Анти-шаблон № 3 і 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();

2

(Розгортається на відповідь 動靜 能量)

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

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

Для мобільних телефонів краще використовувати їх

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

тому що він буде відображатися неправильно після зміни орієнтації. "Перегляд" буде збільшено при зміні орієнтації на портрет. Перегляньте повний приклад

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.