为什么 HTML Canvas 圆角 lineCap 最后一段失败?
使用 HTML Canvas 如果你画一条像这样的虚线:
ctx.lineWidth = 40;
ctx.lineCap = 'round';
ctx.strokeStyle = 'red';
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(150,200);
ctx.moveTo(200,300);
ctx.lineTo(250,400);
ctx.moveTo(300,500);
ctx.lineTo(350,600);
ctx.closePath();
ctx.stroke();
那么结果是这样的:
(来源:phrogz.net)
正如您在 < a href="http://phrogz.net/tmp/canvas_broken_rounded_rinkle.html" rel="nofollow noreferrer">此测试页面,在最后一个之后添加“多余的”moveTo
调用lineTo
修复了最后一个线段以使用圆角大写字母。
我准备将此作为一个错误提交,但后来我发现该行为在 Safari v5、Chrome v8、FireFox v3.6 和 v4.0b 上是相同的。这让我相信这是故意的。
标准中的哪个位置指定了此行为,以及(如果您能辨别)为什么如此指定?
With the HTML Canvas if you draw a dotted line like this:
ctx.lineWidth = 40;
ctx.lineCap = 'round';
ctx.strokeStyle = 'red';
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(150,200);
ctx.moveTo(200,300);
ctx.lineTo(250,400);
ctx.moveTo(300,500);
ctx.lineTo(350,600);
ctx.closePath();
ctx.stroke();
then the result is this:
(source: phrogz.net)
As you can see on this test page, adding a "superfluous" moveTo
call after the last lineTo
fixes the last line segment to use rounded caps.
I was prepared to file this as a bug, but then I found that the behavior is identical on Safari v5, Chrome v8, and FireFox v3.6 and v4.0b. This leads me to believe that it is intentional.
Where in the standard is this behavior specified, and (if you can discern it) why was it specced as such?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
以下是canvas 规范(第 9 节,路径):
每个
moveTo
调用都会创建一个新的子路径,从而结束之前的子路径。在您的情况下,前两个片段以这种方式结束。对于最后一段,调用 closePath 通过沿相反方向绘制另一段来“关闭”该段,因此您看到的结果是 - 不是一个段,而是两个重叠的段。添加另一个moveTo
会像其他段一样结束此段,因此您会看到预期的圆形线帽。Here are the relevant definitions from the canvas spec (section 9, paths):
Each
moveTo
call creates a new subpath, thus ending the previous subpath. In your case, the first two segments are ended this way. For the final segment, callingclosePath
"closes" the segment by drawing another segment in the reverse direction, hence the result you are seeing -- there is not one segment but rather two overlapping segments. Adding anothermoveTo
ends this segment just like the others, so you see the rounded line cap as expected.