Холст растягивается при использовании CSS, но обычно со свойствами ширины / высоты

У меня есть 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.

Почему есть разница в отображении?

alt text


person Sirber    schedule 06.04.2010    source источник


Ответы (8)


Кажется, что атрибуты 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.

person SamB    schedule 06.04.2010
comment
на самом деле ... Я всегда думал, что прямые атрибуты, такие как ширина и высота, устарели в последних версиях html .. - person Sirber; 09.04.2010
comment
О, похоже, это на самом деле довольно хорошо описано на whatwg.org/specs/web-apps/current-work/multipage/ (раздел #attr-canvas-width). Проблема в том, что я раньше нажимал не ту width и вместо этого перешел в раздел #dom-canvas-width. Создан w3.org/Bugs/Public/show_bug.cgi?id=9469. об этом. - person SamB; 09.04.2010
comment
Наличие API, который выглядит, но принципиально отличается от другого (ширина, высота css). Вот это да. - person Ben Aston; 28.08.2017
comment
Важно различать их в тех случаях, когда вы хотите, чтобы внутренняя система координат была другой. (т.е. для дисплеев Retina или 8-битной игры) - person Samy Bencherif; 13.11.2018
comment
Это действительно сбивало с толку. Мы пытались установить ширину и высоту в CSS. Нам потребовалось 2 дня стресса, связанного с выдергиванием волос, чтобы узнать об этих двух различных интерпретациях ширины и высоты. Просто вау... - person NME New Media Entertainment; 08.05.2020

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

canvasObject.setAttribute('width', '475');
person fermar    schedule 16.03.2011
comment
+1 el.setAttribute('width', parseInt($el.css('width'))) сделали свое дело, спасибо - person Shanimal; 07.11.2012
comment
Что, если я хочу, чтобы мой холст имел относительный размер? То есть, как имитировать свойство width: 100%; css? - person Maxbester; 07.03.2013
comment
Отличный ответ, но не забудьте добавить также canvasObject.setAttribute ('height', '123')! - person Tom Wells; 15.03.2013
comment
Не думаю, что вам нужно использовать .setAttribute (). Я всегда использовал свойства .width и .height. - person Zorgatone; 21.06.2017
comment
Обычная версия JavaScript (без jQuery) с использованием getComputedStyle: canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));. Повторите для высоты. - person Ben J; 14.07.2017

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

Например, рассмотрим это (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 единица этих значений равнялась 1 пикселю на странице. Если эти атрибуты не указаны, они по умолчанию будут иметь width 300 и height 150.

person Ben Jackson    schedule 29.09.2013

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

canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
person Bluerain    schedule 22.01.2013
comment
Большой! Спасибо за этот ответ. Пришлось поставить canvas.setAttribute перед canvas.getContext('2d'), чтобы изображение не растягивалось. - person hhh; 13.04.2015

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

var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();
person Russell Harkins    schedule 18.11.2014

Shannimal поправка

var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))
person XaviGuardia    schedule 21.11.2015

CSS устанавливает ширину и высоту элемента холста, поэтому он влияет на пространство координат, оставляя все нарисованное перекошенным.

Вот мой способ установки ширины и высоты с помощью Vanilla JavaScript

canvas.width = numberForWidth

canvas.height = numberForHeight
person Anthony Gedeon    schedule 08.04.2020

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

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

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

var ctx1 = elem.getContext("2d");
...
person Manolo    schedule 25.01.2016
comment
Понятно, что холст получит размер координат по умолчанию (300 x 150), если размер указан только в CSS. Однако это предложение не работает для меня, но решение ниже работает. - person Per Lindberg; 29.03.2016
comment
@PerLindberg - это решение работает, если вы определили ширину и высоту CSS в пикселях для элемента холста. - person Manolo; 31.03.2016