ChatGPT解决这个技术问题 Extra ChatGPT

使用 CSS 时画布会被拉伸,但使用“宽度”/“高度”属性是正常的

我有 2 个画布,一个使用 HTML 属性 widthheight 来调整大小,另一个使用 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 画布上绘制的。

为什么会有显示差异?

https://i.stack.imgur.com/2jpjv.jpg


S
Sebastian Simon

似乎 widthheight 属性决定了画布坐标系的宽度或高度,而 CSS 属性只决定了显示它的框的大小。

这在 HTML specification 中进行了解释:

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


确实..我一直认为在最近的 html 版本中不推荐使用像“宽度”和“高度”这样的直接属性..
哦,显然它实际上在 whatwg.org/specs/web-apps/current-work/multipage/…(第 #attr-canvas-width 节)中得到了很好的描述。问题是我之前点击了错误的 width 并转到了 #dom-canvas-width 部分。提交w3.org/Bugs/Public/show_bug.cgi?id=9469
拥有一个看起来像但与另一个(css 宽度、高度)根本不同的 API。哇。
当您希望内部坐标系不同时,区分这些很重要。 (即用于视网膜显示器或 8 位风格的游戏)
这真是令人困惑。我们试图在css中设置宽度和高度。我们花了 2 天的时间拉扯头发来了解这两种关于宽度和高度的不同解释。哇...
M
Mr. Alien

要设置您需要的 widthheight,您可以使用

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

+1 el.setAttribute('width', parseInt($el.css('width'))) 成功了,谢谢
如果我希望我的画布具有相对大小怎么办?也就是说,如何模仿一个width: 100%;的css属性?
很好的答案,但不要忘记添加 canvasObject.setAttribute('height', '123') !
我认为您不需要使用 .setAttribute() 我一直使用 .width 和 .height 属性
使用 getComputedStyle 的纯 JavaScript(无 jQuery)版本:canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));。重复高度。
a
approxiblue

对于 <canvas> 元素,widthheight 的 CSS 规则设置将绘制到页面的画布元素的实际大小。另一方面,widthheight 的 HTML 属性设置画布 API 将使用的坐标系或“网格”的大小。

例如,考虑这个 (jsfiddle):

var ctx = document.getElementById('canvas1').getContext('2d'); ctx.fillStyle = "红色"; ctx.fillRect(10, 10, 30, 30); var ctx2 = document.getElementById('canvas2').getContext('2d'); ctx2.fillStyle = "红色"; ctx2.fillRect(10, 10, 30, 30);画布{边框:1px纯黑色; }

相对于画布元素的内部坐标,两者都绘制了相同的东西。但是在第二个画布中,红色矩形将是两倍宽,因为整个画布被 CSS 规则拉伸到更大的区域。

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


L
Luke Taylor

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

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

伟大的!感谢您的回答。我必须将 canvas.setAttribute 放在 canvas.getContext('2d') 之前以避免拉伸图像。
R
Russell Harkins

浏览器使用 css 宽度和高度,但画布元素根据画布宽度和高度进行缩放。在 javascript 中,读取 css 宽度和高度并将画布宽度和高度设置为该值。

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

X
XaviGuardia

山尼玛校正

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

C
Coder_Naveed

canvas通过缓冲区渲染图像,因此当您指定宽度和高度html属性时,缓冲区大小和长度会发生变化,但是当您使用css时,缓冲区的大小是不变的。使图像拉伸。

使用 html 大小调整。

画布大小改变 -> 缓冲区大小改变 -> 渲染

使用 css 大小调整

画布大小改变 -> 渲染

由于缓冲区长度保持不变,因此当上下文渲染图像时,图像将显示在调整大小的画布中(但在未更改的缓冲区中渲染)。


A
Anthony Gedeon

CSS 设置画布元素的宽度和高度,因此它会影响坐标空间,使绘制的所有内容都倾斜

这是我如何使用 Vanilla JavaScript 设置宽度和高度的方法

canvas.width = numberForWidth

canvas.height = numberForHeight

M
Manolo

如果您想要基于例如 CSS 媒体查询的动态行为,请不要使用画布宽度和高度属性。使用 CSS 规则,然后在获取画布渲染上下文之前,为宽度和高度属性分配 CSS 宽度和高度样式:

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

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

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

很明显,如果仅在 CSS 中指定尺寸,画布将获得默认坐标尺寸(300 x 150)。但是,这个建议对我不起作用,但下面的解决方案可以。
@PerLindberg - 如果您为画布元素定义了 CSS 宽度和高度(以像素为单位),则此解决方案有效。