2010-04-06 2 views
156

У меня 2 холсты, один использует HTML атрибуты width и height задания размера, другой использует CSS:Холст натягивается при использовании 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

ответ

172

кажется, что 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.

+4

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

+4

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

+1

ты спас мне страшную головную боль .... спасибо! – nurxyz

33

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

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

+1 'el.setAttribute ('width', parseInt ($ el.css ('width')))' сделал трюк, спасибо – Shanimal

+4

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

+1

Отличный ответ, но не забудьте добавить canvasObject.setAttribute ('height', '123') тоже! –

13

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

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

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

17

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

+2

Хорошее четкое описание того, что происходит! – Ben

2

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

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

Shannimal коррекция

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

Если вы хотите, динамическое поведение, основанное на, например, CSS-медиа-запросы, не используйте атрибуты ширины и высоты холста. Используйте правила CSS, а затем, перед тем, как контекст рендеринга холста, присвоить ширину и высоту атрибутов в 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. – Manolo