Вопрос

Как я могу автоматически масштабировать HTML5 <canvas> элемент, подходящий для страницы?

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

Это было полезно?

Решение

Я считаю, что нашел элегантное решение:

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

Пока что это не оказало на меня большого негативного влияния на производительность.

Другие советы

Следующее решение сработало для меня лучше всего.Поскольку я относительно новичок в программировании, мне нравится иметь визуальное подтверждение того, что что-то работает так, как я ожидаю.Я нашел его на следующем сайте: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 сторон, чего НЕ было в случае некоторых других ответов выше.Надеюсь, поможет.

По сути, вам нужно привязать событие 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>

Установка ширины и высоты координатного пространства холста на основе размеров клиента браузера требует изменения размера и перерисовки при каждом изменении размера браузера.

Менее запутанное решение — сохранить размеры рисуемых в переменных Javascript, но установить размеры холста на основе размеров screen.width и screen.height.Используйте CSS, чтобы соответствовать:

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

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

А чистый CSS подход, добавленный к решению @jerseyboy выше.
Работает в Firefox (проверено в версии 29), Chrome (проверено в версии 34) и Internet Explorer (проверено в версии 11).

<!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 с позиции пикселей холста, и вам придется преобразовать координаты системы.

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

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

Если ваш div полностью заполнил веб-страницу, вы можете заполнить этот div и получить холст, заполняющий div.

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

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

Возможно, вам потребуется получить offsetWidth и высоту div или получить высоту/ширину окна и установить ее как значение пикселя.

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

Если вы заинтересованы в сохранении пропорций и делаете это на чистом 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>

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

}());

Используя 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;">

Я думаю, что именно это нам следует сделать: 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);

Во-первых, вы не можете использовать атрибуты ширины и высоты для изменения размера (по крайней мере, по-моему), потому что это сломает его.Вы можете сделать это:HTML:

<canvas id = 'myCanvas'></canvas>

ЯС:

var canvas = document.getElementById('myCanvas');

var W = window.innerWidth;
var H = window.innerHeight;
canvas.width = W;
canvas.height = H;
canvas.style.position = 'absolute';
//Or set the position to absolute using CSS

(Пожалуйста, простите меня за опечатки, я часто так делаю)

Я использую Sketch.js, поэтому после запуска команды инициализации холста я меняю ширину и высоту с помощью jquery.Он основывает размеры на родительском элементе.

$('#DrawCanvas').sketch().attr('height',$('#DrawCanvas').parent().height()).attr('width',$('#DrawCanvas').parent ().ширина());

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top