使用 CSS 时画布会被拉伸,但使用“width”和“width”则正常。 “高度”属性
我有 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 画布上绘制的。
为什么会有显示差异?
I have 2 canvases, one uses HTML attributes width
and height
to size it, the other uses 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 displays like it should, but not compteur2. The content is drawn using JavaScript on a 300x300 canvas.
Why is there a display difference?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
似乎
width
和height
属性决定了画布坐标系的宽度或高度,而 CSS 属性仅决定了显示它的框的大小。HTML 规范对此进行了解释:
It seems that the
width
andheight
attributes determine the width or height of the canvas’s coordinate system, whereas the CSS properties just determine the size of the box in which it will be shown.This is explained in the HTML specification:
要在画布上设置
宽度
和高度
,您可以使用:To set the
width
andheight
on a canvas, you may use:对于
元素,
width
和height
的 CSS 规则设置将绘制到页面的 canvas 元素的实际大小。另一方面,width
和height
的 HTML 属性设置画布 API 将使用的坐标系或“网格”的大小。例如,考虑这个(jsfiddle):
两者都相对于画布元素的内部坐标绘制了相同的东西。但在第二个画布中,红色矩形的宽度将是原来的两倍,因为 CSS 规则将整个画布拉伸到更大的区域。
注意:如果未指定
width
和/或height
的 CSS 规则,则浏览器将使用 HTML 属性来调整元素的大小,以使这些值的 1 个单位等于页面上 1 像素。如果未指定这些属性,则它们的宽度
将默认为300
,高度
为150
。For
<canvas>
elements, the CSS rules forwidth
andheight
set the actual size of the canvas element that will be drawn to the page. On the other hand, the HTML attributes ofwidth
andheight
set the size of the coordinate system or 'grid' that the canvas API will use.For example, consider this (jsfiddle):
Both have had the same thing drawn on them relative to the internal coordinates of the canvas element. But in the second canvas, the red rectangle will be twice as wide because the canvas as a whole is being stretched across a bigger area by the CSS rules.
Note: If the CSS rules for
width
and/orheight
aren't specified then the browser will use the HTML attributes to size the element such that 1 unit of these values equals 1px on the page. If these attributes aren't specified then they will default to awidth
of300
and aheight
of150
.如果您在 CSS 中设置宽度和高度,画布将被拉伸。如果你想动态操纵画布的尺寸,你必须使用 JavaScript,如下所示:
The canvas will be stretched if you set the width and height in your CSS. If you want to dynamically manipulate the dimension of the canvas you have to use JavaScript like so:
Shannimal校正
Shannimal correction
Canvas 通过缓冲区渲染图像,因此当您指定宽度和高度 HTML 属性时,缓冲区的大小和长度会发生变化,但当您使用 CSS 时,缓冲区的大小不会改变。使图像拉伸。
使用 HTML 调整大小。
画布尺寸已更改 ->缓冲区大小已更改 -> 渲染
使用 CSS 调整大小
画布的大小已更改 -> 由于缓冲区长度保持不变,所以
当上下文渲染图像时,
图像显示在调整大小的画布中(但在未更改的缓冲区中渲染)。
Canvas renders image by buffer, so when you specify the width and height HTML attributes the buffer size and length changes, but when you use CSS, the buffer's size is unchanged. Making the image stretched.
Using HTML sizing.
Size of canvas is changed -> buffer size is changed -> rendered
Using CSS sizing
Size of canvas is changed -> rendered
Since the buffer length is kept unchanged, when the context renders the image,
the image is displayed in resized canvas (but rendered in unchanged buffer).
CSS 设置画布元素的宽度和高度,因此它会影响坐标空间,使绘制的所有内容倾斜
这是我如何使用 Vanilla JavaScript 设置宽度和高度的方法
CSS sets the width and height of the canvas element so it affects the coordinate space leaving everything drawn skewed
Here's my way on how to set the width and height with Vanilla JavaScript
如果您想要基于 CSS 媒体查询等动态行为,请不要使用画布宽度和高度属性。使用 CSS 规则,然后在获取画布渲染上下文之前,将 CSS 宽度和高度样式分配给宽度和高度属性:
If you want a dynamic behaviour based on, e.g. CSS media queries, don't use canvas width and height attributes. Use CSS rules and then, before getting the canvas rendering context, assign to width and height attributes the CSS width and height styles:
我相信 CSS 有更好的机制来指定画布的大小,并且 CSS 必须决定样式,而不是 JavaScript 或 HTML。话虽如此,在 HTML 中设置宽度和高度对于解决画布问题非常重要。
CSS 有
!important
规则,允许覆盖其他样式属性的规则,包括 HTML 中的规则。通常,它的使用是不受欢迎的,但这里的使用是合法的黑客。在 WebAssembly 的 Rust 模块中,您可以执行以下操作:
一旦加载 WASM 模块,然后每当调整窗口大小时,我们都会更新画布缓冲区。我们通过手动将画布的
width
和height
指定为clientWidth
和clientHeight
。也许有更好的方法来更新缓冲区,但我相信这个解决方案比 @SamB、@CoderNaveed、@Anthony Gedeon、@Bluerain、@Ben Jackson、@Manolo、@XaviGuardia、@Russel Harkins 和 @fermar 建议的解决方案更好因为elem.style.width
& 不同@Manolo 使用的elem.style.height
技巧或 @XaviGuardia 使用的 JQuery 等效项,它将适用于尺寸由使用情况指定为flex< 的
canvas
。 /code> 或grid
项目。.有大量的
.unwrap()
因为 Rust 显式地处理可能的失败。使用更好的库可以使PPS
变得更加干净。例如
I believe CSS has much better machinery for specifying the size of the canvas and CSS must decide styling, not JavaScript or HTML. Having said that, setting width and height in HTML is important for working around the issue with canvas.
CSS has
!important
rule that allows to override other styling rules for the property, including those in HTML. Usually, its usage is frowned upon but here the use is a legitimate hack.In Rust module for WebAssembly you can do the following:
There we update the canvas buffer once the WASM module is loaded and then whenever the window is resized. We do it by manually specifying
width
andheight
of canvas as values ofclientWidth
andclientHeight
. Maybe there are better ways to update the buffer but I believe this solution is better than those suggested by @SamB, @CoderNaveed, @Anthony Gedeon, @Bluerain, @Ben Jackson, @Manolo, @XaviGuardia, @Russel Harkins, and @fermar becauseelem.style.width
&elem.style.height
trick used by @Manolo or its JQuery equivalent used by @XaviGuardia, it will work forcanvas
whose size is specified by usage asflex
orgrid
item.P.S. there's a ton of
.unwrap()
because Rust explicitly handles possible failures.P.P.S.
can be done much cleaner with better libraries. E.g.