HTML canvas arches do not render correctly in Google Chrome

The code below perfectly displays a broken ring in IE9 and FireFox, but does not wrap around a circle in Chrome. Any ideas why, or what can I do to make this render in all browsers?

Greetings

(version for Chrome 15.0.874.121)

<!DOCTYPE html> <html> <body> <canvas id="canvas1" width="201" height="201">No canvas in your browser...sorry...</canvas> <script> var canv = document.getElementById('canvas1'); var ctx = canv.getContext('2d'); var size = 201; var centerX = size / 2; var centerY = centerX; var i; var PI_180 = Math.PI / 180; var fill = true; size = size / 2; ctx.translate(centerX, centerY); // broken ring for (i = 0; i < 360; i += 15) { fill = !fill; ctx.beginPath(); ctx.arc(0, 0, size * 0.86, i * PI_180, (i + 15) * PI_180, false); ctx.arc(0, 0, size * 0.75, (i + 15) * PI_180, i * PI_180, true); ctx.closePath(); if (fill) { ctx.fill(); } ctx.stroke(); } ctx.translate(-centerX, -centerY); </script> </body> </html> 
+2
source share
3 answers

It works fine in Chrome 16, 17 and 18.

Chrome canvas development is developing very fast, and last year they tore up various things. Problems of smoothing, text distortion and paths that are not displayed at all at some scales have all turned it into a stable version of Chrome, where they can leave (basic) errors for a week or two.

Whenever you suspect a bug in Chrome, you should always see how developers and canaries react. For these reasons, I am developing, and both of them are open, moving from one to another if something is clearly broken. The funny thing is that you will see that the errors are made and corrected, and then after a month people will complain about the error in the stable version!

0
source

Here is the work. This is an alternative implementation of the arc method I made. It is also approximated using quadratic beziers, but much more accurately in Chrome. Aberration is hardly noticeable for the circles I tried (up to double the screen size):

 var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1; if (is_chrome) { CanvasRenderingContext2D.prototype.arc = function(x, y, radius, startAngle, endAngle, anticlockwise) { // Signed length of curve var signedLength; var tau = 2 * Math.PI; if (!anticlockwise && (endAngle - startAngle) >= tau) { signedLength = tau; } else if (anticlockwise && (startAngle - endAngle) >= tau) { signedLength = -tau; } else { var delta = endAngle - startAngle; signedLength = delta - tau * Math.floor(delta / tau); // If very close to a full number of revolutions, make it full if (Math.abs(delta) > 1e-12 && signedLength < 1e-12) signedLength = tau; // Adjust if anti-clockwise if (anticlockwise && signedLength > 0) signedLength = signedLength - tau; } // Minimum number of curves; 1 per quadrant. var minCurves = Math.ceil(Math.abs(signedLength)/(Math.PI/2)); // Number of curves; square-root of radius (or minimum) var numCurves = Math.ceil(Math.max(minCurves, Math.sqrt(radius))); // "Radius" of control points to ensure that the middle point // of the curve is exactly on the circle radius. var cpRadius = radius * (2 - Math.cos(signedLength / (numCurves * 2))); // Angle step per curve var step = signedLength / numCurves; // Draw the circle this.lineTo(x + radius * Math.cos(startAngle), y + radius * Math.sin(startAngle)); for (var i = 0, a = startAngle + step, a2 = startAngle + step/2; i < numCurves; ++i, a += step, a2 += step) this.quadraticCurveTo(x + cpRadius * Math.cos(a2), y + cpRadius * Math.sin(a2), x + radius * Math.cos(a), y + radius * Math.sin(a)); } } 

Edit: Created whatwg-compatible (e.g. Firefox, Safari). Chrome also seems that circles are wrong for certain angles.

+1
source

We can fix it with ctx.clip ().

For ex:

 ctx.save(); // clipping ctx.beginPath() ctx.arc(x, y, radius, 0, 6.28, true); ctx.clip(); // drawing ctx.beginPath(); ctx.arc(x, y, radius, 0, 6.28, true); ctx.fill(); ctx.restore(); ctx.stroke(); 

Your Keyten / Newcomer :)

+1
source

Source: https://habr.com/ru/post/904999/


All Articles