Сравнительный размер HTML-холста

Элемент HTML5 <canvas> не принимает относительные размеры (проценты) для его свойств width и height.

То, что я пытаюсь выполнить, - это иметь размер холста относительно окна. Это то, что я до сих пор придумал, но мне интересно, есть ли лучший способ:

  • Simpler
  • Не требует обертывания <canvas> в <div>.
  • Не зависит от jQuery (я использую его для получения ширины/высоты родительского div)
  • В идеале, не перерисовывается при изменении размера браузера (но я думаю, что это может быть необходимым)

Ниже приведен код, который рисует круг в середине экрана, 40% шириной до максимума 400 пикселей.

Live demo: http://jsbin.com/elosil/2

код:

<!DOCTYPE html>
<html>
<head>
    <title>Canvas of relative width</title>
    <style>
        body { margin: 0; padding: 0; background-color: #ccc; }
        #relative { width: 40%; margin: 100px auto; height: 400px; border: solid 4px #999; background-color: White; }
    </style>
    <script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
    <script>
        function draw() {
            // draw a circle in the center of the canvas
            var canvas = document.getElementById('canvas');
            var relative = document.getElementById('relative');
            canvas.width = $(relative).width();
            canvas.height = $(relative).height();
            var w = canvas.width;
            var h = canvas.height;
            var size = (w > h) ? h : w; // set the radius of the circle to be the lesser of the width or height;
            var ctx = canvas.getContext('2d');
            ctx.beginPath();
            ctx.arc(w / 2, h / 2, size/2, 0, Math.PI * 2, false);
            ctx.closePath();
            ctx.fill();
        }

        $(function () {
            $(window).resize(draw);
        });
    </script>
</head>
<body onload="draw()">
    <div id="relative">
        <canvas id="canvas"></canvas>
    </div>
</body>
</html>

Ответ 1

Атрибуты canvas width и height отделяются от тех же стилей canvas width и height. Атрибутами width и height являются размер поверхности рендеринга холста в пикселях, тогда как его стили выбирают место в документе, где браузер должен рисовать содержимое с поверхности рендеринга. Так получилось, что значение по умолчанию для стилей width и height, если они не указаны, - это ширина и высота поверхности рендеринга. Итак, вы правы насчет №1: нет причин, чтобы обернуть его в div. Вы можете установить процентные значения для всех стилей вашего элемента canvas, как и любой другой элемент.

Для # 3 это довольно просто (и кросс-браузер), чтобы получить размер вещей с помощью clientWidth и clientHeight, если вы не используете прописку на вашем элементе canvas.

Я закодировал немного упрощенную версию здесь.

Для №4 вы правы, что не везете. Можно проверить перед установкой ширины и высоты и оставить только холст, если он не требует изменения размера, что устранит некоторые из перерисовок, но вы не сможете избавиться от всех из них.

EDIT: Портман отметил, что я испортил стиль центрирования. Обновлена ​​версия здесь.

Ответ 2

Как сказано sethobrien, элемент canvas имеет TWO​​strong > пар ширину/высоту атрибутов.

  • canvas.width/canvas.height относятся к размеру в пикселе буфера, который будет содержать результат команд рисования.

  • canvas.style.width/canvas.style.height относятся к размеру, используемому для отображения объекта canvas в окне браузера, и они могут находиться в любом из блоков, поддерживаемых css.

Вы действительно можете установить canvas.width и canvas.height только один раз, сделать рисунок в холсте, установить параметры размера стиля в процентах и ​​затем забыть о перерисовке содержимого холста. Конечно, это означает, что браузер просто выполняет масштабирование, как для обычного изображения, загруженного из сети, так что видимый результат будет показывать артефакты масштабирования пикселей.

Вам нужно только перерисовать содержимое холста после изменения размера элемента canvas только в том случае, если вам нужны результаты, идеально подходящие для пикселя.

Ответ 3

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

Предположим, что высота холста = 400, для высоты окна = 480, и вы хотите изменить ее высоту относительно, если высота окна изменится на 640.

canvas = document.getElementById("canvas"); 
canvas.height=window.innerHeight*400/480;

p.s: не инициализировать высоту холста внутри тега html.

Используйте "window.innerHeight" (который возвращает высоту окна браузера.. аналогично "window.innerWidth" ), где вы хотите вычислить относительные позиции в окне.

Надеюсь, вы получили то, что вам нужно.