为什么使用lineTo()会改变内部像素?

12

这种情况很难解释,所以让我用一张图片来说明:像素变亮

创建的第一个图形内部的像素变亮。屏幕被清除成黑色,绘制了红色和绿色的框,然后绘制路径。到目前为止,我找到的唯一解决方法是将方框的线宽设置为2个像素,原因在这里here

下面是用于绘制正方形的代码:

sctx.save();
sctx.strokeStyle = this.color;
sctx.lineWidth = this.width;
sctx.beginPath();
sctx.moveTo(this.points[0].x, this.points[0].y);
for (var i = 1; i < this.points.length; i++)
{
    sctx.lineTo(this.points[i].x, this.points[i].y);
}
sctx.closePath();
sctx.stroke();
sctx.restore();

并且这些行:

sctx.save();
sctx.strokeStyle = 'orange';
sctx.lineWidth = 5;
console.log(sctx);
sctx.beginPath();
sctx.moveTo(this.points[0].x, this.points[0].y);
for (var i = 1; i < this.points.length; i++)
{
    sctx.lineTo(this.points[i].x, this.points[i].y);
}
sctx.closePath();
sctx.stroke();
sctx.restore();

下面是同一情况下,用2像素的宽度绘制的盒子图片: 第二种不协调情况

lineTo() 可能会影响 alpha 值吗?非常感谢任何帮助。

编辑:为了澄清,当从绘制路径中省略 sctx.closePath(); 时,同样会出现相同问题。


1
你能否提供一个 jsfiddle? - jcolebrand
如果必要的话,我可能会这样做。我正在使用一个相当大的库(我自己创建的):https://github.com/Bloodyaugust/SugarLab,所以我需要削减很多内容才能使它对你有帮助。 - Bloodyaugust
我认为你的分析是正确的,这些方框被绘制时降低了不透明度,而在其上绘制形状会将这些“内部”方框重置为完全不透明度。恐怕我对涉及的技术了解不够,无法推测原因。 - Mark Ransom
1
你所描述的表明你知道问题,但我需要看到更多实际操作才能确定。将问题简化为最少可重复结果会有助于找到问题根源。 - jcolebrand
解决方案不是放置2像素宽的线条,而是使用fillRect()而不是lineTo() — 如果您发布一个fiddle,我会给出正确的答案。 - Tom Roggero
这在所有浏览器中都会发生吗? - Jesse Hattabaugh
2个回答

1

看起来这是一个目前未记录的呈现错误,出现在所有平台上的某个原因。关于它的信息非常少,希望在HTML5成为正式标准之前可以解决。

作为一种解决方法,不要使用lineTo(),而使用多组单行。


0

假设你有:http://jsfiddle.net/g3Kvw/ 如你所见,它似乎是2像素宽。但如果你改用fillRect()而不是lineTo(),你会得到http://jsfiddle.net/g3Kvw/1/,看起来很好。

问题:使用这种方法,您将无法绘制不是矩形的东西。

但是,如果您将0.5加到每个int坐标(x,y)中:http://jsfiddle.net/g3Kvw/3/,您将获得常规线。

我认为这是FF和webkit上某种抗锯齿计算错误...但我在错误跟踪器中没有找到它,而将数字转换为浮点数以获得实线的“奇怪”解决方案相当令人困惑。因为使用整数应该足够了。


虽然这确实解决了抗锯齿的问题,但它并没有解释lineTo()在其区域内更改像素的问题。事实上,即使将lineTo()内部的线条宽度更改为2以使其颜色正确,它们仍会与橙色线条略微重叠。 - Bloodyaugust
@Bloodyaugust 这是由于渲染引擎的原因。你是否在CSS和JS两侧都设置了画布的宽度和高度? - Tom Roggero
我唯一会涉及宽度和高度的时候是在HTML声明中:<canvas id="gameCanvas" width="1000" height="600" style="position: relative"></canvas>。 - Bloodyaugust
你能否尝试在JS中的canvas对象上添加canvas.width = 1000;和canvas.height = 600;? - Tom Roggero
你能创建一个 Fiddle 来展示你的东西吗? - Tom Roggero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接