下面的代码在IE9和FireFox中很好地呈现了一个破环,但在Chrome中的圆圈部分失败了。任何想法,或者我可以做些什么来使它在所有浏览器中呈现?
干杯
(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>
答案 0 :(得分:1)
这是一个解决方法。这是我制作的弧形方法的另一种实现方式。它也近似使用二次贝塞尔曲线,但在Chrome中更精确。对于我尝试过的圆圈(最多两倍的屏幕尺寸),这种像差几乎不可察觉:
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));
}
}
编辑:使得符合条件(如Firefox,Safari)。对某些角度来说,Chrome似乎也存在错误。
答案 1 :(得分:1)
我们可以用ctx.clip()修复它。
例如:
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();
你的Keyten / Newcomer:)
答案 2 :(得分:0)
在Chrome 16,17和18中完美运行。
Chrome的画布开发速度非常快,过去一年他们一直在打破和关闭各种各样的东西。抗锯齿,文本失真以及在某些尺度上根本没有出现的路径的问题都已经成为Chrome的稳定版本,他们可能会在一两个星期内留下(主要)错误。
每当你怀疑Chrome中存在错误时,总是值得研究dev和canary版本的反应。出于这些原因,我发展它们都是开放的,如果某些东西明显被打破,则从一个切换到另一个。有趣的是,你会看到bug被修复并修复,然后一个月后人们会抱怨稳定版本中的bug!