HTML5 дуги холста неправильно отображаются в Google Chrome - PullRequest
2 голосов
/ 22 декабря 2011

Приведенный ниже код прекрасно отображает разорванное кольцо в IE9 и FireFox, но частично завершается неудачей в Chrome.Любые идеи, почему или что я могу сделать, чтобы он отображался во всех браузерах?

Cheers

(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 ]

1 голос
/ 27 июля 2012

Вот обходной путь. Это альтернативная реализация метода дуги, которую я сделал. Он также приближается к использованию квадратичных Безье, но гораздо более точен в 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));
    }
}

Редактировать: Сделано в соответствии с Whatwg (например, Firefox, Safari). Хром также, кажется, делает круги неправильными для определенных углов.

1 голос
/ 29 июня 2014

Мы можем исправить это с помощью 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:)

0 голосов
/ 22 декабря 2011

Отлично работает в Chrome 16, 17 и 18.

Разработка холста в Chrome идет очень быстрыми темпами, и в течение последнего года они ломали разные вещи. Проблемы сглаживания, искажения текста и путей, которые вообще не отображаются в некоторых масштабах, превратили его в стабильную версию Chrome, где они могут оставить (основные) ошибки на неделю или две.

Всякий раз, когда вы подозреваете ошибку в Chrome, всегда стоит посмотреть, как реагируют версии dev и canary. По этим причинам я развиваюсь с обоими открытыми, переключаясь с одного на другой, если что-то явно сломано. Самое смешное, что вы увидите, как исправляются и исправляются ошибки, а через месяц люди будут жаловаться на ошибку в стабильной версии!

...