Полотно розтягується при використанні 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.