HTML5画布圆弧在Google Chrome中无法正确呈现

时间:2011-12-22 12:07:00

标签: html5 google-chrome canvas rendering

下面的代码在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>

3 个答案:

答案 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!