虽小但意义重大:我想在 Firefox 的 JS Canvas 中画一个带有轮廓的半圆。不知何故,笔画的线条末端不符合其应有的效果,根据我的理解,这将是一个实心半圆。但即使在 Firefox 中也没有结局。知道为什么吗? (稍后我需要它来制作圆环图)
ctx.beginPath();
ctx.arc(0,0,20,0,Math.PI);
ctx.lineWidth = 40;
ctx.fillStyle = "#ff00ff";
ctx.strokeStyle = "#000000";
ctx.lineCap = "butt";
ctx.stroke();
ctx.fill();
火狐结果:
结果 Chrome:
这确实是 Firefox 的一个 bug。我打开了https://bugzil.la/1868067。
该问题源于以下事实:Firefox 最近将其笔画渲染器切换为 GPU 加速渲染器,而此前他们使用 Skia 的 2D 渲染器进行笔画。然而,该渲染器一定有问题,并且无法正确渲染弧线(实际上以各种方式)。
因此,为了避免该错误,您可以通过在创建上下文时传入
willReadFrequently: true
选项来强制浏览器使用软件渲染器。但这也意味着没有任何东西可以再利用 GPU 渲染。根据您在该上下文中所做的操作,它可能会也可能不会对性能造成严重影响。所以你可能想彻底测量一下。
如果它确实显着影响您的应用程序的性能,并且如果您经常遇到该错误,则可以在启动应用程序之前运行测试,这样只有有问题的配置才会受到影响:
const isBuggy = (() => {
const ctx = document.createElement("canvas").getContext("2d");
ctx.lineWidth = 50;
ctx.arc(50, 50, 25, 0, Math.PI);
ctx.stroke();
return ctx.getImageData(50, 49, 1, 1).data[3] > 200;
})();
console.log({ isBuggy });
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d", { willReadFrequently: isBuggy });
ctx.translate(50, 50);
ctx.beginPath();
ctx.arc(0, 0, 20, 0, Math.PI);
ctx.lineWidth = 40;
ctx.stroke();
<canvas></canvas>
否则,根据您的设置,另一种解决方法可能是使用减速画布预渲染形状(
OffscreenCanvas
默认情况下似乎是减速的,因此它们可能是一个不错的选择),并且drawImage
在您的加速上需要时画布。这显然只有在形状不随时间变化的情况下才有效。