Змініть розмір полотна HTML5 відповідно до вікна


400

Як я можу автоматично масштабувати <canvas>елемент HTML5 для розміщення сторінки?

Наприклад, я можу отримати <div>масштаб, встановивши значення heightі widthвластивості на 100%, але <canvas>масштаб не буде, чи не так?


7
чому полотно {ширина: 100%; висота: 100%} не працює?
злоктб

28
@zloctb - це дозволить збільшити масштаб полотна безпосередньо, що розтягне ваше зображення.
Дерек 朕 會 功夫

8
Докладні пояснення щодо того, що і що не потрібно робити для пов'язаних питань, див. У Основах WebGL .
legends2k

2
Полотно також буде добре масштабувати, просто додайте css {width: 100%}, але його вміст не буде, проте це зовсім інша справа!
викидання

Відповіді:


372

Я вважаю, що я знайшов для цього елегантне рішення:

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

Поки що не вплинуло на мене якнайбільше.


7
Можливо, вам доведеться відключити маржу за допомогоюbody, html { margin: 0px;}
Nicklas A.

45
Чи бажано це слухати події зміни розміру?
Ерік

25
@Elisabeth: Щоб позбутися смуг прокрутки, додайте "переповнення: приховано" до стилю html та елементів тіла. Дивіться thefutureoftheweb.com/blog/100-percent-height-interface
Деніс Вашингтон

17
Я зробив це плюс, я також встановив полотно для відображення: block (здавалося, дефолт відображається: inline, що створює додатковий простір!).
Елізабет

15
Це може бути анти-модель; дивіться третій пункт тут щодо причини та виправлення.
legends2k

67

Наступне рішення працювало для мене найкраще. Оскільки я відносно новачка в кодуванні, мені подобається мати візуальне підтвердження того, що щось працює так, як я очікую. Я знайшов його на наступному веб-сайті: http://htmlcheats.com/html/resize-the-html5-canvas-dyamically/

Ось код:

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

Блакитна рамка показує вам край полотна, що змінює розмір, і завжди знаходиться по краю вікна, видно з усіх 4 сторін, що НЕ було випадку для деяких інших відповідей вище. Сподіваюся, це допомагає.


Ця відповідь вирішила мою проблему. overflow: hiddenІ display: blockто , що не вистачає для мене , щоб отримати цю роботу належним чином.
Deathicon

1
Посилання розірвано
Nic Scozzaro

22

В основному те, що вам потрібно зробити, - прив’язати подію onresize до свого тіла, коли ви перейдете на цю подію, вам просто потрібно змінити розмір полотна за допомогою window.innerWidth та 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
Ви можете просто скористатися слухачем подій.
Девід Корбін

Це поле та показує смуги прокрутки, плюс вам потрібно змінити розмір екрана, перш ніж він щось зробить.
ArtOfWarfare

Що робити, якщо полотно більше, ніж вікно перегляду (якщо зробить вигляд огляду чи коротшим)? Це рішення, схоже, не справляється з цим.
Ларс Гіруп Брінк Нільсен

В оригінальних запитаннях @ArtOfWarfare нічого не згадується про стилі. Але ви можете стилізувати його за допомогою css та видалити поля та приховати смуги прокрутки, якщо хочете. І ви просто можете додати `<body onload =" resize_canvas () ">` тоді при завантаженні сторінки потім змінити розмір полотна.
еквіман

@LayZee оригінальне запитання, яке стосується питання, масштабує полотно для розміщення сторінки , а не вікна перегляду. Це може бути інше питання.
еквіман

19

Встановлення ширини та висоти простору координати полотна на основі розмірів клієнта браузера вимагає змінити розмір та перемальовувати кожен раз, коли розмір браузера змінюється.

Менш складним рішенням є підтримка розмірних розмірів у змінних Javascript, але встановлення розмірів полотна на основі розмірів екрана, ширини, висоти екрана. Використовуйте CSS для пристосування:

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

Вікно браузера зазвичай не буде більше, ніж сам екран (за винятком випадків, коли роздільна здатність екрана неправильно повідомляється, як це могло бути з невідповідними подвійними моніторами), тому фон не відображатиметься, а пропорції пікселів не змінюватимуться. Пікселі полотна будуть прямо пропорційними дозволу екрана, якщо ви не використовуєте CSS для масштабування полотна.


7
Масштабування полотна за допомогою CSS - клопітка. Принаймні, на Chrome і Safari позиції подій миші / сенсорного походження не відповідають 1: 1 позиціям пікселів полотна, і вам доведеться трансформувати системи координат.
jerseyboy

14

Чистий CSS підхід додавання до розчину @jerseyboy вище.
Працює в Firefox (тестується в v29), Chrome (тестовано в v34) та Internet Explorer (тестується в 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>

Посилання на приклад: http://temporaer.net/open/so/140502_canvas-fit-to-window.html

Але будьте обережні, як у своєму коментарі стверджує @jerseyboy:

Масштабування полотна за допомогою CSS - клопітка. Принаймні, на Chrome і Safari позиції подій миші / сенсорного походження не відповідають 1: 1 позиціям пікселів полотна, і вам доведеться трансформувати системи координат.


5
CSS-спосіб розтягує полотно, таким чином витягнуті зображення натягуються. Це не добре в порівнянні із зміною розміру полотна. З невеликим регулюванням відповідь Крейга працює найкраще.
Найян

Мені подобається це рішення, оскільки це робить полотно на 100% залежно від ширини батьків.
Майхан Ніят

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

Приємно, коли співвідношення важливе
саркірока

8

Якщо ви не хочете, щоб полотно автоматично збільшило масштаб даних ваших зображень (саме про це йдеться у відповіді Джеймса Блека, але це не буде виглядати досить сильно), вам доведеться змінити розмір самостійно та перемалювати зображення. Центрування полотна


4

Якщо ваш div повністю заповнив веб-сторінку, ви можете заповнити цей div та мати на ньому полотно, яке заповнює div.

Це може бути вам цікавим, оскільки вам може знадобитися використовувати css, щоб використовувати відсоток, але це залежить від того, який браузер ви використовуєте, і наскільки він узгоджується зі специфікацією: http://www.whatwg.org/ specs / web-apps / current-work / multipage / the-canvas-element.html # the-canvas-element

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

Можливо, вам доведеться отримати ширину і висоту зсуву, або отримати висоту / ширину вікна і встановити це як значення пікселя.


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

Якщо вам цікаво зберегти співвідношення сторін і робити це в чистому CSS (з урахуванням співвідношення сторін), ви можете зробити щось подібне нижче. Ключ padding-bottomна ::contentелемент , який змінює розмір containerелемента. Це розмір відносно ширини батьків, яка 100%за замовчуванням. Зазначене співвідношення має відповідати співвідношенню розмірів на canvasелементі.

// 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, ви можете відстежувати розмір вікна та змінювати ширину полотна, використовуючи також jQuery.

Щось схоже

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

Я думаю, що саме це ми повинні робити: 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

Я використовую sketch.js, тому після запуску команди init для полотна я змінюю ширину та висоту за допомогою jquery. Він засновує розміри на батьківському елементі.

$ ('# DrawCanvas'). Sketch (). Attr ('height', $ ('# DrawCanvas'). Parent (). Height ()). Attr ('width', $ ('# DrawCanvas'). Батьківський () .width ());

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