Полотно розтягується при використанні CSS, але нормально з властивостями "ширина" / "висота"


195

У мене є 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 текст

Відповіді:


216

Здається, що атрибути 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.


11
дійсно .. Я завжди думав, що прямі атрибути, такі як "ширина" та "висота", в останніх версіях html застаріли ..
Сірбер

4
О, мабуть, це насправді добре описано в 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, висота). Ого.
Бен Астон

1
Важливо розрізняти їх у часи, коли потрібно, щоб внутрішня система координат була іншою. (тобто для дисплеїв сітківки або 8-
бітової

1
Це було справді заплутано. Ми де намагаємось задати ширину та висоту в css. Ми зайняли 2 дні, коли стрес витягує волосся, щоб дізнатися про ці дві різні інтерпретації про ширину та висоту. Просто вау ...
NME New Media Entertainment

39

Щоб встановити widthі heightвам потрібно, ви можете використовувати

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

6
+1 el.setAttribute('width', parseInt($el.css('width')))зробив трюк, спасибі
Shanimal

9
Що робити, якщо я хочу, щоб мої полотна мали відносний розмір? Тобто, як імітувати width: 100%;властивість css?
Максбестер

1
Чудова відповідь, але не забудьте додати також canvasObject.setAttribute ('висота', '123')!
Том Уеллс

Я не думаю, що вам потрібно використовувати .setAttribute () Я завжди використовував властивості .width і .height
Zorgatone

4
Plain JavaScript (без JQuery) версії з допомогою getComputedStyle : canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));. Повторіть для висоти.
Бен Дж

25

Для <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.


16

Полотно буде розтягнуте, якщо встановити ширину та висоту в CSS. Якщо ви хочете динамічно маніпулювати розмірами полотна, вам потрібно використовувати JavaScript так:

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

1
Чудово! Дякую за цю відповідь. Я повинен був поставити canvas.setAttributeраніше, canvas.getContext('2d')щоб уникнути розтягування зображення.
hhh

6

Браузер використовує ширину та висоту css, але елемент полотна масштабується на основі ширини та висоти полотна. У javascript прочитайте ширину та висоту css та встановіть для цього ширину та висоту полотна.

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

2

Корекція шанімалу

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

0

CSS встановлює ширину і висоту елемента полотна, щоб він впливав на координатний простір, залишаючи все намальованим перекошеним

Ось мій шлях щодо встановлення ширини та висоти за допомогою Vanilla JavaScript

canvas.width = numberForWidth

canvas.height = numberForHeight

-1

Якщо ви хочете динамічну поведінку, засновану, наприклад, на запити медіа CSS, не використовуйте атрибути ширини та висоти полотна. Використовуйте правила CSS, а потім, перш ніж отримувати контекст відображення полотна, призначте атрибути ширини та висоти стилі ширини та висоти CSS:

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

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

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

Зрозуміло, що полотно отримає розмір координати за замовчуванням (300 х 150), якщо розмір визначений лише у CSS. Однак ця пропозиція не працює для мене, але рішення, наведене нижче, - це.
Пер Ліндберг

@PerLindberg - Це рішення працює, якщо ви визначили ширину та висоту CSS у пікселях для елемента полотна.
Маноло
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.