Canvas растягивается при использовании CSS, но обычно со свойствами «width» / «height»

148

У меня есть 2 холста, один использует атрибуты HTML width и height для его размера, а другой использует CSS:

<canvas id="compteur1" width="300" height="300" onmousedown="compteurClick(this.id);"></canvas>
<canvas id="compteur2" style="width: 300px; height: 300px;" onmousedown="compteurClick(this.id);"></canvas>

Compteur1 отображается как должно, но не compteur2. Содержимое рисуется с использованием JavaScript на холсте 300x300.

Почему существует разница в показаниях?

Изображение 372

Теги:
canvas
width
height

7 ответов

159
Лучший ответ

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

Это объясняется в http://www.whatwg.org/html#attr-canvas-width (требуется JS) или http://www.whatwg.org/c#attr-canvas-width (вероятно, будет есть ваш компьютер):

Элемент canvas имеет два атрибута для управления размером растрового изображения элемента: width и height. Эти атрибуты, если они указаны, должны иметь значения, которые являются действительными неотрицательными целыми числами. Правила для анализа неотрицательных целых чисел должны использоваться для получения их числовых значений. Если атрибут отсутствует или разбор его значения возвращает ошибку, вместо этого следует использовать значение по умолчанию. Атрибуту width по умолчанию соответствует 300, а атрибуту height по умолчанию соответствует 150.

  • 7
    действительно .. Я всегда думал, что прямые атрибуты, такие как "ширина" и "высота", были устаревшими в последних версиях HTML ..
  • 4
    О, по-видимому, на самом деле это довольно хорошо описано на whatwg.org/specs/web-apps/current-work/multipage/… (section #attr-canvas-width ). Проблема в том, что я нажал на неправильную width раньше и вместо этого перешел в раздел #dom-canvas-width . Подал w3.org/Bugs/Public/show_bug.cgi?id=9469 об этом.
Показать ещё 2 комментария
33

Чтобы установить width и height, вам нужно использовать

canvasObject.setAttribute('width', '475');
  • 5
    +1 el.setAttribute('width', parseInt($el.css('width'))) добились el.setAttribute('width', parseInt($el.css('width'))) , спасибо
  • 7
    Что если я хочу, чтобы мой холст имел относительный размер? То есть, как имитировать width: 100%; css свойство?
Показать ещё 3 комментария
16

Для элементов <canvas> правила CSS для width и height устанавливают фактический размер элемента canvas, который будет нарисован на странице. С другой стороны, атрибуты HTML width и height устанавливают размер системы координат или сетки, которые будет использовать API-интерфейс canvas.

Например, рассмотрим это (jsfiddle):

var ctx = document.getElementById('canvas1').getContext('2d');
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);

var ctx2 = document.getElementById('canvas2').getContext('2d');
ctx2.fillStyle = "red";
ctx2.fillRect(10, 10, 30, 30);
canvas {
  border: 1px solid black;
}
<canvas id="canvas1" style="width: 50px; height: 100px;" height="50" width="100"></canvas>
<canvas id="canvas2" style="width: 100px; height: 100px;" height="50" width="100"></canvas>

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

Примечание. Если правила CSS для width и/или height не указаны, браузер будет использовать атрибуты HTML для размера элемента таким образом, чтобы 1 единица этих значений равнялась 1px на странице. Если эти атрибуты не указаны, они будут по умолчанию равны width из 300 и a height of 150.

  • 3
    Хорошее четкое описание того, что происходит!
13

Холст будет растянут, если вы установите ширину и высоту в CSS. Если вы хотите динамически манипулировать размером холста, вы должны использовать JavaScript следующим образом:

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
  • 1
    Большой! Спасибо за этот ответ. Мне пришлось поместить canvas.setAttribute перед canvas.getContext('2d') чтобы избежать растяжения изображения.
2

Коррекция ланномания

var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))
2

Браузер использует ширину и высоту css, но элемент холста масштабируется на основе ширины и высоты холста. В javascript читайте ширину и высоту css и задайте ширину и высоту холста.

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();
0

Если вы хотите динамическое поведение, основанное на, например, CSS-медиа-запросы, не используйте атрибуты ширины и высоты холста. Используйте правила CSS, а затем, прежде чем получить контекст рендеринга canvas, присвойте атрибутам width и height стилям ширины и высоты CSS:

var elem = document.getElementById("mycanvas");

elem.width = elem.style.width;
elem.height = elem.style.height;

var ctx1 = elem.getContext("2d");
...
  • 0
    Понятно, что холст получит размер координат по умолчанию (300 x 150), если размер указан только в CSS. Тем не менее, это предложение не работает для меня, но решение ниже работает.
  • 0
    @PerLindberg - это решение работает, если вы определили ширину и высоту CSS в пикселях для элемента canvas.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню