Относительный размер холста HTML - PullRequest
11 голосов
/ 24 августа 2011

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

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

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

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

Живая демоверсия: 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>

Ответы [ 3 ]

15 голосов
/ 24 августа 2011

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

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

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

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

РЕДАКТИРОВАТЬ: Портман указал, что я испортил стиль центрирования. Обновленная версия здесь .

7 голосов
/ 24 августа 2011

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

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

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

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

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

1 голос
/ 24 августа 2011

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...