Home > Back-end >  HTML5, canvas: some linewidth too narrow and then disappear
HTML5, canvas: some linewidth too narrow and then disappear

Time:04-12

A stupid simple canvas usage:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.scale(100000, 100000);
ctx.lineWidth = 0.00001;
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>

The current line segment is not displayed。 if I change to this:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.scale(10000, 10000);
ctx.lineWidth = 0.0001;
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>

Line segments will be displayed? Why does this happen. It’s annoying. Thanks for your help!

CodePudding user response:

This is caused by a bug in the GPU renderer used by Chrome.

We can confirm it's only a bug in the GPU pipes by initializing your context with the willReadFrequently flag, but that's not a proper solution (because you want GPU acceleration when available).

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d", { willReadFrequently: true });
ctx.scale(100000, 100000);
ctx.lineWidth = 0.00001;
ctx.moveTo(0, 0);
ctx.lineTo(200, 100);
ctx.stroke();
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>

So, it would be great to open an issue against Chromium, you can point to them that apparently this CL introduced the issue, and thus it is a regression.

While you're there, you can also open one against WebKit, which doesn't even pass the x10,000 scale test.

But to be honest, you are asking for trouble using such scales.
Such "rounding" bugs regularly come and go in various engines, and not only this obvious, sometimes only when doing a particular curve etc.

So the best is to stick to "standard" scales, if you really need to go that far, then do the scaling yourself from JS:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
const scale = 100_000;
ctx.moveTo(0, 0);
ctx.lineTo(200 * scale, 100 * scale);
ctx.stroke();
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>

  • Related