奇怪的HTML5 Canvas closePath渲染工件

时间:2017-09-22 15:27:16

标签: javascript canvas rendering

我在我正在处理的项目中使用HTML5 Canvas元素,在渲染一堆东西的时候,我遇到了一个非常奇怪的神器,我想知道是否有人见过。基本上,在这种特殊情况下(这是我见过的唯一产生这种行为的情况),我碰巧在我的应用程序中平移/缩放,并发现在画布的一部分上有一种非常奇怪的渲染效果。经过进一步检查,我能够以一个非常简单的例子再现效果:

Strange HTML5 Canvas Rendering Artifact

在这种情况下,我有一条路径(其坐标不会发生变化),所有从第一个屏幕截图到第二个屏幕截图的变化都是应用的变换矩阵(非常少量)。

您可以访问我用于在https://jsfiddle.net/ynsv66g8/生成这些屏幕截图的JSFiddle,这是相关的呈现代码:

// Clear context
context.setTransform(1, 0, 0, 1, 0, 0);
context.fillStyle = "#000000";
context.fillRect(0, 0, 500, 500);

if (showArtifact) { // This transformation causes the artifact
  context.transform(0.42494658722537976, 0, 0, -0.42494658722537976, 243.95776291868646, 373.14630356628857);
} else { // This transformation does not
  context.transform(0.4175650109545749, 0, 0, -0.4175650109545749, 243.70987992043368, 371.06797574381795);
}

// Draw path
context.lineWidth = 3.488963446543301;
context.strokeStyle = 'red';
context.beginPath();
var p = path[0];
context.moveTo(p[0], p[1]);
for (var i = 1; i < path.length; ++i) {
  p = path[i];
  context.lineTo(p[0], p[1]);
}
context.closePath();
context.stroke();

它似乎与canvas.closePath()的来电相关,因为如果您移除对context.closePath()的调用并将其替换为:

p = path[0];
context.lineTo(p[0], p[1]);

(因此手动&#34;关闭&#34;路径)一切正常(授予,这确实无法解决我的特定问题,因为我依靠多个封闭路径来应用填充规则)。

可以使问题消失的另一个有趣变化是反转path数组(即,在定义之后立即添加对path.reverse()的调用)。

总之,所有这些似乎都会增加与路径特征相关的某种浏览器渲染错误,特别是因为在我的Mac上,问题出现在Chrome(v61.0.3163.91)和Firefox中(v55.0.3)但不是Safari(第11节)。我已经做了一些广泛的搜索,试图找到这个问题(或类似的东西),但到目前为止已经空了。

对于可能导致此问题的任何见解(或者如果共识是由某些浏览器错误引起的正确报告此问题的正确方法)将不胜感激。

1 个答案:

答案 0 :(得分:3)

这似乎是线路缓解问题;也就是说,当宽度相对于段大小/方向太大时,渲染器无法正确连接线。

这似乎不受路径关闭的影响(我可以用开放路径重现工件);请注意,手动关闭路径与closePath()不同,因为在前一种情况下不执行行连接。

据我所知,似乎通过将lineJoin设置为&#39; round&#39;或者减小线宽......无论如何,对我来说似乎是一个渲染器错误......只是我的两分钱:)。