为什么使用 ctx.lineCap = "round" 时,ctx.roundRect 的左上角会突然出现一个小点
这是 Chromium 浏览器中的一个错误,因为它不会出现在 Firefox 中吗?
以下是重现该问题的代码:
const ctx = canvas.getContext('2d')
let width = window.innerWidth
let height = window.innerHeight
canvas.width = width
canvas.height = height
ctx.clearRect(0,0,canvas.width, canvas.height)
ctx.lineWidth = 5
ctx.strokeStyle = "black"
ctx.lineCap = "round"
ctx.beginPath()
ctx.roundRect(100,100,100,100,12)
ctx.closePath()
ctx.stroke()
这是由与导致此问答相同的 Chrome 错误引起的。因此,我邀请您阅读我的答案以获得详细的解释。
TL;DR;是规范对于如何绘制零长度子路径相对混乱,而且使用线帽,并且 3 个主要实现在这方面确实有所不同。
ctx.roundRect()
指定到
- 将子路径标记为关闭。
- 创建一个新的子路径,将点 (x, y) 作为子路径中唯一的点。
在绘制圆角矩形之后。
这相当于调用
ctx.closePath(); ctx.moveTo(x, y)
;
因此,当您的脚本在调用
ctx.roundRect()
后再次获得控制权时,上下文中确实有一个单独的零长度子路径。 Chrome 会渲染它。
他们是唯一这样做的人,甚至在 Canary 上进行了当前可用的更新,确实删除了此类零长度子路径,但“修复”无法处理不单独的子路径(即,当当前有更多内容时)要绘制的路径)。
但无论如何,关于标准化正确行为™的讨论仍在继续,暂时我们只能忍受这些差异(如果你开始玩
setLineDash()
,还会有更多差异)。
closePath()
。如前面的引文所示,圆角矩形子路径已经“标记为关闭”,因此您不需要再次调用它。