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

#javascript #css #canvas #css-animations

Вопрос:

У меня есть 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 на холсте 300х300.

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

альтернативный текст

Ответ №1:

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

Это объясняется в спецификации HTML:

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

Комментарии:

1. действительно.. Я всегда думал, что прямые атрибуты, такие как «ширина» и «высота», устарели в последних версиях html..

2. О, по-видимому, на самом деле это довольно хорошо описано в whatwg.org/specs/web-apps/current-work/multipage/… (раздел #attr-canvas-width ). Проблема в том, что я нажал не на ту width страницу раньше и вместо этого перешел в #dom-canvas-width раздел. Подано w3.org/Bugs/Public/show_bug.cgi?id=9469 об этом.

3. Наличие API, похожего на внешний вид, но принципиально отличающегося от другого (ширина css, высота). Вау.

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

5. Это действительно сбивало с толку. Мы пытаемся установить ширину и высоту в css. Нам потребовалось 2 дня стресса, связанного с потягиванием за волосы, чтобы узнать об этих 2 различных интерпретациях ширины и высоты. Просто вау…

Ответ №2:

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

 canvasObject.setAttribute('width', '475');
 

Комментарии:

1. 1 el.setAttribute('width', parseInt($el.css('width'))) сделал свое дело, спасибо

2. Что делать, если я хочу, чтобы мой холст имел относительный размер? То есть, как имитировать width: 100%; свойство css?

3. Отличный ответ, но не забудьте также добавить атрибут canvasObject.setAttribute(«высота», «123»)!

4. Я не думаю, что вам нужно использовать .setAttribute() Я всегда использовал свойства .width и .height

5. Обычная версия JavaScript (без jQuery) с использованием getComputedStyle : canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width")); . Повторите для высоты.

Ответ №3:

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

Ответ №4:

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

 canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
 

Комментарии:

1. Отлично! Спасибо за этот ответ. Мне пришлось поставить canvas.setAttribute раньше canvas.getContext('2d') , чтобы избежать растягивания изображения.

Ответ №5:

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

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

Ответ №6:

Поправка Шеннимала

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

Ответ №7:

CSS задает ширину и высоту элемента canvas, чтобы он влиял на пространство координат, оставляя все нарисованное искаженным

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

 canvas.width = numberForWidth

canvas.height = numberForHeight
 

Ответ №8:

холст отображает изображение буфером, поэтому при указании атрибутов html ширины и высоты размер и длина буфера меняются, но при использовании css размер буфера остается неизменным. делая изображение растянутым.

Использование размера html.

размер холста изменен -> размер буфера изменен ->> визуализация

Использование размера css

размер холста изменяется -> визуализация

поскольку длина буфера остается неизменной, при отображении изображения в контексте изображение отображается на холсте с измененным размером (но отображается в неизмененном буфере).

Ответ №9:

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

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

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

var ctx1 = elem.getContext("2d");
...
 

Комментарии:

1. Ясно, что холст получит размер координат по умолчанию (300 x 150), если размер указан только в CSS. Однако это предложение не работает для меня, но решение, приведенное ниже, работает.

2. @PerLindberg — Это решение работает, если вы определили ширину и высоту CSS в пикселях для элемента canvas.