2010-04-06 48 views
156

我有2个画布,一个使用HTML属性widthheight大小它,另一个使用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。内容在300x300画布上使用JavaScript绘制。

为什么会有显示差异?

alt text

回答

172

看来,widthheight属性决定了画布的坐标系的宽度或高度,而CSS属性只是确定其将要示出的框的大小。

这是在http://www.whatwg.org/html#attr-canvas-width解释(需要JS)或http://www.whatwg.org/c#attr-canvas-width(可能会吃掉你的计算机):

canvas元素有两个属性来控制元素的位图的大小:widthheight。这些属性在指定时必须具有值有效的非负整数。必须使用解析非负整数的规则来获取它们的数值。如果某个属性缺失,或者解析其值时返回错误,则必须使用默认值。该width属性默认为300,height属性默认为150

+4

的确..我一直以为像“宽度”和“高度”被抛弃了直接的属性在最近的html版本中.. – Sirber 2010-04-09 00:02:03

+4

哦,显然它在http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#attr-canvas-宽度(section#'attr-canvas-width')。麻烦的是,我之前点击了错误的'width',而是转到了'#dom-canvas-width'部分。归档http://www.w3.org/Bugs/Public/show_bug.cgi?id=9469。 – SamB 2010-04-09 16:27:11

+1

你救了我一个可怕的头痛....谢谢! – nurxyz 2013-07-18 10:51:32

33

要设置widthheight你需要,你可以使用

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

+1'el.setAttribute('width',parseInt($ el.css('width')))'诀窍,谢谢 – Shanimal 2012-11-07 16:53:47

+4

如果我想让我的画布具有相对大小?也就是说,如何模仿'width:100%;''css属性? – Maxbester 2013-03-07 08:00:06

+1

很好的答案,但不要忘了添加canvasObject.setAttribute('height','123')! – 2013-03-15 14:46:05

13

画布会被拉伸,如果你设置宽度和你的CSS中的高度。如果要动态操纵画布的尺寸,你必须使用JavaScript像这样:

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

太棒了!感谢这个答案。我不得不在'canvas.getContext('2d')'之前放置'canvas.setAttribute',以避免图像拉伸。 – hhh 2015-04-13 09:25:26

17

对于<canvas>元素,widthheight的CSS规则设置画布元素的实际大小将被吸引到这一页。另一方面,widthheight的HTML属性设置画布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>

两者有相对于canvas元素的内部坐标上画出他们同样的事情。但是在第二个画布中,红色矩形的宽度会增加两倍,因为整个画布通过CSS规则被拉伸到更大的区域。

注意:如果未指定width和/或height的CSS规则,那么浏览器将使用HTML属性大小的元素,使得1个单位,这些值等于在页面上1px的。如果这些属性未被指定,那么它们将默认为width300height150

+2

对发生了什么很好的描述! – Ben 2015-04-05 09:02:23

2

浏览器使用css宽度和高度,但canvas元素根据画布宽度和高度进行缩放。在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规则,然后,让画布渲染上下文之前,分配给width和height属性CSS的宽度和高度风格:

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

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

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

很明显,如果尺寸仅在CSS中指定,画布将获得默认坐标尺寸(300 x 150)。 但是,这个建议对我不起作用,但下面的解决方案确实如此。 – 2016-03-29 14:29:39

+0

@PerLindberg - 如果您已为canvas元素定义了像素的CSS宽度和高度,则此解决方案可以工作。 – Manolo 2016-03-31 07:43:17